changing the attached template programmatically

C

Chip Orange

We are trying to change a document's attached template from within a macro,
and we are running into an odd problem. As soon as we make the template
change, the rest of the macro fails to execute. This happens even if we make
the template change from within a macro which is part of a global add-in. Is
there anyway to do this?



thanks.



Chip
 
P

Peter Hewett

Hi Chip Orange

Obviously if you're running code in a template attached to a document and then you change
the documents attached template the code will stop dead. That's because the template
executing the code is unloaded and replaced with another template!

However, you should be able to change a documents attached template from either another
template or an add-in. If your add-in stops as well something else is going on and you
need to do some investigative work. Add some debug code to your add-in so that you can
see what the documents attached template is before you change it, display also the full
name and path of the template your attaching to make sure that's valid as well. You get
the idea.

HTH + Cheers - Peter
 
C

Charles Kenyon

Hi Peter,
Obviously if you're running code in a template attached to a document and then you change
the documents attached template the code will stop dead. That's because the template
executing the code is unloaded and replaced with another template!

You are right, this is obvious. It also doesn't happen to me in Word 2003. I
do make the change late in an AutoNew macro but the remainder of the macro
continues to run. The same macro (in the same module) is in the new attached
template. Both the old and the new templates have the same project name. I
find it anomolous and try to not rely on it happening, but it does happen.

The macro checks to see if the attached template is the main template. If it
is, fine. If not, it attaches the document to the main template.

After that, it displays a userform (from the first template). I also tested
and had it display a message box after the userform. The code for that is
only in the first template and not in the main template.
--

Charles Kenyon

Word New User FAQ & Web Directory:
<URL: http://addbalance.com/word/index.htm>

Intermediate User's Guide to Microsoft Word (supplemented version of
Microsoft's Legal Users' Guide)
<URL: http://addbalance.com/usersguide/index.htm>

See also the MVP FAQ: <URL: http://www.mvps.org/word/> which is awesome!
--------- --------- --------- --------- --------- ---------
This message is posted to a newsgroup. Please post replies
and questions to the newsgroup so that others can learn
from my ignorance and your wisdom.

Peter Hewett said:
Hi Chip Orange

However, you should be able to change a documents attached template from either another
template or an add-in. If your add-in stops as well something else is going on and you
need to do some investigative work. Add some debug code to your add-in so
that you can
 
C

Charles Kenyon

Please see my response to Peter H.

I do this regularly, although not from a global. From within the document
template itself I change the attached template and my code continues to run.
That is true even though the code is run after the display of a userform.
That is, the code changes the attached template then displays a userform
from the original template, and continues to run. (I don't understand how it
can do this, but it does. Word 2003.)

You should follow Peter's suggestions about debugging. Perhaps post the code
here, both the code that changes the attached template and the code that
doesn't run after that happens.
--

Charles Kenyon

Word New User FAQ & Web Directory:
<URL: http://addbalance.com/word/index.htm>

Intermediate User's Guide to Microsoft Word (supplemented version of
Microsoft's Legal Users' Guide)
<URL: http://addbalance.com/usersguide/index.htm>

See also the MVP FAQ: <URL: http://www.mvps.org/word/> which is awesome!
--------- --------- --------- --------- --------- ---------
This message is posted to a newsgroup. Please post replies
and questions to the newsgroup so that others can learn
from my ignorance and your wisdom.
 
P

Peter Hewett

Hi Charles Kenyon

Ok, it sounds like for some reason your template is being kept alive by either a Project
reference to the original template, you have another document loaded that uses the
template as well or the template is also an add-in. In this instance, even though the
template is detached from the document it would still be kept in "memory" by Word and thus
continue running.

I don't have Word 2003 (yet!) so I can't try this out. When I get a chance I'll try it
using XP - but the theory appears reasonable.

If the above does not account for what you're seeing I'd say it a bug and a very nasty one
at that. Word never (well never before) runs a macro when you manually attach a template
to a document. This makes perfect sense as how does it know what macro you want to run.
So to see it running another macro in a different template is crazy! - Even if the
Project/Module/Macro names are the same.

You can prove what I'm saying easily enough. Add a MsgBox statement as the very first
line (after the declarations of course) of the AutoNew macro in the template your code
attaches to. If you never see it you know it's not the code in the second template that's
running.

HTH + Cheers - Peter
 
C

Charles Kenyon

Hi Peter,

