Cannot add reference to Word template project via Automation

H

Howard Kaikow

The problem does not exist with Word 97, but exists for Word 2000, Word 2002
and Word 2003.
Without using Automation, I can delete a reference, then recreate the
reference in a Word template, and the resulting reference does get saved
with the changed template.

However, the reference does not get saved if I try to do this via automation
via a Word object in any of the following:

1. Word itself.
2. VB .NET 2003, VB 6 or Excel.
3. VSTO, using the built-n This Application object in VB .NET.

Note that the reference does get added, one can see this by stepping thru
the code, and examining the physical file.
However, the reference does not get saved with the template when the code
ends, implying that Word is somehow working with a temporary copy of the
template and not correctly updating the saved template.

Note that I tried an analogous problem using Excel and no such problem
exists when adding a reference to an Excel Workbook

Below you will find code that can be used to replicate the problem.

You can change the values for strDLLPath, strReference and strTargetPath.
SetReferenceInWordNotUsingWordObject will produce the expected result, i.e.,
the reference will be saved.
SetReferenceInWordUsingWordObject will NOT produce the expected result,
i.e., the reference will not be saved.

You will get the same result in Word 2000, Word 2002, Word 2003; or by using
the appropriate code to automate Word via, say, VB .NET 2003, VB 6 (SP 6),
VSTO and Excel 2003 (I've not tried this with other Excel versions).

Option Explicit
' strReference must be set to the reference name.
Private Const strReference As String = "EudoraLib"
' strDLLPath has to be set to path of library.
Private Const strDLLPath As String = "J:\Program
Files\Qualcomm\Eudora\Eudora.exe"
' strTargetPath has to be set to path where target template will be
created
Private Const strTargetPath As String = "C:\Test\VB-Test" ' For VBA
Private Const strTemplate As String = strTargetPath &
"\TargetForRef.dot"

Dim docTemplate As Word.Document
Dim ref As VBIDE.Reference
Dim strOutput As String

Private Sub SetReferenceInWordNotUsingWordObject()
On Error Resume Next
Kill strTemplate
Set docTemplate = Documents.Add(NewTemplate:=True,
Template:=NormalTemplate.FullName)
With docTemplate
.SaveAs FileName:=strTemplate, addtorecentfiles:=False
strOutput = "Using: " & .FullName & vbCrLf
With .AttachedTemplate
strOutput = strOutput & vbCrLf & "Template: " & .FullName &
vbCrLf
With .VBProject
On Error Resume Next
' Remove reference
.References.Remove (.References(strReference))
Err.Clear
' Add reference
Set ref = .References.AddFromFile(strDLLPath)
End With
.Save ' Save template
For Each ref In .VBProject.References
strOutput = strOutput & vbCrLf & ref.Name
Next ref
strOutput = strOutput & vbCrLf & vbCrLf & _
"If " & Chr(34) & strReference & Chr(34) & _
" appears in the above list, then the reference should have
been saved."
strOutput = strOutput & vbCrLf & "Finished"
End With
MsgBox (strOutput)
.Save
'Closing does not destroy Reference, which is expected behavior
.Close
End With
Set docTemplate = Nothing
Set ref = Nothing
End Sub

Private Sub SetReferenceInWordUsingWordObject()
Dim appWord As Word.Application

On Error Resume Next
Set appWord = New Word.Application
If Err.Number <> 0 Then
Exit Sub
End If
Kill strTemplate
With appWord
Set docTemplate = .Documents.Add(NewTemplate:=True,
Template:=.NormalTemplate.FullName)
End With
With docTemplate
.SaveAs FileName:=strTemplate, addtorecentfiles:=False
strOutput = "Using: " & .FullName & vbCrLf
With .AttachedTemplate
strOutput = strOutput & vbCrLf & "Template: " & .FullName &
vbCrLf
With .VBProject
On Error Resume Next
' Remove reference
.References.Remove (.References(strReference))
Err.Clear
' Add reference
Set ref = .References.AddFromFile(strDLLPath)
End With
.Save ' Save template
For Each ref In .VBProject.References
strOutput = strOutput & vbCrLf & ref.Name
Next ref
strOutput = strOutput & vbCrLf & vbCrLf & _
"If " & Chr(34) & strReference & Chr(34) & _
" appears in the above list, then the reference should have
been saved."
strOutput = strOutput & vbCrLf & "Finished"
End With
MsgBox (strOutput)
.Save
'Closing causes Reference to no longer be in template
.Close
End With
appWord.Quit
Set docTemplate = Nothing
Set ref = Nothing
Set appWord = Nothing
End Sub
 
W

Word Heretic

G'day "Howard Kaikow" <[email protected]>,

This is just an educated guess :) I think that merely adding a ref
does not set the document dirty flag, so the save autoskips. If you
were to NOT save BEFORE the reference, then there will be sufficient
changes to have a dirty document that will save with all the reuested
changes.

Good luck, let me know if it works.

Steve Hudson - Word Heretic
Want a hyperlinked index? S/W R&D? See WordHeretic.com

steve from wordheretic.com (Email replies require payment)


Howard Kaikow reckoned:
 
H

Howard Kaikow

When using the GUI, adding a ref does dirty the template and one is asked
to save the template when exiting word.

In any case, that would not be the problem as the ref does get saved, unless
the instance of Word is automated.

