Can one save a reference added to project when automating Word

H

Howard Kaikow

Can one SAVE a reference added to a project when automating Word using a
Word object?

I want to do this from within VB 6, but I find that I cannot do this even
from within Word itself?

For example, using the code below (obvious pieces of code are omitted), one
gets the desired result, i.e., all of the following are executed.

Debug.Print "Found(1): " & ref.Name
Debug.Print "Found(2): " & ref.Name
Debug.Print "Found(3): " & ref.Name

However, if I instead use the Word object, say:

dim appWord as Word.Application

set appWord = New Word.application

and use, e.g.,

Set docNew = appWord.Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)

instead of

Set docNew = Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)

The 3rd test fails and the following is executed:

Debug.Print "Not Found(3): " & strReference, Err.Number,
Err.Description

Is this behavior documented?

Is there a way to SAVE a project after adding a Reference when automating
Word?
-----------------------------------------------
Dim docWord As Word.Document
Dim docNew As Word.Document
Dim ref As VBIDE.Reference

Set docNew = Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
Set docWord = docNew.AttachedTemplate.OpenAsDocument
With docWord
' add a reference here, then do the following
For Each ref In .VBProject.References
Debug.Print ref.Name
Next ref
If .VBProject.Saved Then
Debug.Print "Project was not modified"
Else
Debug.Print "Project was modified"
End If

On Error Resume Next
Set ref = .VBProject.References(strReference)
If Err.Number = 0 Then
Debug.Print "Found(1): " & ref.Name
Else
Debug.Print "Not Found(1): " & strReference, Err.Number,
Err.Description
End If
.Save
.Close savechanges:=wdSaveChanges
End With

With docNew
For Each ref In .AttachedTemplate.VBProject.References
Debug.Print ref.Name
Next ref
On Error Resume Next
Set ref = .AttachedTemplate.VBProject.References(strReference)
If Err.Number = 0 Then
Debug.Print "Found(2): " & ref.Name
Else
Debug.Print "Not Found(2): " & strReference, Err.Number,
Err.Description
End If
.Close
End With

Set docWord = Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
With docWord
For Each ref In .AttachedTemplate.VBProject.References
Debug.Print ref.Name
Next ref
On Error Resume Next
Set ref = .AttachedTemplate.VBProject.References(strReference)
If Err.Number = 0 Then
Debug.Print "Found(3): " & ref.Name
Else
Debug.Print "Not Found(3): " & strReference, Err.Number,
Err.Description
End If
.Close
End With
 
H

Howard Kaikow

Here's a simpler example.
Working via the Word application object, the reference is not saved in the
template.
Removing "appWord." in the set statement allows the reference to be saved in
the template.

Private Sub Main()
Dim appWord As Word.Application
Dim docWord As Word.Document
Dim docNew As Word.Document
Dim ref As VBIDE.Reference
Dim strTemplate As String

Set appWord = New Word.Application
' strTemplate = CurDir$ & "\TestMe.dot" ' For VB
strTemplate = "I:\Word VB
DLL\Development\SourceHowardKaikowWordVBDLLMakeTools\VB" & "\TestMe.dot" '
For VBA
Set docNew = appWord.Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
Set docWord = docNew.AttachedTemplate.OpenAsDocument
With docWord
ReplaceReference .VBProject
If .VBProject.Saved Then
Debug.Print "Project was not modified"
Else
Debug.Print "Project was modified"
End If
On Error Resume Next
Set ref = .VBProject.References(strReference)
If Err.Number = 0 Then
Debug.Print "Found(1): " & ref.Name
Else
Debug.Print "Not Found(1): " & strReference, Err.Number,
Err.Description
End If
.Save
.Close
End With
Set docNew = Nothing
Set docWord = Nothing
Set ref = Nothing
appWord.Quit
Set appWord = Nothing
End Sub
 
P

Peter Hewett

Hi Howard Kaikow

I'm not sure if I'm at cross purposes with you here. I don't see the code for
"ReplaceReference" so I don't know what it's doing. But you don't seem to be saving the
Template as in:
docWord.Save

before testing:
If [docWord].VBProject.Saved Then

(the square brackets are mine as I abstracted your code from the With block) so the
..Saved property will be False.

Cheers - Peter