I know it is code in the first template that is running because I did insert
a message box to display in the code in that template that was not present
in the code of the new template. That message box displays _after_
(1) the code switches the attached template and
(2) displays and executes code in a form from the original template.

That is, the code in template 1:
Switches the attached template to be template 2,
Creates an instance of the form from template 1 and displays it (with no
explicit reference back to template 1)
Follows the code in the cmdOK_click event or the cancel event from that
form, and
Displays a message box (not found in template 2's code).

I suspect that the code finishes loading before the template switch takes
place.

BTW - the same thing happens in Word 97.

No, I don't think it should work this way, either. But it does. So, for now,
I use it.

There is no other instance of template 1 open or loaded when this happens.
--

Charles Kenyon

Word New User FAQ & Web Directory:
<URL: http://addbalance.com/word/index.htm>

Intermediate User's Guide to Microsoft Word (supplemented version of
Microsoft's Legal Users' Guide)
<URL: http://addbalance.com/usersguide/index.htm>

See also the MVP FAQ: <URL: http://www.mvps.org/word/> which is awesome!
--------- --------- --------- --------- --------- ---------
This message is posted to a newsgroup. Please post replies
and questions to the newsgroup so that others can learn
from my ignorance and your wisdom.
 
P

Peter Hewett

Hi Charles Kenyon

I was trying to explain under what conditions I might expect the behavior you reported to
occur. It sounds like the original template never gets unloaded and thus the code
continues to execute. The original code must still be around otherwise you would not be
able to instantiate the Form in your original template.

I believe the explanation is logical albeit obtuse!

Cheers - Peter


Hi Peter,

I know it is code in the first template that is running because I did insert
a message box to display in the code in that template that was not present
in the code of the new template. That message box displays _after_
(1) the code switches the attached template and
(2) displays and executes code in a form from the original template.

