How to access a Word document object from VB?

R

raymond jasinski

What I want to be able to do is write to a table in a Word 2002 document
from VB Express Edition 2008. Evidently one uses a statement like 'Imports
Microsoft.Office.InterOp' to allow one to reference an Office application
(like Word, Excel, etc.). One then has

Imports Microsoft.Office.InterOp

Dim oWord As Application
Dim oDoc as Word.Document
oWord = GetObject(, "Word.Application")

With oDoc.Tables(1)
(Code to fill table cells)
End With

However, VB (the editor) says Microsoft.Office.InterOp contains no public
member, etc., so the technique fails. What to do?
 
C

Cindy M.

Hi Raymond,

There are a number of PIAs (references) when automating (interoping with)
Office, depending on which functionality you require. The Imports statement
for the general Office functionality - things all Office applications share,
such as toolbars (CommandBars) - would be Microsoft.Office.Core.

For Word you need to set a Reference to the Microsoft Word library. Then you
can create an Imports Microsoft.Office.Interop.Word (it's the name of the
application you've been missing, up until now, but you can't get it if you
don't have the Reference).

Note: Office 2002 doesn't come with a set of PIAs. But they can be downloaded
from msdn.microsoft.com. If you haven't done so, then your project generated a
set of IAs. You could use these, but you have to realize that they are not
optimized. This means that things may not work the way you expect (or that you
see in code snippets and samples).

If you're distributing your application you need to make sure this set of IAs
is part of your solution and will be installed with it. If you use the PIAs
(recommended), then you need to distribute those. (The download is a
redistributable.)
What I want to be able to do is write to a table in a Word 2002 document
from VB Express Edition 2008. Evidently one uses a statement like 'Imports
Microsoft.Office.InterOp' to allow one to reference an Office application
(like Word, Excel, etc.). One then has

Imports Microsoft.Office.InterOp

Dim oWord As Application
Dim oDoc as Word.Document
oWord = GetObject(, "Word.Application")

With oDoc.Tables(1)
(Code to fill table cells)
End With

However, VB (the editor) says Microsoft.Office.InterOp contains no public
member, etc., so the technique fails. What to do?

Cindy Meister
INTER-Solutions, Switzerland
http://homepage.swissonline.ch/cindymeister (last update Jun 17 2005)
http://www.word.mvps.org

This reply is posted in the Newsgroup; please post any follow question or
reply in the newsgroup and not by e-mail :)
 
R

raymond jasinski

Hi Cindy,

I had already done the following before I read your reply:

I tried the code in the "Control Word from Excel" example at
http://www.word.mvps.org/FAQs/InterDev/ControlWordFromXL.htm using Excel
and Word. It works. Sort of.
1. I created a form using VBA in Excel with a button which executes the
aforementioned code when clicked:
A. Word opens displaying a document containing the word "Hi" and a
"replace" dialog box set to replace "Hi" with "Ho".
B. The dialog box will change the open Word document the way it's
supposed to, but
C. an error occurs when you close the Word document.

2. I then was able to open Word from VB using the same code as above
(adapted to VB Express Edition 2008)(again using a button on a form) after
having set a reference to the Microsoft Word library.

A. Word opens but there is evidently an enumeration missing since it
bombs on the statement
With myDialog
.Find ="Hi"
.Replace="Ho"
End With
because "Find" is not defined. Evidently, more references or
perhaps "Imports" statements are needed.

I will definitely follow your advice. As you say, the code doesn't behave
quite as one would expect. There is some work to do.

Once I get the sample code to work, I should then know how to run and use
Word from inside my VB program.

I will keep you posted.

Thanks for your response.

(I apologize for the email. I thought I was posting to this newsgroup.)
 
C

Cindy M.

Hi Raymond,
C. an error occurs when you close the Word document.
I can't comment, not knowing the code, the error message, or the exact
circumstances involved.
A. Word opens but there is evidently an enumeration missing since it
bombs on the statement
With myDialog
.Find ="Hi"
.Replace="Ho"
End With
because "Find" is not defined.
In order to offer an opinion, we'd need to know how myDialog is
defined and exactly what you intend. But I get the feeling you need to
look up an article on how to use Find. In the object model it's not
used via a dialog box. Find is a property of the Range or Selection
object. One sets additional properties, then uses the Execute method.
Record it in a macro to get the basics...

Cindy Meister
INTER-Solutions, Switzerland
http://homepage.swissonline.ch/cindymeister (last update Jun 17 2005)
http://www.word.mvps.org

This reply is posted in the Newsgroup; please post any follow question
or reply in the newsgroup and not by e-mail :)
 
R

raymond jasinski

Cindy,