Here's a simpler example.
Working via the Word application object, the reference is not saved in the
template.
Removing "appWord." in the set statement allows the reference to be saved in
the template.

Private Sub Main()
Dim appWord As Word.Application
Dim docWord As Word.Document
Dim docNew As Word.Document
Dim ref As VBIDE.Reference
Dim strTemplate As String

Set appWord = New Word.Application
' strTemplate = CurDir$ & "\TestMe.dot" ' For VB
strTemplate = "I:\Word VB
DLL\Development\SourceHowardKaikowWordVBDLLMakeTools\VB" & "\TestMe.dot" '
For VBA
Set docNew = appWord.Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
Set docWord = docNew.AttachedTemplate.OpenAsDocument
With docWord
ReplaceReference .VBProject
If .VBProject.Saved Then
Debug.Print "Project was not modified"
Else
Debug.Print "Project was modified"
End If
On Error Resume Next
Set ref = .VBProject.References(strReference)
If Err.Number = 0 Then
Debug.Print "Found(1): " & ref.Name
Else
Debug.Print "Not Found(1): " & strReference, Err.Number,
Err.Description
End If
.Save
.Close
End With
Set docNew = Nothing
Set docWord = Nothing
Set ref = Nothing
appWord.Quit
Set appWord = Nothing
End Sub

HTH + Cheers - Peter
 
H

Howard Kaikow

Here's a complete example that demonstrates the problem.
Before running, the variables strReference, strDLLPath and strTemplate must
be set as indicated in the comments.

All RemoveReerence did was remove the reference, if it was present, then add
the reference.
I've included analagous code inline below.

Note that I am saving the template.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''
Option Explicit
' strReference must be set to the reference name.
' Private Const strReference As String = "MyReference"
Private Sub Main()
Debug.Print RunTest(False)
Debug.Print RunTest(True)
Debug.Print RunTest(False)
Debug.Print RunTest(False)
End Sub

Private Function RunTest(blnUseAppWord As Boolean) As String
' blnUseWordApp = True, create new Word object
' blnUseWordApp = False, do not create new Word object

' strDLLPath has to be set to path of DLL.
' Const strDLLPath As String = "SomePath\SomeDLL.dll"
Dim appWord As Word.Application
Dim docOther As Word.Document
Dim docWord As Word.Document
Dim ref As VBIDE.Reference
Dim strTemplate As String
Dim VBP As VBIDE.VBProject

' strTemplate has to be set to path of template to which reference is to
be added
' strTemplate = CurDir$ & "\TestMe.dot" ' For VB
' strTemplate = "APath\TestMe.dot" ' For VBA
If blnUseAppWord Then
Set appWord = New Word.Application
Set docWord = appWord.Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
Else
Set docWord = Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
End If
With docWord
'Debug.Print "0. Added: " & .Name
'Debug.Print "1. Template:" & .AttachedTemplate.Name,
..AttachedTemplate.FullName
Set VBP = .AttachedTemplate.VBProject
On Error Resume Next
' Remove reference
VBP.References.Remove VBP.References(strReference)
Err.Clear
' Add reference
Set ref = VBP.References.AddFromFile(strDLLPath)
If Err.Number <> 0 Then
RunTest = "Could not add reference: " & Err.Number & ", " &
Err.Description
Exit Function
End If

If .AttachedTemplate.VBProject.Saved Then
'Debug.Print "2. Project was not modified"
Else
'Debug.Print "2. Project was modified"
End If

On Error Resume Next
'Debug.Print "3. Project: " & .AttachedTemplate.VBProject.Name
Set ref = .AttachedTemplate.VBProject.References(strReference)
If Err.Number = 0 Then
'Debug.Print "4. Found(1): " & ref.Name
Else
'Debug.Print "4. Not Found(1): " & strReference, Err.Number,
Err.Description
End If
'Debug.Print "5. Save: " & .AttachedTemplate.Name
.AttachedTemplate.Save
'Debug.Print "6. Close: " & .Name
.Close
End With