That is, the code in template 1:
Switches the attached template to be template 2,
Creates an instance of the form from template 1 and displays it (with no
explicit reference back to template 1)
Follows the code in the cmdOK_click event or the cancel event from that
form, and
Displays a message box (not found in template 2's code).

I suspect that the code finishes loading before the template switch takes
place.

BTW - the same thing happens in Word 97.

No, I don't think it should work this way, either. But it does. So, for now,
I use it.

There is no other instance of template 1 open or loaded when this happens.

HTH + Cheers - Peter
 
C

Chip Orange

Thanks Peter, but I've done all that. Just before the change template
command all is fine, and immediately afterwards, well, there's no code
executing at all.

Chip
 
C

Chip Orange

Charles Kenyon said:
Please see my response to Peter H.

I do this regularly, although not from a global. From within the document
template itself I change the attached template and my code continues to run.
That is true even though the code is run after the display of a userform.
That is, the code changes the attached template then displays a userform
from the original template, and continues to run. (I don't understand how it
can do this, but it does. Word 2003.)

You should follow Peter's suggestions about debugging. Perhaps post the code
here, both the code that changes the attached template and the code that
doesn't run after that happens.


thanks Charles.

This is my Word 2002 code in my global add-in:

Public Sub ChangeTemplate(ByVal NewTemplateName As String, _
ByVal SaveDocumentAfterChange As Boolean, _
ByVal CloseDocumentAfterChange As Boolean)
' changes the associated template for the active document and optionally
saves and/or closes it afterwards
ActiveDocument.AttachedTemplate = NewTemplateName
MsgBox "Changed!"
If SaveDocumentAfterChange Then
ActiveDocument.Save
End If
If CloseDocumentAfterChange Then
ActiveDocument.Close
End If

End Sub
 
C

Charles Kenyon

I put the following into a global template and tried running it. It is
essentially your macro stripped of the parameters so that I could run it
from the user interface. The message box displayed after the template was
changed. In checking under Tools => Templates and Add-Ins... the attached
template is changed.

Word 2003.

Public Sub ChangeTemplate()
' changes the associated template for the active document and optionally
saves and/or closes it afterwards
ActiveDocument.AttachedTemplate = "normal.dot"
MsgBox "Changed!"
' If SaveDocumentAfterChange Then
' ActiveDocument.Save
' End If
' If CloseDocumentAfterChange Then
' ActiveDocument.Close
' End If

End Sub
 
P

Peter Hewett

Hi Chip Orange

That's exactly what I would expect. Not what Charles sees. Charles code exploits a Word
"feature". I would not rely on this as it could break any time MS patch Word/VBA or next
time you upgrade Word.

HTH + Cheers - Peter
 
C

Chip Orange

I can only put it down to the difference in Word versions, and hope someone
else with 2002 will give my code a try as well to let me know how it works
for them.

Thanks Charles for your efforts.

Chip
 
P

Peter Hewett

Hi Chip Orange

This may seem like an odd question this late in the thread, but how is the code in your
Add-in being called? Are you calling it from the Template or is it hooked to an
Application event handler or to a menu button?

If you're calling the code in your Add-in from your template then I would expect your code
to terminate as soon as you change the attached template. If the code is triggered by an
Application event handler or a menu button then there's a problem.

Cheers - Peter


I can only put it down to the difference in Word versions, and hope someone
else with 2002 will give my code a try as well to let me know how it works
for them.

Thanks Charles for your efforts.

Chip

HTH + Cheers - Peter
 
C

Chip Orange

Thanks Peter.

Yes, I'm calling this from a template that is currently in use before the
change, that's why I placed the code to do the change in a global add-in
template, in hopes that it would keep running (since it's still available)
after the template change.

Chip
 
P

Peter Hewett

Hi Chip Orange

Then I must reiterate - It working *exactly* as I'd expect. You may be able to do
something really nasty like having your Add-In load the Template as an Add-In before
changing the documents attached template! The code in the Template (now also installed as
an add-in) would then have to unload itself as an Add-In after the call to the SUb in you
original add-in returns. I haven't tried it but it might work. What we're actually doing
is ensuring the Template remains in memory. This is so that when the Add-In changes the
attached template, the template is still in memory (as an Add-In) and the code in it
(hopefully) continues to run.

If this behavior works, I'd make sure it was very well documented as it may break in the
future.

HTH + Cheers - Peter
 
C

Chip Orange

Thanks Peter.

Do you know what command I would use to cause a template to be loaded as an
add-in programatically? The only way I know to do it is to place it in the
startup dir before starting Word.

thanks.

Chip
 
C

Charles Kenyon

Try doing it from the user interface and recording the action.
Tools => Templates and Add-Ins...


Chip Orange said:
Thanks Peter.

Do you know what command I would use to cause a template to be loaded as an
add-in programatically? The only way I know to do it is to place it in the
startup dir before starting Word.

thanks.

Chip


Peter Hewett said:
Hi Chip Orange

Then I must reiterate - It working *exactly* as I'd expect. You may be able to do
something really nasty like having your Add-In load the Template as an Add-In before
changing the documents attached template! The code in the Template (now also installed as
an add-in) would then have to unload itself as an Add-In after the call
to
the SUb in you
original add-in returns. I haven't tried it but it might work. What we're actually doing
is ensuring the Template remains in memory. This is so that when the Add-In changes the
attached template, the template is still in memory (as an Add-In) and
the
code in it
(hopefully) continues to run.

If this behavior works, I'd make sure it was very well documented as it may break in the
future.

HTH + Cheers - Peter
is
code
It
 
P

Peter Hewett

Hi Chip Orange

I use something like this:

Public Sub InstallMESWizard()
Dim adiWizard As Word.AddIn
Dim boolInstalled As Boolean
Dim boolInList As Boolean
Dim strWizardFullName As String
Dim strCurrentFile As String

' Check to see if the Wizard is already open
For Each adiWizard In AddIns
If StrComp(adiWizard.Name, MESWizardName, vbTextCompare) = 0 Then
boolInList = True
boolInstalled = adiWizard.Installed
adiWizard.Installed = True
Exit For
End If
Next

' Install the MES Wizard as a Global Add-In so that
' we can get to the macros it contains
If boolInList = False Then

' Install the Wizard so that we can run a macro to start the Wizard proper
strWizardFullName = ActiveDocument.AttachedTemplate.Path & "\" & MESWizardName
Set adiWizard = AddIns.Add(strWizardFullName, True)
End If

' Save the current documents full name so that we can
' tell the Wizard which document to use
strCurrentFile = ActiveDocument.FullName

' Application.Run seems to be very flaky, "Project!Module.Proc" fails,
' "Project.Proc" works, but if you add a parameter it then fails!

' The MES Wizard must be installed for the Application.Run to work!!
Application.Run "MESWizardRestart", strCurrentFile

' Remove the Wizard if necessary
If boolInstalled = False Then adiWizard.Installed = False
If boolInList = False Then adiWizard.Delete
End Sub

MESWizardName is a constant that defines the name of the Add-Ins template.

HTH + Cheers - Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top