The code works like it's supposed to from within Excel VBA without
modification (follow the link in my previous response if you want to see
the original Excel VBA code)(it's pretty much the same as below). When I
previously said it didn't work, I simply didn't understand how it was
supposed to.
The code does not work from within VB Express Edition 2008. Word comes up
but VB still can't find "myDialog.Find" .

I've yet to install the PIAs. Does Access 2003 also require a PIA install?
(The rest of my Office suite is 2002.)

Notice the 2 "Imports....." statements at the top. Why do you have to have
these statments? The items referred to are in the Word namespace which is
referenced, so VB already knows it's there. Evidently you have to reference
and import, both????

Here is the VB code:

(Could've taken out the Msgboxes but I left things pretty much as I found
them.)

What happens is that when you click the button on the form, Word opens and
then a dialog box is supposed to open, but it bombs on the ".Find" instead.

*****************************************************
Imports Word.WdWordDialog

Imports Word.WdSaveOptions

Public Class Form1

Private Sub btnOpenWord_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnOpenWord.Click

Dim myWord As Word.Application

Dim WordWasNotRunning As Boolean

Dim myDoc As Word.Document

Dim myDialog As Word.Dialog

Dim UserButton As Long

'Get existing instance of Word if it's open; otherwise create a new one

On Error Resume Next

myWord = GetObject(, "Word.Application")

If myWord.Equals(Nothing) Then

myWord = New Word.Application

WordWasNotRunning = True

End If

On Error GoTo Err_Handler

myWord.Visible = True

myWord.Activate()

myDoc = myWord.Documents.Add

myDoc.Range.Text = "Hi"

myDialog = myWord.Dialogs(wdDialogEditReplace)

With myDialog

..Find = "Hi" 'Bombs here

..Replace = "Ho"

End With

On Error Resume Next

UserButton = myDialog.Display()

On Error GoTo Err_Handler

MsgBox("User Button = " & CStr(UserButton))

MsgBox("Find = " & CStr(myDialog.Find))

MsgBox("Replace = " & CStr(myDialog.Replace))

MsgBox("Direction = " & CStr(myDialog.Direction))

MsgBox("Wrap = " & CStr(myDialog.Wrap))

MsgBox("Format = " & CStr(myDialog.Format))

MsgBox("MatchCase = " & CStr(myDialog.MatchCase))

MsgBox("WholeWord = " & CStr(myDialog.WholeWord))

MsgBox("PatternMatch = " & CStr(myDialog.PatternMatch))

MsgBox("FindAllWordForms = " & CStr(myDialog.FindAllWordForms))

MsgBox("SoundsLike = " & CStr(myDialog.SoundsLike))

MsgBox("FindNext = " & CStr(myDialog.FindNext))

MsgBox("ReplaceOne = " & CStr(myDialog.ReplaceOne))

MsgBox("ReplaceAll = " & CStr(myDialog.ReplaceAll))

MsgBox("MatchByte = " & CStr(myDialog.MatchByte))

MsgBox("FuzzyFind = " & CStr(myDialog.FuzzyFind))

MsgBox("Destination = " & CStr(myDialog.Destination))

myDoc.Close(SaveChanges:=wdDoNotSaveChanges)


If WordWasNotRunning Then

myWord.Quit()

End If

'Make sure you release object references.

myWord = Nothing

myDoc = Nothing

myDialog = Nothing

'quit

Exit Sub

Err_Handler:

MsgBox("Word caused a problem. " & Err.Description, vbCritical, "Error: " _

& Err.Number)

If WordWasNotRunning Then

myWord.Quit()

End If

End Sub

End Class

*****************************************************************************
 
C

Cindy M.

Hi Raymond,
The code works like it's supposed to from within Excel VBA without
modification
Excel VBA is irrelevant when you're working with Word. The two object models
are in no respect the same. You cannot take code from one and use it in the
other.
I've yet to install the PIAs. Does Access 2003 also require a PIA install?
(The rest of my Office suite is 2002.)
Whether or not you need the PIA for any particular applications depends on
whether you're planning to automate the application interface. Under most
circumstances I wouldn't expect you to need to automate Access, as you'd use
the ADO.NET capabilities to work with the data...

But if you haven't installed any PIAs, how is that you're able to test the code
you show us? (I suppose, if the PIAs aren't present, your project may have
automatically created a set of IAs...)
Notice the 2 "Imports....." statements at the top. Why do you have to have
these statments? The items referred to are in the Word namespace which is
referenced, so VB already knows it's there. Evidently you have to reference
and import, both????

Imports Word.WdWordDialog
Imports Word.WdSaveOptions
As far as I know, you shouldn't need either of these. I suppose you could have
them, as it would shorten the code lines when you need to use the Enums they
hold. But at some point your code will become unreadable if you do this a
lot...
On Error Resume Next
myWord = GetObject(, "Word.Application")
I strongly urge you to NOT use this in your .NET code. Use the Try...Catch
blocks for your error handling. And use the .NET Framework equivalent of
GetObject: GetActiveObject()

If you search the VSTO forum (http://forums.microsoft.com/msdn/showforum.aspx?
forumid=16&siteid=1&sb=0&d=1&at=7&ft=11&tf=0&pageid=0) on MSDN you'll find a
number of examples how to use this method.
'Make sure you release object references.

myWord = Nothing
myDoc = Nothing
myDialog = Nothing
You're doing this in the wrong order. You need to release objects in the
reverse order they were instantiated. If you release the application object
(myWord) first, then myDoc and myDialog are "orphaned" and cannot be released:
they both depend on the Application object for their existance.
myDialog = myWord.Dialogs(wdDialogEditReplace)
With myDialog
..Find = "Hi" 'Bombs here
As I mentioned before, you should work with Word's object model, not over the
Dialog for this... Do you have Option Strict On in your project? If you do, you
won't be able to use late-binding the same way the classic VB languages can.
You'd need to use PInvoke (GetType().InvokeMember). That's not a simply way to
proceed...

Cindy Meister
INTER-Solutions, Switzerland
http://homepage.swissonline.ch/cindymeister (last update Jun 17 2005)
http://www.word.mvps.org

This reply is posted in the Newsgroup; please post any follow question or reply
in the newsgroup and not by e-mail :)
 

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