The template file IS changed, and that can be seen by stepping thru the code
and examining the file after the SAVE.
However, when using an instance of Word, the CLOSE appears to overwrite the
saved/changed file.

This issue is a showstopper if one wishes to fully automate the installation
of software using, say, VB 6, VB .NET or VSTO.
Word 97 did not have this problem. Bug got into Word 2000 and has lurked
there ever since.
Surely, sombody else has encountered this previously?
 
W

Word Heretic

G'day "Howard Kaikow" <[email protected]>,

Hmmm. I wonder if a DoEvents after the save and before the close would
work. If that doesn't, a hard-core OnTime command in the same place
could break the functioning up so that Word gets a bite in on the way.

I _never_ programatically add references. I can't really see the
point. If the code references something absent, you get a compile
error...

Steve Hudson - Word Heretic
Want a hyperlinked index? S/W R&D? See WordHeretic.com

steve from wordheretic.com (Email replies require payment)


Howard Kaikow reckoned:
 
H

Howard Kaikow

Word Heretic said:
G'day "Howard Kaikow" <[email protected]>,

Hmmm. I wonder if a DoEvents after the save and before the close would
work. If that doesn't, a hard-core OnTime command in the same place
could break the functioning up so that Word gets a bite in on the way.

I _never_ programatically add references. I can't really see the
point. If the code references something absent, you get a compile
error...

It is necessary to add a reference in an installation program, which would
ordinarily be written in VB or VB .NET or ..., so using Word via a Word
object is mandatory.
 
H

Howard Kaikow

DoEvents didn't help.

OnTime won't help. I've stepped thru the code and looked at the template,
which would have the effect of putting in an OnTime delay 'tween the Save
and Close.

I have thought of the following:

With Microsoft
With .Word
.FixBugs =True
.LearnHowToDesignSoftware = True
With SoftwareQualityAssurance
.LearnHowToDoSQA = True
End With
End With
.AllOfTheAbove = True
.AndThenSome = True
End With

Dim bug as Word.Bug
For Each bug in Word.Bugs
bug.fix
Next bug
Set bug = Nothing
 
C

Chad DeMeyer

Howard,

I'm not sure that I understand exactly what your code is doing. You create
docTemplate as a new template based on Normal, save it ... and then access
it's attached template? How can a template be attached to another template?
I think your code may be failing because of the way you're approaching this
part of Word's object model. Once you have created and saved docTemplate,
it should now be a member of the templates collection, so to get a reference
to it as a template, you might use something like:

....
Dim objDoc as Document
Dim objTemplate as Template
....
Set objDoc = Documents.Add(NewTemplate:=True,
Template:=NormalTemplate.FullName)
objDoc.SaveAs FileName:=strTemplate ...
Set objTemplate = Templates(strTemplate)
....

Regards,
cjd
 
H

Howard Kaikow

I have previously tried opening the template directly and using
OpenAsDocument.
I have to use the .AttachedTemplate, otherwise there is a problem accessing
the References in VBProject, I know not why.

I'll try the suggestion below to see if that helps.

--
http://www.standards.com/; See Howard Kaikow's web site.
Chad DeMeyer said:
Howard,

I'm not sure that I understand exactly what your code is doing. You create
docTemplate as a new template based on Normal, save it ... and then access
it's attached template? How can a template be attached to another template?
I think your code may be failing because of the way you're approaching this
part of Word's object model. Once you have created and saved docTemplate,
it should now be a member of the templates collection, so to get a reference
to it as a template, you might use something like:

...
Dim objDoc as Document
Dim objTemplate as Template
...
Set objDoc = Documents.Add(NewTemplate:=True,
Template:=NormalTemplate.FullName)
objDoc.SaveAs FileName:=strTemplate ...
Set objTemplate = Templates(strTemplate)
...

Regards,
cjd
 
H

Howard Kaikow

Your suggestion is cleaner code, but the result is still the same.
Somehow, when using the Word object, Word is working with a copy of the
template, and the final result is not getting saved after closing.

In an earlier attempt at getting this critter to work, I had inserted
Debug.Print .FullName statements all over the place and I was able to see
references to the temporary file.

I'd like to know whether others are able to replicate the behavior I see.
If so, then I'll clean up (or maybe add cuss words) and send the problem to
MSFT, tho I expect that folkes from MSFT have already seen this posting and
are remaining quiet,
--
http://www.standards.com/; See Howard Kaikow's web site.
Chad DeMeyer said:
Howard,

I'm not sure that I understand exactly what your code is doing. You create
docTemplate as a new template based on Normal, save it ... and then access
it's attached template? How can a template be attached to another template?
I think your code may be failing because of the way you're approaching this
part of Word's object model. Once you have created and saved docTemplate,
it should now be a member of the templates collection, so to get a reference
to it as a template, you might use something like:

...
Dim objDoc as Document
Dim objTemplate as Template
...
Set objDoc = Documents.Add(NewTemplate:=True,
Template:=NormalTemplate.FullName)
objDoc.SaveAs FileName:=strTemplate ...
Set objTemplate = Templates(strTemplate)
...

Regards,
cjd
 
W

Word Heretic

G'day "Howard Kaikow" <[email protected]>,

<standing ovation>

Steve Hudson - Word Heretic
Want a hyperlinked index? S/W R&D? See WordHeretic.com

steve from wordheretic.com (Email replies require payment)


Howard Kaikow reckoned:
 

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