Creating MS Word Documents (Part 1)
This is the first in a 4-part series concerning creating MS Word documents in LotusScript. In this tip, we'll talk about the basics of creating a Word document and adding text to it. In the next tip, we'll get a bit more advanced with some formatting options, and the last two tips we'll talk about updating headers and footers and some other advanced topics. The first thing I'll point out is that we have all these functions in a script library. There's advantages and disadvantages to doing it this way. The advantage is that everything is centrallized and somewhat hidden from the developer using the script library - the developer doesn't need to know how to navigate the MS Word Document Model. The main disadvantage is that there's tons of functions in the script library, so it becomes difficult to find the function you need.
Speaking of the MS Word Document Model, it can be found at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbawd10/html/wotocObjectModelDocument.asp. You click on the item and navigate through the model. That web site doesn't work very well in Firefox - you probably want to use IE to access it. And the "back" button doesn't work very well - a lot happens on page load to screw up the browser's history.
The first thing we need is a way to create a new Word document. There are two ways to do this in LotusScript - either by creating a new object or adding on to the existing object. "Existing Object" means the existing instance of Word if it has already been loaded. So our code attempts to find the existing instance first. If that can't be found, then a new instance is created. Either way, a new document is added and a handle to the document is returned.
Function CreateMSWordDocument(isVisible As Integer) As Variant
Dim msWord As Variant
On Error Goto CreateNewInstance
Set msWord = GetObject("", "Word.Application")
Done:
If isVisible Then msWord.Visible = True Else msWord.Visible = False
msWord.documents.Add
Set CreateMSWordDocument = msWord.ActiveDocument
Exit Function ' ==================
CreateNewInstance:
Print "Loading Microsoft Word.... Please Wait...."
Err = 0
Set msWord = CreateObject("Word.Application")
Print " "
Resume Done
End Function
The code works by setting an error trap and then attempting to get the existing instance of the MS Word application. If that errors out, the code jumps down to the "CreateNewInstance" block. This block clears the error handler and creates a new object before returning to the "Done" block.
The "Done" block sets whether MS Word should be visible or hidden. Our experience has shown that hiding MS Word makes the code run faster, but it certainly comes at a price - if you have any errors anywhere you won't be able to return back to MS Word (because it's hidden). So we will generally test with MS Word as visible and after we are sure that all errors are trapped and any possible error un-hides Word, then we will set the visibility to hidden to speed things up.
A new document is added to Word, and that new document is returned from this function. The fact that we return ActiveDocument is somewhat key - the rest of the functions in our script library rely on this information. The developer using the function doesn't care what is returned; they just have to realize that the return value needs to be passed in to other functions.
Note that you are working with objects in the code (the Set statement is used). So your calling function must work with objects. You would need to use code similar to the following:
Sub Initialize
Dim objWord As Variant
Set objWord = CreateMSWordDocument(True)
' Perform the rest of the functions on the MS Word Object
End Sub
The next thing we need to know is how to close MS Word when we are done. Sometimes you'll want to leave Word open for the user to interact with the document you created, but other times you want to close Word when you're finished.
Sub CloseMSWord
Dim msWord As Variant
On Error Goto CreateNewInstance
Set msWord = GetObject("", "Word.Application")
Done:
msWord.Quit
Exit Sub ' =========================
CreateNewInstance:
Print "Loading Microsoft Word.... Please Wait...."
Err = 0
Set msWord = CreateObject("Word.Application")
Print " "
Resume Done
End Sub
The code works similarly to the "Create" function - it gets the existing handle (trapping for the case where Word was already closed) and then calls "Quit". Note that this will close all instances - if the user had Word open working on their own stuff, it will close that (but prompt if they want to save changes).
The next thing we'll look at is adding text to the document. This function takes two parameters. The first is a handle to the document that was returned from the "Create" function. The second is the text to be appended to the end of the document. It returns a handle to the text that was inserted. The return value is important, because you can call other functions (shown in future tips) to do things this make it bold or italics or underline.
Function AppendTextToDoc(doc As Variant, text As String) As Variant
Dim lastParagraph As Variant
Dim newRangeStart As Long
' Find the last paragraph in this document
Set lastParagraph = doc.Paragraphs(doc.Paragraphs.Count).Range
newRangeStart = lastParagraph.End-1 ' This is where the new text will be placed
Call lastParagraph.InsertAfter(text)
' Reset the range handle to include the text we just entered and only that text.
Set lastParagraph = doc.Paragraphs(doc.Paragraphs.Count).Range
Call lastParagraph.SetRange(newRangeStart, lastParagraph.End)
Set AppendTextToDoc = lastParagraph
End Function
The variable lastParagraph points to the end of the passed-in document. Refer to the MSDN documentation to find out how paragraphs work programmatically in Word. It then saves a pointer to the start of that range. This is so we can return only the text that was inserted. The text is inserted and a new Range object is created that includes only the text that was inserted. That object is returned to the calling code.
Again, we have an object. So you'll need to use the Set statement in the calling code to get a handle to the range that is returned.
Well, that's enough for this tip. Take a look at the MSDN Documentation to find out all the things that you can do programmatically. Since you're working with LotusScript, you have to be aware of the syntax that you see on the web site. It takes trial and error to figure everything out. And also note that the documentation uses many constants that just won't exist in LotusScript. The way to find out the constants is to use the MS Word Macro debugger. I'll post more on that in the next tip.