If blnUseAppWord Then
Set docOther = appWord.Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
Else
Set docOther = Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
End If
With docOther
'Debug.Print "i. Added: " & .Name
'Debug.Print "ii. Template: " & .AttachedTemplate.Name,
..AttachedTemplate.FullName
On Error Resume Next
'Debug.Print "iii. Project: " & .AttachedTemplate.VBProject.Name
Set ref = .AttachedTemplate.VBProject.References(strReference)
If Err.Number = 0 Then
RunTest = "Test Passed - Reference " & strReference & " was
found."
Else
RunTest = "Test Failed - Reference " & strReference & " was not
found: " & _
Err.Number & ", " & Err.Description
End If
.Saved = True
'Debug.Print "v. Close: " & .Name
.Close
End With

Set docOther = Nothing
Set docWord = Nothing
Set ref = Nothing
If blnUseAppWord Then
appWord.Quit
Set appWord = Nothing
End If
End Function
 
H

Howard Kaikow

It does appear that if working thru the Word object, a copy of the template
is being used, so the reference fails because, although I've saved the
changed template, the subsequent creation of a new doc still is using the
old copy of the template.

I've even tried opening the template directly as a document, but still the
changed ref does not appear to get saved until the code finishes running.

The following isolates the relevant code even further than my previous
examples.

Option Explicit
' strReference must be set to the reference name.
' Private Const strReference As String = "MyReference"
' strDLLPath has to be set to path of DLL.
' Const strDLLPath As String = "SomePath\SomeDLL.dll"
Private blnUseAppWord As Boolean
' blnUseWordApp = True, create new Word object
' blnUseWordApp = False, do not create new Word object

Private appWord As Word.Application
Private docWord As Word.Document
Private ref As VBIDE.Reference
Private strTemplate As String

Private Sub Main()
' strTemplate has to be set to path of template to which reference is to
be added
' strTemplate = CurDir$ & "\TestMe.dot" ' For VB
' strTemplate = "APath\TestMe.dot" ' For VBA
Set appWord = New Word.Application
blnUseAppWord = False
Debug.Print "False"
Debug.Print RunTest1()
Debug.Print RunTest2()
blnUseAppWord = True
Debug.Print "True"
Debug.Print RunTest1()
Debug.Print RunTest2()
blnUseAppWord = False
Debug.Print "False"
Debug.Print RunTest1()
Debug.Print RunTest2()
Debug.Print "False"
Debug.Print RunTest1()
Debug.Print RunTest2()
Set docWord = Nothing
Set ref = Nothing
appWord.Quit
Set appWord = Nothing
End Sub

Private Function RunTest1() As String
Dim docNew As Word.Document
If blnUseAppWord Then
Set docNew = appWord.Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
Else
Set docNew = Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
End If
Set docWord = docNew.AttachedTemplate.OpenAsDocument
docNew.Close
With docWord
With .VBProject
On Error Resume Next
' Remove reference
.References.Remove .References(strReference)
Err.Clear
' Add reference
Set ref = .References.AddFromFile(strDLLPath)
End With
If Err.Number = 0 Then
RunTest1 = "Reference was added."
.Save
Else
RunTest1 = "Could not add reference: " & Err.Number & ", " &
Err.Description
End If
.Close
End With
Set docNew = Nothing
End Function

Private Function RunTest2() As String
Dim docOther As Word.Document
If blnUseAppWord Then
Set docOther = appWord.Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
Else
Set docOther = Documents.Add(NewTemplate:=False,
DocumentType:=wdNewBlankDocument, _
Template:=strTemplate)
End If
With docOther
' .AttachedTemplate = NormalTemplate.Name
' .AttachedTemplate = strTemplate
On Error Resume Next
Set ref = .AttachedTemplate.VBProject.References(strReference)
If Err.Number = 0 Then
RunTest2 = "Test Passed - Reference " & strReference & " was
found."
Else
RunTest2 = "Test Failed - Reference " & strReference & " was not
found: " & _
Err.Number & ", " & Err.Description
End If
.Saved = True
.Close
End With
Set docOther = Nothing
End Function
 
H

Howard Kaikow

Bingo!!!

It's a Word bug/feature!

Code works as expected in Word 97.
Problem occurs with Word 2000, Word 2002 and Word 2003.
All English (US) versions.

Even if MSFT would fix the problem for Word 2003, the problem would still
exist for Word 2000 and Word 2002, preventing proper coding across
versions.
 
H

Howard Kaikow

In case anybody's interested, I've reproduced the problem automating Word
from within Word itself, Excel, VB 6 and VB .NET 2003.
Of course, that should be expected.
 

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