Hands-on 8: Automation using Word

advertisement
Database Design 3
Hands-on Excercises
Hands-on 8: Automation using Word
To work with Office documents (such as Word or Excel) using VBA code you need to use
Automation. This allows you to work with the object models of the other applications.
In this exercise you will explore automation with Word.
Set a reference to Word’s Object Library
The first stage in writing Automation code is to set a reference to the object model of the
application you want to work with.
To set the Word object library reference:
Open the VBA Editor and click Tools > References... to display the References dialog.
Make sure a reference is set to the Word 11 object library. You might need to scroll the list to
find this. If it is not checked already, click the check box.
Fig.12.1: Setting reference to Word’s Object Library
View the Word object model using the Object Browser
Open the VBA Editor and press F2 to open the Object Browser. Select Word from the libraries
list.
The Classes pane lists the objects, collections and enumerations that
are available. Selecting an item from this list displays the associated
properties, methods and events in the Members pane. When you select
one of these, the syntax will be displayed in the status bar at the bottom
of the screen.Create a new standard module
533565558
Page 1
of 9
Database Design 3
Hands-on Excercises
You will be writing several functions to automate Word from Access. It would be useful if
these were available to any forms in your application. You will store all of these together in a
standard module.
To make the same Word application available to all the functions in the module we will
declare it as a Private variable in the General Declarations section at the start of the module.
The Word application is an Object variable.
Option Compare Database
Option Explicit
Private objWord As Object
Note: The two Option lines should be inserted when you open a new module. To ensure that
the Option Explicit statement (that forces you to declare variables before using them) is
always inserted click Tools > Options and check the require variable declarations check box
in the Editor tab.
Create a Word instance
You will first write a function that will open word. The application needs to be opened before
you can work with it. Any function that needs to use Word can call this function.
Public Function OpenWord()
On Error GoTo Err_OpenWord
Set objWord = GetObject(, "Word.Application")
objWord.Application.Visible = True
Exit_OpenWord:
Exit Function
Err_OpenWord:
If Err = 429 Then 'word is not running
Set objWord = CreateObject("Word.Application")
Resume Next
Else
MsgBox "Error no. " & Err.Number
Resume Exit_OpenWord
End If
End Function
This code initially uses the GetObject function to open Word. GetObject opens an instance of
Word if it is already running. It is best to use this first as otherwise you will have two versions
of Word open. This is not necessarily a problem with the large amounts of memory available
today but it is better practice to use the existing open version if possible.
If GetObject is called when Word is not running it generates error 429. The error handling
code traps this error and calls the CreateObject function to open a new version of Word. If
there is an error other than this, an error message is displayed to the user and the function
exits.
Use F8 to step through the code both with a running version of Word and with Word closed.
You will see that there is a different path through the function in each case.
Enter this code into your module and test it (press F5 with the cursor somewhere inside the
function to run the code directly from the editor. Word should open with no document
displayed.
Create a new blank document in Word
533565558
Page 2
of 9
Database Design 3
Hands-on Excercises
Public Function OpenNewWordDoc()
' Uses OpenWord function to open Word
' Opens new blank document
On Error GoTo Err_OpenNewWordDoc
Dim docWord As Word.Document
OpenWord
Set docWord = objWord.Documents.Add
Exit_OpenNewWordDoc:
Exit Function
Err_OpenNewWordDoc:
MsgBox "Error no. " & Err.Number
Resume Exit_OpenNewWordDoc
End Function
Close the document and Word
Of course, you will actually want to use the document you have opened in some way but
before we look at how you might do that we will write the code to close the document and exit
Word.
Adding the two lines below to your code will close the document and release the object
reference.
docWord.Close
Set docWord = Nothing
To close the Word application you need to use the Quit method:
objWord.Quit
The complete function up to this point with the new code highlighted is shown below:
Public Function OpenNewWordDoc()
' Uses OpenWord function to open Word
' Opens new blank document
On Error GoTo Err_OpenNewWordDoc
Dim docWord As Word.Document
OpenWord
Set docWord = objWord.Documents.Add
docWord.Close
Set docWord = Nothing
objWord.Quit
Set objWord = Nothing
Exit_OpenNewWordDoc:
Exit Function
Err_OpenNewWordDoc:
MsgBox "Error no. " & Err.Number
533565558
Page 3
of 9
Database Design 3
Hands-on Excercises
Resume Exit_OpenNewWordDoc
End Function
Again, use F8 to step through the function to see how it works. You should see that the code
starts Word, opens a new blank document and then closes it and exits Word.
Although Word is successfully closed there is one problem with the approach we have taken
here. If the user already had a version of Word running our code used that instance rather
than opening a new one. If the user had unsaved documents open in Word they have now
been closed which might have resulted in lost work. To avoid this happening we need to add
code so that the function will only close Word if it also opened it. To do this we will use a flag
– a Boolean variable that will be set to true if the function has opened Word and False
otherwise.
As we are using the OpenWord function to open Word, we need to set the flag in this function
and then test its value in any other functions that are using Word. As the flag needs to be
available to all the functions in the module we will declare it as a private variable in the
declarations section at the start of the module in the same way as we declared the Word
variable earlier.
Option Compare Database
Option Explicit
Private objWord As Object
Private blOpenedWord As Boolean
Then add the following code to the error handling section of the OpenWord function:
Public Function OpenWord()
...
Err_OpenWord:
If Err = 429 Then 'word is not running
Set objWord = CreateObject("Word.Application")
blOpenedWord = True
Resume Next
...
Now when the function opens a new copy of Word, the flag will be set to true. The code that
closes Word can now check the value of this flag and only close Word if it was opened by our
function. Add this code to the OpenNewWordDoc function to test the value of the flag before
closing Word.
Public Function OpenNewWordDoc()
...
OpenWord
Set docWord = objWord.Documents.Add
docWord.Close
Set docWord = Nothing
If blOpenedWord = True Then
objWord.Quit
End If
Set objWord = Nothing
...
Again test the function by stepping through it both with an open and closed version of Word.
You should notice that if Word is already open when you run the function the Quit method is
not executed.
Inserting text
533565558
Page 4
of 9
Database Design 3
Hands-on Excercises
Now add some code to the OpenNewWordDoc function to insert some text into the document.
To do this we will use the TypeText method of the Selection object. The Selection object is
the text selected (or the position of the insertion point) in the currently active Word document.
Once we have inserted a line of text we will use the TypeParagraph method of the Selection
object to insert a new line character.
Insert this code into your OpenNewWordDoc function:
Set docWord = objWord.Documents.Add
' insert text into the Word document
objWord.Selection.TypeText "This document was created
automatically by Access"
objWord.Selection.TypeParagraph
objWord.Selection.TypeText "It will now be closed and saved"
objWord.Selection.TypeParagraph
objWord.Activate
This code will insert two lines of text into your Word document. The last statement uses the
Activate method to display Word on your screen.
Save and Close the document
Not surprisingly, we will use the Save and Close methods of the document object to do this.
The Save method will open the Save As box if the document hasn’t been saved before so
that the user can select a folder and enter a file name for the document. insert the following
lines into your function:
docWord.Save
docWord.Close
Set docWord = Nothing
The final line of this code releases the memory used by the docWord variable.
Test the function. It should open a new Word document, insert the specified text, and then
open the Save As dialog to allow you to save the file. Provided you do save the file everything
is ok. However, if you click the Cancel button you generate error 4198 – Command
Cancelled. You need to add appropriate error handling code to the function to deal with this. It
is sufficient to add general purpose error handling unless you want to deal with error 4198
specifically.
The completed code for this function is given below:
Public Function OpenNewWordDoc()
' Uses OpenWord function to open Word
' Opens new blank document
On Error GoTo Err_OpenNewWordDoc
Dim docWord As Word.Document
OpenWord
Set docWord = objWord.Documents.Add
' objWord.Activate
' insert text into the Word document
objWord.Selection.TypeText "This document was created
automatically by Access"
objWord.Selection.TypeParagraph
objWord.Selection.TypeText "It will now be closed and saved"
objWord.Selection.TypeParagraph
objWord.Activate
docWord.Save
533565558
Page 5
of 9
Database Design 3
Hands-on Excercises
docWord.Close
Set docWord = Nothing
If blOpenedWord = True Then
objWord.Quit
End If
Set objWord = Nothing
Exit_OpenNewWordDoc:
Exit Function
Err_OpenNewWordDoc:
MsgBox "Error no. " & Err.Number
Resume Exit_OpenNewWordDoc
End Function
Open an existing document
To open an exisitng document you use the Open method of the Documents object. The first
argument to the method is the name of the file you wish to open. You need to use the full
pathname for the file. The following code will open a file named empMemo.doc, stored in the
D3 folder of the I: drive.
appWord.Documents.Open("I:\D3\empMemo.doc")
Note:
You can use the Path property of the current project to get the path for the folder where your
database is located. Test this out by typing print CurrentProject.Path into the
Immediate Window. Press Enter and you will see the drive and folder for your current
database displayed. This method is used in the following code to open a file named
empMemo.doc stored in the same folder as the database.
Add this function to your modWordUtilities module.
You might want to consider passing the file name as an argument to the function to make it
more general purpose.
Public Function OpenWordDoc()
On Error GoTo Err_OpenWordDoc
Dim fname As String
Dim docWord As Word.Document
OpenWord
' file name needs to include path
' if file to open is in same folder as database can use Path
attribute of current project
fname = CurrentProject.Path & "\empMemo.doc"
Set docWord = objWord.Documents.Open(fname)
Exit_OpenWordDoc:
Exit Function
Err_OpenWordDoc:
MsgBox "Error no. " & Err.Number
Resume Exit_OpenWordDoc
End Function
Create a Word Memo for all Yum employees
533565558
Page 6
of 9
Database Design 3
Hands-on Excercises
You will now use Word Automation to create a memo document to be sent to all Yum
employees. Before you can do that you will need to create a query to list the employee
names.
Create a query to list the employee names
To provide the list of employee names to be used by Word to create the memo we will use a
query that will combine the employee first name and surname in a single field. Create this
query as shown below and save it with a meaningful name.
Fig. 12.2: Employee name query to be used as data source for memo
The Word document
The Word document you will use for this exercise has already been created for you.
Download it from WebCT and save it in the same folder as your database (this will simplify
the code to open the file as you can then use the CurrentProject.Path as discussed above).
We are going to write text to specific locations in this document, identified by bookmarks. Two
bookmarks have been set – one for the position of the date and the other for the position of
the employee names. You can see the Bookmarks that are set in a Word document by
clicking Bookmark from the Insert Menu.
533565558
Page 7
of 9
Database Design 3
Hands-on Excercises
If you click the Go To button the insertion point will be moved to the specified bookmark.
Insert the date and list of names
The following code will insert today’s date and the list of employee names at the appropriate
points in the memo document. You need to make sure that you have created the employee
names query and saved the memo document to the same folder as your database before
running the code.
Public Function CreateWordMemo()
' Open memo in Word and insert text
On Error GoTo CreateWordMemo_Error
Dim
Dim
Dim
Dim
Dim
Dim
dbs As Database
rstEmployees As Recordset
appWord As Word.Application
docWord As Word.Document
fname As String
strDate As String
strDate = Date 'assign date to string variable so we can
print it
OpenWord ' use function to open Word
'Open recordset based on employee name query
Set dbs = CurrentDb()
Set rstEmployees = dbs.OpenRecordset("qryEmpFullName")
' open the memo document
' assume memo document in same folder as database
fname = CurrentProject.Path & "\empMemo.doc"
533565558
Page 8
of 9
Database Design 3
Hands-on Excercises
Set docWord = objWord.Documents.Open(fname)
objWord.Visible = True
With objWord
.Selection.Goto wdGoToBookmark, Name:="DateToday" 'move
to date bookmark
.Selection.TypeText " " & strDate 'insert date
.Selection.Goto wdGoToBookmark, Name:="MemoToLine" 'move
to memo line bookmark
End With
'Loop through recordset returned by query, inserting name of
each employee
Do Until rstEmployees.EOF
objWord.Selection.TypeText rstEmployees!Employee & ", "
rstEmployees.MoveNext
Loop
'reset variables to nothing and free up memory for other
processes
Set rstEmployees = Nothing
Set dbs = Nothing
Set docWord = Nothing
Set objWord = Nothing
Exit_CreateWordMemo:
Exit Function
CreateWordMemo_Error:
'error trapping routine
MsgBox Err.Description
Resume Exit_CreateWordMemo
End Function
The comments embedded in the code should help you to understand how it works. You can
test it from the VBA editor by pressing F8 with the insertion point somewhere inside the
function.
Notice that although the code frees the variables, it does not close Word. This means that the
document is open in Word for the user to save or edit as they choose. If you want to save the
document it is best to use Save As or you will write duplicate text to the same document the
next time you run the function.
Once you are happy that the function works as it should, create a utilities form and add a
button to allow the user to create an employee memo.
Enhancements
At the moment only the date and list of employees are entered automatically by Access. The
user then needs to enter the memo text directly into Word. One simple improvement that
could be made is to add another Bookmark to the Word document at the position where the
memo text needs to be entered. Then add a line of code to your function so that the
document is ready for the user to enter text.
You could also consider passing the recordset as a parameter so that the user could select
who the memo would be sent to. To do this you would pass a string containing the name of
the query to be used.
A final modification would be to add a text box to your form to allow the user to enter the
memo content. This would then be passed as a string to the function and printed to the
appropriate bookmark by your code.
533565558
Page 9
of 9
Download