C H A P T E R    7 Microsoft Office 97/Visual Basic Programmer's Guide

Microsoft Word Objects


Contents

Visual Basic supports a set of objects that correspond directly to elements in Microsoft Word 97, most of which you're familiar with from the user interface. For example, the Document object represents an open document, the Bookmark object represents a bookmark in a document, and the Selection object represents the selection in a document window pane. Every type of element in Word — documents, tables, paragraphs, bookmarks, fields, and so on — can be represented by an object in Visual Basic. To automate tasks in Word, use methods and properties of these objects.

For general information about understanding and navigating the object models in Microsoft Office 97, see Chapter 2, "Understanding Object Models." The object model in Microsoft Word 97 is extensive, encompassing approximately 180 objects. To view a graphical representation of the Word object model, see "Microsoft Word Objects" in Help. For a detailed description of a specific object, click the name of the object on the diagram, or search for the specific object name in the Help index.

How Do I Display Visual Basic Help for Word?

To use Visual Basic Help for Word, you must click Custom during Setup and select the Online Help for Visual Basic check box for Word. Otherwise, Visual Basic Help won't be installed. If you've already installed Word, you can run Setup again to install Visual Basic Help.

To see the contents and index of Visual Basic Help for Word, click Contents and Index on the Help menu in the Visual Basic Editor. On the Contents tab in the Help Topics dialog box, double­click "Microsoft Word Visual Basic Reference," and then double­click "Shortcut to Microsoft Word Visual Basic Reference." The Help Topics dialog box should reappear, displaying the contents and index for Visual Basic Help for Word.

Working with the Application Object

When you start a Word session, you automatically create an Application object. You use properties or methods of the Application object to control or return application­wide attributes, to control the appearance of the application window, and to get to the rest of the Word object model. Use the Application property to return the Word Application object. The following example switches the view to print preview.

Application.PrintPreview = True

Some properties of the Application object control the appearance of the application. For example, if the DisplayStatusBar property is True, the status bar is visible, and if WindowState property is wdWindowStateMaximize, the application window is maximized. The following example sets the size of the application window on the screen.

With Application
    .WindowState = wdWindowStateNormal
    .Height = 450
    .Width = 600
End With

Properties of the Application object also provide access to objects lower in the object hierarchy, such as the Windows collection (representing all currently open windows) and the Documents collection (representing all currently open documents). You use properties, which are sometimes called accessors, to move down through the object hierarchy from the top­level Application object to the lower levels (Document, Window, Selection, and so forth). You can use either of following examples to open MyDoc.doc.

Application.Documents.Open FileName:="C:\DOCS\MYDOC.DOC"
Documents.Open FileName:="C:\DOCS\MYDOC.DOC"

Because the Documents property is global, the Application property is optional. Global properties and methods don't need the Application object qualifier. To view the list of global properties and methods in the Object Browser, click <globals> in the Classes box. The global items are listed in the Members of box.

Note   The Options object includes a number of properties that control the global behavior of Word. Many of the properties for the Options object correspond to items in the Options dialog box (Tools menu). Use the Options property of the Application object to return the Options object. The following example sets three application­wide options (because the Options property is global, the Application property isn't needed in this example).

With Application.Options
    .AllowDragAndDrop = True
    .ConfirmConversions = False
    .MeasurementUnit = wdPoints
End With

Working with the Document Object

When you open or create a file in Word, you create a Document object. You use properties and methods of the Document object or the Documents collection to open, create, save, activate, and close files.

Returning the Document Object

You can return any open document as a Document object, using the syntax Documents(index), where index is the document's name or index number. In the following example, the variable myDoc contains a Document object that refers to the open document named "Report.doc."

Set myDoc = Documents("Report.doc")

The index number represents the position of the document in the Documents collection. In the following example, the variable myDoc contains a Document object that refers to the first document in the Documents collection.

Set myDoc = Documents(1)

Note   Because the index number of a particular document can change when you add or close documents, it's best to use the document name to index a Document object in the Documents collection.

In addition to referring to a document by either its name or index number, you can use the ActiveDocument property to return a Document object that refers to the active document (the document with the focus). The following example displays the name of the active document; if there are no documents open, the example displays a message.

If Documents.Count >= 1 Then 
    MsgBox ActiveDocument.Name
Else
    MsgBox "No documents are open"
End If

Opening Documents

To open an existing document, use the Open method. The Open method applies to the Documents collection, which you return using the Documents property. The following example opens the file Test.doc (from the current folder) and turns on change tracking.

Set myDoc = Documents.Open(FileName:="TEST.DOC")
myDoc.TrackRevisions = True

Notice that the return value of the Open method in the preceding example is a Document object that represents the document that was just opened. The file name in the example doesn't contain a path; therefore, the file is assumed to be in the current folder. This is guaranteed to cause a run­time error, because as soon as the user makes a different folder the current folder, Visual Basic can no longer find the file. You can, however, ensure that the correct file is opened by specifying the complete path, as shown in the following table.

Operating system FileName
Windows FileName:="C:\Documents\Temporary File.doc"
Macintosh FileName:="Hard Drive:Documents:Temporary File"

If your macro is intended for only one file system, you can hard­code the path separator ("\" or ":") in the FileName argument, as shown in the preceding table. The following example shows file­system­independent code you can use to open Sales.doc, assuming that Sales.doc has been saved in the Word program folder.

programPath = Options.DefaultFilePath(wdProgramPath)
Documents.Open FileName:=programPath & Application.PathSeparator & "SALES.DOC"

The PathSeparator property returns the correct separator character for the current file system (for example, "\" for MS­DOS/Windows FAT or ":" for the Macintosh). The DefaultFilePath property returns folder locations such as the paths for the document folder, the program folder, and the current folder.

An error occurs if the specified file name doesn't exists in either the current folder (if a path isn't specified) or the specified folder (if a path is specified). The following example uses properties and methods of the FileSearch object to determine whether a file named "Test.doc" exists in the user's default document folder. If the file is found (FoundFiles.Count = 1), it's opened; otherwise, a message is displayed.

defaultDir = Options.DefaultFilePath(wdDocumentsPath)
With Application.FileSearch
    .FileName = "Test.doc"
    .LookIn = defaultDir
    .Execute
    If .FoundFiles.Count = 1 Then
        Documents.Open FileName:=defaultDir & Application.PathSeparator & "TEST.DOC"
    Else
        MsgBox "Test.doc file was not found"
    End If
End With

Instead of hard­coding the FileName argument of the Open method, you may want to allow a user to select a file to open. Use the Dialogs property with the wdDialogFileOpen constant to return a Dialog object that refers to the Open dialog box (File menu), as in the following example. The Show method displays and executes actions performed in the Open dialog box.

Dialogs(wdDialogFileOpen).Show

The Display method displays the specified dialog box without doing anything further. The following example checks the value returned by the Display method. If the user clicks OK to close the dialog box, the value –1 value is returned and the selected file, whose name is stored in the variable fSelected, is opened.

Set dlg = Dialogs(wdDialogFileOpen)
aButton = dlg.Display
fSelected = dlg.Name
If aButton = -1 Then
    Documents.Open FileName:=fSelected
End If

For more information about displaying Word dialog boxes, see "Displaying built­in Word dialog boxes" in Help.

To determine whether a particular document is open, you can enumerate the Documents collection by using a For Each...Next statement. The following example activates the document named "Sample.doc" if it's already open; if it's not currently open, the example opens it.

docFound = True
For Each aDoc In Documents
    If InStr(1, aDoc.Name, "sample.doc", 1) Then 
        aDoc.Activate
    Exit For
    Else
        docFound = False
    End If
Next aDoc
If docFound = False Then Documents.Open _
    FileName:="C:\Documents\Sample.doc"

Use the Count property to determine how many documents are currently open. The Count property applies to the Documents collection, which you return using the Documents property. The following example displays a message if there are no documents open.

If Documents.Count = 0 Then MsgBox "No documents are open"

Creating and Saving Documents

To create a new document, apply the Add method to the Documents collection. The following example creates a new document.

Documents.Add

The Add method returns the document that was just created as a Document object. When you add a document, you can set the return value of the Add method to an object variable so that you can refer to the new document in your code. The following example creates a new document and sets its top margin to 1.25 inches.

Dim myDoc As Document
Set myDoc = Documents.Add
myDoc.PageSetup.TopMargin = InchesToPoints(1.25)

To save a new document for the first time, use the SaveAs method with a Document object. The following example saves the active document as "Temp.doc" in the current folder.

ActiveDocument.SaveAs FileName:="Temp.doc"

After a document is saved, you can use its document name to get to the Document object. The following example creates a new document and immediately saves it as "1996 Sales.doc." The example then uses the new name to index the document in the Documents collection and adds a table to the document.

Documents.Add.SaveAs FileName:="1996 Sales.doc"
Documents("1996 Sales.doc").Tables.Add _
    Range:=Selection.Range, NumRows:=2, NumColumns:=4

To save changes to an existing document, use the Save method with a Document object. The following instruction saves the document named "Sales.doc."

Documents("Sales.doc").Save

If you use the Save method with an unsaved document or template, the Save As dialog box will prompt the user for a file name. To save all open documents, apply the Save method to the Documents collection. The following example saves all open documents without prompting the user for their file names.

Documents.Save NoPrompt:=True

Activating a Document

To make a different document the active document, apply the Activate method to a Document object. The following example activates the open document (MyDocument.doc).

Documents("MyDocument.doc").Activate

The following example opens two documents and then activates the first one (Sample.doc).

Set Doc1 = Documents.Open(FileName:="C:\Documents\Sample.doc")
Set Doc2 = Documents.Open(FileName:="C:\Documents\Other.doc")
Doc1.Activate

Printing a Document

To print a document, apply the PrintOut method to a Document object, as shown in the following example.

ActiveDocument.PrintOut

To programmatically set print options that you'd otherwise set in the Print dialog box (File menu), use the arguments of the PrintOut method. You can use properties of the Options object to set print options that you'd otherwise set on the Print tab in the Options dialog box (Tools menu). The following example sets the active document to print hidden text and then prints the first three pages.

Options.PrintHiddenText = True
ActiveDocument.PrintOut Range:=wdPrintFromTo, From:="1", To:="3"

Closing Documents

To close a document, apply the Close method to a Document object. The following example closes the document named "Sales.doc."

Documents("Sales.doc").Close

If there are changes in the document, Word displays a message asking whether the user wants to save changes. You can prevent this prompt from appearing by using the wdDoNotSaveChanges or wdSaveChanges constant with the SaveChanges argument. The following example saves and closes Sales.doc.

Documents("Sales.doc").Close SaveChanges:=wdSaveChanges

To close all open documents, apply the Close method to the Documents collection. The following example closes all documents without saving changes.

Documents.Close SaveChanges:=wdDoNotSaveChanges

Accessing Objects in a Document

From the Document object, you have access to a number of properties and methods that return objects. To view a graphical representation of the objects available from the Document object, see "Microsoft Word Objects (Documents)" in Help. For example, the Tables property, which returns a collection of Table objects, is available from the Document object. Use the Count property with a collection object to determine how many items there are in the collection. The following example displays a message that indicates how many tables there are in the active document.

MsgBox ActiveDocument.Tables.Count & " table(s) in this document"

Use Tables(index), where index is the index number, to return a single Table object. In the following example, myTable refers to the first table in the document named "Sales.doc."

Set myTable = Documents("Sales.doc").Tables(1)

Information about returning a particular object is available in the object topic itself (for example, "Table Object") and in the corresponding collection object topic (for example, "Tables Collection Object") in Help.

Adding Objects to a Document

You can add objects, such as a footnotes, comments, or tables, to a document using the Add method with a collection object accessed from the Document object. For example, the following instruction adds a 3x3 table at the location specified by the myRange variable (myRange is an object variable that contains a Range object).

ActiveDocument.Tables.Add Range:=myRange, NumRows:=3, NumColumns:=3

This following example adds a footnote at the location specified by the variable myRange.

ActiveDocument.Footnotes.Add Range:=myRange, Text:="The Willow Tree"

For a list of collection objects that support the Add method, see "Add Method" in Help.

Working with the Range Object

A common task when using Visual Basic is to specify an area in a document and then do something with it, such as insert text or apply formatting. For example, you may want to write a macro that locates a word or phrase within a portion of a document. You can use a Range object to represent the portion of the document you want to search for the specified word or phrase. After you identify the Range object, you can apply methods and properties of this object to modify the contents of the range.

A Range object represents a contiguous area in a document. Each Range object is defined by a starting character position and an ending character position. Similar to the way you use bookmarks in a document, you use Range objects in Visual Basic procedures to identify specific portions of a document. A Range object can be as small as the insertion point or as large as the entire document. However, unlike a bookmark, a Range object exists only while the procedure that defined it is running.

Range objects are independent of the selection; that is, you can define and modify a range without changing the selection. You can also define multiple ranges in a document, while there is only one selection per document pane.

The Start, End, and StoryType properties uniquely identify a Range object. The Start and End properties return or set the starting and ending character positions of the Range object. The character position at the beginning of each story is 0 (zero), the position after the first character is 1, and so on. There are 11 different story types represented by the WdStoryType constants of the StoryType property. For example, if a Range object is in the footnote area, the StoryType property returns wdFootnotesStory. For more information about stories, see "Working with Stories" later in this section.

Using the Range Object Instead of the Selection Object

The macro recorder will often create a macro that uses the Selection property to manipulate the Selection object. However, you can usually accomplish the same task with fewer instructions by using one or more Range objects. The following example was created using the macro recorder. This macro applies bold formatting to the first two words in the document.

Selection.HomeKey Unit:=wdStory
Selection.MoveRight Unit:=wdWord, Count:=2, Extend:=wdExtend
Selection.Font.Bold = wdToggle

The following example accomplishes the same task without using the Selection object.

ActiveDocument.Range(Start:=0, End:=ActiveDocument.Words(2).End).Bold = True

The following example applies bold formatting to the first two words in the document, and then it inserts a new paragraph.

Selection.HomeKey Unit:=wdStory
Selection.MoveRight Unit:=wdWord, Count:=2, Extend:=wdExtend
Selection.Font.Bold = wdToggle
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.TypeParagraph

The following example accomplishes the same task as the preceding example without using the Selection object.

Set myRange = ActiveDocument.Range(Start:=0, End:=ActiveDocument.Words(2).End)
myRange.Bold = True
myRange.InsertParagraphAfter

Both of the preceding examples change the formatting in the active document without changing the selection. In most cases, Range objects are preferred over the Selection object for the following reasons:

  • You can define and use multiple Range objects, whereas you can only have one Selection object per document window.

  • Manipulating Range objects doesn't change the selected text.

  • Manipulating Range objects is faster than working with the selection.

Using the Range Method to Return a Range Object

You use the Range method to create a Range object in the specified document. The Range method (which is available from the Document object) returns a Range object located in the main story, with a given starting point and ending point. The following example creates a Range object that's assigned to the variable myRange.

Set myRange = ActiveDocument.Range(Start:=0, End:=10)

In the preceding example, myRange represents the first 10 characters in the active document. You can see that the Range object has been created when you apply a property or method to the Range object stored in the myRange variable. The following example applies bold formatting to the first 10 characters in the active document.

Set myRange = ActiveDocument.Range(Start:=0, End:=10)
myRange.Bold = True

When you need to refer to a Range object multiple times, you can use the Set statement to set a variable equal to the Range object. However, if you need to perform only a single action on a Range object, there's no need to store the object in a variable. You can achieve the same results by using just one instruction that identifies the range and changes the Bold property, as in the following example.

ActiveDocument.Range(Start:=0, End:=10).Bold = True

Like a bookmark, a range can span a group of characters or mark a location in a document. In the following example, the starting and ending points of the Range object are the same, and the range doesn't include any text. The example inserts text at the beginning of the active document.

ActiveDocument.Range(Start:=0, End:=0).InsertBefore Text:="Hello "

You can define the beginning and ending points of a range by using the character position numbers as shown in the preceding example, or by using the Start and End properties with the Selection, Bookmark, or Range object. The following example creates a Range object that refers to the third and fourth sentences in the active document.

Set myDoc = ActiveDocument
Set myRange = myDoc.Range(Start:=myDoc.Sentences(3).Start, _
    End:=myDoc.Sentences(4).End)

Tip   A Range object doesn't have a visual representation in a document. You can, however, use the Select method to select a Range object to ensure that the Range object refers to the correct range of text. The Range object in the following example refers to the first three paragraphs in the active document. After this macro has been run, the selection indicates the range of text that was contained in the variable aRange.
Set aRange = ActiveDocument.Range(Start:=0, _
    End:=ActiveDocument.Paragraphs(3).Range.End)
aRange.Select

Using the Range Property to Return a Range Object

The Range property is available from multiple objects — for instance, Paragraph, Bookmark, Endnote, and Cell — and is used to return a Range object. The following example returns a Range object that refers to the first paragraph in the active document.

Set myRange = ActiveDocument.Paragraphs(1).Range

After you've created a reference to a Range object, you can use any of its properties or methods to modify the range. The following example copies the first paragraph in the active document.

Set myRange = ActiveDocument.Paragraphs(1).Range
myRange.Copy

This following example copies the first row in table one in the active document.

ActiveDocument.Tables(1).Rows(1).Range.Copy

The following example displays the text marked by the first bookmark in the active document. The Range property is available from the Bookmark object.

MsgBox ActiveDocument.Bookmarks(1).Range.Text

If you need to apply numerous properties or methods to the same Range object, you can use the With…End With statement. The following example formats the text in the first paragraph in the active document.

Set myRange = ActiveDocument.Paragraphs(1).Range
With myRange
    .Bold = True
    .ParagraphFormat.Alignment = wdAlignParagraphCenter
    .Font.Name = "Arial"
End With

For additional examples of returning Range objects, see "Range Property" in Help.

Modifying a Portion of a Document

Visual Basic includes objects you can use to modify the following types of document elements: characters, words, sentences, paragraphs, and sections. The following table includes the properties that correspond to these document elements and the objects they return.

This expression Returns this object
Words(index) Range
Characters(index) Range
Sentences(index) Range
Paragraphs(index) Paragraph
Sections(index) Section

When you use these properties without an index, a collection with the same name is returned — for example, the Paragraphs property returns the Paragraphs collection. However, if you identify an item within a collection by index, the object in the second column of the preceding table is returned — for example, Words(1) returns a Range object. You can use any of the range properties or methods to modify a Range object, as in the following example, which copies the first word in the selection to the Clipboard.

Selection.Words(1).Copy

The items in the Paragraphs and Sections collections are Paragraph and Section objects, respectively, rather than Range objects. However, the Range property (which returns a Range object) is available from both the Paragraph and Section objects. The following example copies the first paragraph in the active document to the Clipboard.

ActiveDocument.Paragraphs(1).Range.Copy

All the document element properties in the preceding table are available from the Document, Selection, and Range objects, as shown in the following three examples.

This example sets the case of the first word in the active document.

ActiveDocument.Words(1).Case = wdUpperCase

This example sets the bottom margin of the first selected section to 0.5 inch.

Selection.Sections(1).PageSetup.BottomMargin = InchesToPoints(0.5)

This example double­spaces the text in the active document (the Content property returns a Range object that represents the main document story).

ActiveDocument.Content.ParagraphFormat.Space2

Modifying a Group of Document Elements

To modify a range of text that consists of a group of document elements (characters, words, sentences, paragraphs, or sections), you can create a Range object that includes the document elements. Using the Start and End properties with a Range object, you can create a new Range object that refers to a group of document elements. The following example creates a Range object (myRange) that refers to the first three words in the active document and then changes the font for these words to Arial.

Set Doc = ActiveDocument
Set myRange = Doc.Range(Start:=Doc.Words(1).Start, End:=Doc.Words(3).End)
myRange.Font.Name = "Arial"

The following example creates a Range object beginning at the start of the second paragraph and ending after the fourth paragraph.

Set myDoc = ActiveDocument
Set myRange = myDoc.Range(Start:=myDoc.Paragraphs(2).Range.Start, _
	End:=myDoc.Paragraphs(4).Range.End)

The following example creates a Range object (aRange) beginning at the start of the second paragraph and ending after the third paragraph. The ParagraphFormat property is used to access paragraph formatting properties such as SpaceBefore and SpaceAfter.

Set Doc = ActiveDocument
Set aRange = Doc.Range(Start:=Doc.Paragraphs(2).Range.Start, _
	End:=Doc.Paragraphs(3).Range.End)
With aRange.ParagraphFormat
    .Space1
    .SpaceAfter = 6
    .SpaceBefore = 6
End With

Returning or Setting the Text in a Range

Use the Text property to return or set the contents of a Range object. The following example returns the first word in the active document.

strText = ActiveDocument.Words(1).Text

The following example changes the first word in the active document to "Hello."

ActiveDocument.Words(1).Text = "Hello"

Use the InsertAfter or InsertBefore method to insert text before or after a range. The following example inserts text at the beginning of the second paragraph in the active document.

ActiveDocument.Paragraphs(2).Range.InsertBefore Text:="In the beginning "

After you use either the InsertAfter or InsertBefore method, the range expands to include the new text. You can, however, collapse the range to its beginning or ending point by using the Collapse method. The following example inserts the word "Hello" before the existing text and then collapses the range to its beginning (before the word "Hello").

With ActiveDocument.Paragraphs(2).Range
    .InsertBefore Text:="Hello "
    .Collapse Direction:=wdCollapseStart
End With

Formatting the Text in a Range

Use the Font property to get to character­formatting properties and methods, and use the ParagraphFormat property to get to paragraph­formatting properties and methods. The following example sets character and paragraph formatting for the text in the first paragraph in the active document.

With ActiveDocument.Paragraphs(1).Range.Font
    .Name = "Times New Roman"
    .Size = 14
    .AllCaps = True
End With
With ActiveDocument.Paragraphs(1).Range.ParagraphFormat
    .LeftIndent = InchesToPoints(0.5)
    .Space1
End With

Redefining a Range Object

Use the SetRange method to redefine an existing Range object. The following example defines myRange as the current selection. The SetRange method redefines myRange so that it refers to the current selection plus the next 10 characters.

Set myRange = Selection.Range
myRange.SetRange Start:=myRange.Start, End:=myRange.End + 10

For additional information about and examples of redefining a Range object, see "SetRange Method" in Help.

You can also redefine a Range object by changing the values of the Start and End properties, or by using the MoveStart or MoveEnd methods. The following example redefines myRange so that it refers to the current selection plus the next 10 characters.

Set myRange = Selection.Range
myRange.End = myRange.End + 10

The following example uses the MoveEnd method to extend myRange to include the next paragraph.

Set myRange = ActiveDocument.Paragraphs(2)
myRange.MoveEnd Unit:=wdParagraph, Count:=1

Looping Through a Range of Paragraphs

There are several different ways to loop through the paragraphs in a range. This section includes examples of using the For Each...Next statement and the Next property and method to loop through a range of paragraphs. You can use these same techniques to loop through characters, words, or sentences in a range.

Using the For Each...Next Statement

The recommended way to loop through the paragraphs in a range is to use the For Each...Next statement, which is also the recommended way to loop on the elements in a collection. The following example loops through the first five paragraphs in the active document, adding text before each paragraph.

Set myDoc = ActiveDocument
Set myRange = myDoc.Range(Start:=myDoc.Paragraphs(1).Range.Start, _
    End:=myDoc.Paragraphs(5).Range.End)
For Each para In myRange.Paragraphs
    para.Range.InsertBefore "Question:" & vbTab
Next para

Suppose that you want to modify this code to loop through a range of paragraphs that a user selected. You can use the Selection property to refer to the paragraphs in the selection. The following example loops through the paragraphs in the selection, removing bold formatting.

For Each para In Selection.Paragraphs
    para.Range.Bold = False
Next para

Using the Next Property or Method

You can also use the Next property and method to loop through a range of paragraphs. The following example shows how you can loop through a range of words and increase the size of each word by 1 point. The example also uses the Next method to redefine myRange to represent the next word.

Set myRange = ActiveDocument.Words(1)
For i = 1 To 5
    myRange.Font.Size = myRange.Font.Size + i
    Set myRange = myRange.Next(Unit:=wdWord, Count:=1)
Next i

The following example loops through a range of paragraphs and changes the range's alignment from centered to left aligned. The example also uses the Next property to redefine myRange to represent the next paragraph.

Set myRange = ActiveDocument.Paragraphs(1).Range
For i = 1 To 5
    If myRange.Paragraphs(1).Alignment = wdAlignParagraphCenter Then
        myRange.Paragraphs(1).Alignment = wdAlignParagraphLeft
    End If
    Set myRange = myRange.Paragraphs(1).Next.Range
Next i

Assigning Ranges

There are several ways to assign an existing Range object to a variable. In the following examples, the variables Range1 and Range2 refer to Range objects. The instructions in the examples assign the first and second words in the active document to the variables Range1 and Range2, respectively.

Set Range1 = ActiveDocument.Words(1)
Set Range2 = ActiveDocument.Words(2)

Setting a Range Object Variable Equal to Another Range Object Variable

The following example creates the variable Range2 and assigns it to the same range as Range1.

Set Range2 = Range1

You now have two variables that represent the same range. When you manipulate the starting point, the ending point, or the text of Range2, your changes affect Range1 as well, and vice versa.

The following example assigns the value of the default property of Range1 (the Text property) to the default property of Range2. The code in this example is equivalent to Range2.Text = Range1.Text, which doesn't change what the Range objects actually represent; the only thing that's changed is the contents (text) of Range2.

Range2 = Range1

The two ranges (Range2 and Range1) have the same contents as one another, but they may point to different locations in the document, or even to different documents.

Using the Duplicate Property

The following example creates a new, duplicated Range object, Range2, which has the same starting point, ending point, and text as Range1.

Set Range2 = Range1.Duplicate

If you change the starting or ending point of Range1, this change doesn't affect Range2, and vice versa. However, because these two ranges point to the same location in the document, changing the text in one range changes the text in the other range as well.

Working with Stories

A story is a document area that contains a range of text distinct from other areas of text in that document. For example, if a document includes body text, footnotes, and headers, it contains a main text story, a footnotes story, and a headers story. There are 11 different types of stories you can have in a document, corresponding to the following WdStoryType constants: wdCommentsStory, wdEndnotesStory, wdEvenPagesFooterStory, wdEvenPagesHeaderStory, wdFirstPageFooterStory, wdFirstPageHeaderStory, wdFootnotesStory, wdMainTextStory, wdPrimaryFooterStory, wdPrimaryHeaderStory, and wdTextFrameStory.

Use the StoryType property to return the story type for the specified range, selection, or bookmark. The following example closes the footnote pane in the active window if the selection is contained in the footnote story.

ActiveWindow.View.Type = wdNormalView
If Selection.StoryType = wdFootnotesStory Then ActiveWindow.ActivePane.Close

The StoryRanges collection contains the first story range for each story type available in a document. Use the NextStoryRange method to return subsequent stories. The following example searches each story in the active document for the text "Microsoft Word." The example also applies italic formatting to any instances of this text that it finds.

For Each myStoryRange In ActiveDocument.StoryRanges
    myStoryRange.Find.Execute FindText:="Microsoft Word", Forward:=True
    While myStoryRange.Find.Found
        myStoryRange.Italic = True
        myStoryRange.Find.Execute FindText:="Microsoft Word", _
            Forward:=True, Format:=True
    Wend
    While Not (myStoryRange.NextStoryRange Is Nothing)
        Set myStoryRange = myStoryRange.NextStoryRange
        myStoryRange.Find.Execute FindText:="Microsoft Word", Forward:=True
        While myStoryRange.Find.Found
            myStoryRange.Italic = True
            myStoryRange.Find.Execute FindText:="Microsoft Word", _
                Forward:=True, Format:=True
        Wend
    Wend
Next myStoryRange

Working with the Selection Object

When you work on a document in Word, you usually select text and then perform an action, such as formatting existing text or typing new text. In Visual Basic, it's usually not necessary to select text before modifying it; instead, you create and manipulate a Range object that refers to a specific portion of the document. However, when you want your code to respond to or change the selection, you can do so with the Selection object.

Use the Selection property to return the Selection object. There can only be one Selection object per pane in a document window, and only one Selection object can be active at any given time. The selection can either encompass an area in the document or be collapsed to an insertion point. The following example changes the paragraph formatting of the paragraphs in the selection.

Selection.Paragraphs.SpaceBefore = InchesToPoints(0.25)

The Selection property is available from the Application, Window, and Pane objects. If you use the Selection property with the Application object, the Selection object refers to the active selection. The following example inserts text after the selection (because Selection is a global property, the Application property isn't included).

Selection.InsertAfter Text:="Next Text"

You can also use the Selection property with a Window or Pane object to return a Selection object in a particular window or window pane. The following example uses the Selection property with a Window object to insert text into the document window named "Document2."

Windows("Document2").Selection.InsertAfter Text:="New Text"

The following example uses the Selection property with a Pane object to insert text into the primary header pane.

With ActiveWindow
    .View.Type = wdPageView
    .View.SeekView = wdSeekPrimaryHeader
    .ActivePane.Selection.InsertAfter Text:="Header"
End With

After you use the InsertAfter or InsertBefore method, the selection expands to include the new text. You can, however, collapse the selection to its beginning or ending point by using the Collapse method. The following example inserts the word "Hello" after the text in the selection and then collapses the selection to an insertion point after the word "Hello."

Selection.InsertAfter Text:="Hello"
Selection.Collapse Direction:=wdCollapseEnd

Moving and Extending the Selection

There are a number of methods you can use to move or extend the selection represented by the Selection object (for instance, Move and MoveEnd). The following example moves the selection to the beginning of the next paragraph.

Selection.MoveDown Unit:=wdParagraph, Count:=1, Extend:=wdMove

You can also move or extend the selection by changing the values of the Start and End properties of the Selection object or by using the MoveStart and MoveEnd methods. The following example extends the selection by moving the ending position to the end of the paragraph.

Selection.MoveEnd Unit:=wdParagraph, Count:=1

Because there can be only one selection in a document window or pane, you can also move the selection by selecting another object. Use the Select method to select an item in a document. After using the Select method, you can use the Selection property to return a Selection object. The following example selects the first word in the active document and then changes the word to "Hello."

ActiveDocument.Words(1).Select
Selection.Text = "Hello "

You can also move the selection by using the GoToNext, GoToPrevious, or GoTo method. The following example moves the selection to the fourth line in the document.

Selection.GoTo What:=wdGoToLine, Which:=wdGoToAbsolute, Count:=4

The following example moves the selection just before the next field in the active document.

Selection.GoToNext What:=wdGoToField

Objects Available from the Selection Object

Many of the objects available from the Range and Document objects are also available from the Selection object, making it possible for you to manipulate the objects within a selection. For a complete list of the objects available from the Selection object, see "Microsoft Word Objects (Selection)" or "Selection Object" in Help.

The following example updates the results of the fields in the selection.

If Selection.Fields.Count >= 1 Then Selection.Fields.Update

The following example indents the paragraphs in the selection by 0.5 inch.

Selection.Paragraphs.LeftIndent = InchesToPoints(0.5)

Instead of manipulating all the objects in the collection, you can use For Each...Next to loop through the individual objects in the selection. The following example loops through each paragraph in the selection and left aligns any paragraphs it finds that are centered.

For Each para In Selection.Paragraphs
   If para.Alignment = wdAlignParagraphCenter Then para.Alignment = _
	wdAlignParagraphLeft
Next para

The following example displays the name of each bookmark in the selection.

For Each aBook In Selection.Bookmarks
   MsgBox aBook.Name
Next aBook

Properties and Methods of the Selection Object

This section highlights some of the commonly used properties and methods of the Selection object.

Returning or Setting the Text in the Selection

Use the Text property to return or set the contents of a Selection object. The following example returns the selected text.

strText = Selection.Text

The following example changes the selected text to "Hello World."

Selection.Text = "Hello World"

Use the InsertBefore or InsertAfter method to insert text before or after the selection. The following example inserts text at the beginning of the selection.

Selection.InsertBefore Text:="And furthermore "

Formatting the Selected Text

Use the Font property to gain access to character­formatting properties and methods, and use the ParagraphFormat property to gain access to paragraph­formatting properties and methods. The following example sets character and paragraph formatting for the selection.

With Selection.Font
    .Name = "Times New Roman"
    .Size = 14
End With
Selection.ParagraphFormat.LeftIndent = InchesToPoints(0.5)

Returning a Range Object

If a method or property is available from the Range object but not from the Selection object (the CheckSpelling method, for example), use the Range property to return a Range object from the Selection object. The following example checks the spelling of the selected words.

Selection.Range.CheckSpelling

Returning Information About the Selection

Use the Information property to return information about the selection. For example, you can determine the current page number, the total number of pages in a document, or whether or not the selection is in a header or footer. The Information property accepts 35 different constants (wdActiveEndPageNumber, wdNumberOfPagesInDocument, and wdInHeaderFooter, to name just a few) that you can use to return different types of information about the selection. If the selection is in a table, for instance, the following example displays the number or rows and columns in the table.

If Selection.Information(wdWithInTable) = True Then
    MsgBox "Columns = " & Selection.Information(wdMaximumNumberOfColumns) _
        & vbCr & "Rows = " & Selection.Information(wdMaximumNumberOfRows)
End If

For a complete list and description of the constants you can use with the Information property, see "Information Property" in Help.

Determining Whether Text Is Selected

Use the Type property to set or return the way you want the selection to be indicated in your document. For instance, you can use the wdSelectionBlock constant to determine whether a block of text is selected. The following example selects the paragraph that contains the insertion point if the selection is an insertion point.

If Selection.Type = wdSelectionIP Then
    Selection.Paragraphs(1).Range.Select
End If

Working with the Find and Replacement Objects

Use the Find and Replacement objects to find and replace specified ranges of text in your documents. The Find object is available from either the Selection or Range object (the find action differs slightly depending on whether you return the Find object from the Selection object or the Range object).

Using Selection.Find

If you return the Find object from the Selection object, the selection is changed when the find criteria are found. The following example selects the next occurrence of the word "Hello." If the end of the document is reached before the word "Hello" is found, the search is stopped.

With Selection.Find
    .Forward = True
    .Wrap = wdFindStop
    .Text = "Hello"
    .Execute
End With

The Find object includes properties that relate to the options in the Find and Replace dialog box (Edit menu). You can set the individual properties of the Find object, or you can use arguments with the Execute method, as shown in the following example.

Selection.Find.Execute FindText:="Hello", Forward:=True, Wrap:=wdFindStop

Using Range.Find

If you return the Find object from a Range object, the selection isn't changed but the range is redefined when the find criteria are found. The following example locates the first occurrence of the word "blue" in the active document. If the find operation is successful, the range is redefined and bold formatting is applied to the word "blue."

With ActiveDocument.Content.Find
    .Text = "blue"
    .Forward = True
    .Execute
    If .Found = True Then .Parent.Bold = True
End With

The following example performs the same action as the preceding example, using arguments of the Execute method.

Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:="blue", Forward:=True
If myRange.Find.Found = True Then myRange.Bold = True

Using the Replacement Object

The Replacement object represents the replace criteria for a find and replace operation. The properties and methods of the Replacement object correspond to the options in the Find and Replace dialog box (Edit menu).

The Replacement object is available from the Find object. The following example replaces all occurrences of the word "hi" with "hello." The selection changes when the find criteria are found because the code returns the Find object from the Selection object.

With Selection.Find
    .ClearFormatting
    .Text = "hi"
    .Replacement.ClearFormatting
    .Replacement.Text = "hello"
    .Execute Replace:=wdReplaceAll, Forward:=True, Wrap:=wdFindContinue
End With

The following example removes all bold formatting in the active document. The Bold property is True for the Find object and False for the Replacement object. To find and replace formatting, set the find and replace text to empty strings (""), and set the Format argument of the Execute method to True. The selection remains unchanged because the code returns the Find object from a Range object (the Content property returns a Range object).

With ActiveDocument.Content.Find
    .ClearFormatting
    .Font.Bold = True
    With .Replacement
        .ClearFormatting
        .Font.Bold = False
    End With
    .Execute FindText:="", ReplaceWith:="", Format:=True, Replace:=wdReplaceAll
End With

Working with Table, Column, Row, and Cell Objects

The Word object model includes an object for tables as well as objects for the various elements of a table. Use the Tables property with the Document, Range, or Selection object to return the Tables collection. Use Tables(index), where index is the table's index number, to return a single Table object. The index number represents the position of the table in the selection, range, or document. The following example converts the first table in the selection to text.

If Selection.Tables.Count >= 1 Then
    Selection.Tables(1).ConvertToText Separator:=wdSeparateByTabs
End If

Use the Cells property with the Column, Range, Row, or Selection object to return the Cells collection. You can get an individual Cell object by using the Cell method of the Table object or by indexing the Cells collection. The following two statements both set myCell to a Cell object that represents the first cell in table one in the active document.

Set myCell = ActiveDocument.Tables(1).Cell(Row:=1, Column:=1)
Set myCell = ActiveDocument.Tables(1).Columns(1).Cells(1)

Note   To insert text into a cell in a table, use the Text property, the InsertAfter method, or the InsertBefore method with a Range object. Use the Range property with a Cell object to return a Range object. The following example inserts a sequential cell number into each cell in table one.

i = 1
For Each c In ActiveDocument.Tables(1).Range.Cells
    c.Range.InsertBefore Text:="Cell " & i
    i = i + 1
Next c

Use the Columns property with the Table, Range, or Selection object to return the Columns collection. Use Columns(index), where index is the index number, to return a single Column object. The following example selects the first column in table one.

ActiveDocument.Tables(1).Columns(1).Select

Use the Rows property with the Table, Range, or Selection object to return the Rows collection. Use Rows(index), where index is the index number, to return a single Row object. The following example applies shading to the first row in table one.

ActiveDocument.Tables(1).Rows(1).Shading.Texture = wdTexture10Percent

Modifying Rows and Columns in Drawn Tables

When you try to work with an individual row or column in a drawn table (or any table where two or more adjacent cells have been merged, leaving the rows and columns not uniform), a run­time error may occur. The following example generates an error if the first table in the active document doesn't have the same number of rows in each column.

ActiveDocument.Tables(1).Rows(1).Borders.Enable = False

You can avoid this error by first using the SelectColumn or SelectRow method to select the cells in a particular column or row. After you've selected the column or row you want, use the Cells property with the Selection object. The following example selects the first row in table one in the active document. The example uses the Cells property to return the selected cells (all the cells in the first row) so that borders can be removed.

If ActiveDocument.Tables(1).Uniform = False
    ActiveDocument.Tables(1).Cell(1, 1).Select
    With Selection
        .SelectRow
        .Cells.Borders.Enable = False
    End With
End If

The following example selects the first column in table one. The example uses a For Each...Next loop to add text to each cell in the selection (all the cells in the first column).

If ActiveDocument.Tables(1).Uniform = False
    ActiveDocument.Tables(1).Cell(1, 1).Select
    Selection.SelectColumn
    i = 1
    For Each oCell In Selection.Cells
        oCell.Range.Text = "Cell " & i
        i = i + 1
    Next oCell
End If

Working with Other Common Objects

This section provides information and tips about working the some common Word objects.

Using the HeaderFooter Object

The HeaderFooter object can represent either a header or a footer. The HeaderFooter object is a member of the HeadersFooters collection, which is available from the Section object. Use the Headers(index) or Footers(index) property, where index is one of the WdHeaderFooterIndex constants, to return a single HeaderFooter object.

The following example creates a Range object (oRange) that references the primary footer for section one in the active document. After the example sets the Range object, it deletes the existing footer text. It also adds the AUTHOR field to the footer, along with two tabs and the FILENAME field.

Set oRange = ActiveDocument.Sections(1).Footers(wdHeaderFooterPrimary).Range
With oRange
    .Delete
    .Fields.Add Range:=oRange, Type:=wdFieldFileName, Text:="\p"
    .InsertAfter Text:=vbTab
    .InsertAfter Text:=vbTab
    .Collapse Direction:=wdCollapseStart
    .Fields.Add Range:=oRange, Type:=wdFieldAuthor
End With

Note   The PageNumbers collection is available only from a HeaderFooter object. Apply the Add method to the PageNumbers collection to add page numbers to a header or footer.

Using the Styles Collection

The Styles collection is available from the Document object. The following example changes the formatting of the Heading 1 style in the active document.

ActiveDocument.Styles(wdStyleHeading1).Font.Name = "Arial"

The Styles collection isn't available from the Template object. If you want to modify styles in a template, use the OpenAsDocument method to open a template as a document so that you can modify styles. The following example changes the formatting of the Heading 1 style in the template attached to the active document.

Set aDoc = ActiveDocument.AttachedTemplate.OpenAsDocument
With aDoc
    .Styles(wdStyleHeading1).Font.Name = "Arial"
    .Close SaveChanges:=wdSaveChanges
End With

Specifying the CommandBars Context

Before using the CommandBars collection (which represents menus and toolbars), use the CustomizationContext property to set the Template or Document object in which changes to menus and toolbars are stored. The following example adds the Double Underline command to the Formatting toolbar. Because the customization change is stored in the Normal template, all documents are affected.

CustomizationContext = NormalTemplate
CommandBars("Formatting").Controls.Add Type:=msoControlButton, _
    ID:=60, Before:=7

For more information about the scope of changes to menus and toolbars, see Chapter 8, "Menus and Toolbars."

Using the Dialogs Collection

Use the Dialogs property to return the Dialogs collection, which represents the built­in Word dialog boxes (for example, the Open and File Save dialog boxes). You cannot create a new built­in dialog box or add one to the Dialogs collection. For information about creating custom dialog boxes with ActiveX controls, see Chapter 12, "ActiveX Controls and Dialog Boxes."

Returning the MailMerge and Envelope Objects

Use the MailMerge property of the Document object to return a MailMerge object. The MailMerge object is available regardless of whether or not the specified document is a mail­merge document. Use the State property to determine the state of the mail­merge operation before you execute the merge by using the Execute method. The following example executes a mail merge if the active document is a main document with an attached data source.

Set myMerge = ActiveDocument.MailMerge
If myMerge.State = wdMainAndDataSource Then myMerge.Execute

Use the Envelope property of the Document object to return an Envelope object. The Envelope object is available regardless of whether or not you've added an envelope to the specified document. However, an error occurs if you use one of the following properties and you haven't added an envelope to the document: Address, AddressFromLeft, AddressFromTop, FeedSource, ReturnAddress, ReturnAddressFromLeft, ReturnAddressFromTop, or UpdateDocument.

The following example uses the On Error GoTo statement to trap the error that occurs if you haven't added an envelope to the active document. If, however, you've added an envelope to the document, the recipient address is displayed.

On Error GoTo ErrorHandler
MsgBox ActiveDocument.Envelope.Address
ErrorHandler:
If Err = 5852 Then MsgBox "Envelope is not in the specified document"

Adding and Editing Fields in a Document

You can add fields to a document by applying the Add method to the Fields collection. The following example adds a DATE field in place of the selection.

ActiveDocument.Fields.Add Range:=Selection.Range, Type:=wdFieldDate

After you've added a field, you can return or set the field result and field code by using the Result or Code property, either of which returns a Range object. The following example changes the first field code in the selection, updates the field, and then displays the field result.

If Selection.Fields.Count >= 1 Then
    With Selection.Fields(1)
        .Code.Text = "CREATEDATE \*MERGEFORMAT"
        .Update
        MsgBox .Result.Text
    End With
End If

InlineShape Objects vs. Shape Objects

A Shape object represents an object in the drawing layer, such as an AutoShape, freeform, OLE object, ActiveX control, or picture. Shape objects are anchored to a range of text but are free­floating in that you can positioned them anywhere on the page. For information about working with Shape objects, see Chapter 10, "Shapes and the Drawing Layer," and see "Shape Object" in Help.

An InlineShape object represents an object in the text layer of a document. An inline shape can be a picture, an OLE object, or an ActiveX control. InlineShape objects are treated like characters and are positioned as characters within a line of text. For information about InlineShape objects, see "InlineShapes Collection Object" or "InlineShape Object" in Help.

Using FormField Objects in Word Forms

You can create an Word online form that includes check boxes, text boxes, and drop­down list boxes. These form elements can be inserted using the Forms toolbar. The corresponding Visual Basic objects are CheckBox, TextInput, and DropDown. All these objects can be returned from any FormField object in the FormFields collection; however, you should return the object that corresponds to the type of the form field. For example, the following instruction selects the check box form field named "Check1" in the active document.

ActiveDocument.FormFields("Check1").CheckBox.Value = True

In addition to the form elements available on the Forms toolbar, you can add ActiveX controls to an online form. ActiveX controls can be inserted using the Control Toolbox. You can insert a control into the text layer or into the drawing layer; the control will be represented by an InlineShape object or a Shape object, respectively. For more information about working with ActiveX controls, see Chapter 12, "ActiveX Controls and Dialog Boxes."

Determining Whether an Object Is Valid

You can avoid many run­time errors in your code by including statements that determine whether a particular object returned by an expression or an object referenced by a variable is valid. This section discusses some techniques for checking the validity of a value returned by an expression or stored in a variable.

You can use the TypeName function with a variable or expression to determine the object type. The following example displays a message in the status bar if Selection.NextField returns a Field object.

If TypeName(Selection.NextField) = "Field" Then StatusBar = "A field was found"

The following example is functionally equivalent to the preceding example; it's different only in that it uses an object variable (myField) to store the return value of the NextField method.

Set myField = Selection.NextField
If TypeName(myField) = "Field" Then StatusBar = "A field was found"

If the specified variable or expression doesn't refer to an object, it evaluates to Nothing. The following example applies the Update method to myField if the NextField method doesn't return Nothing (that is, if the NextField method returns a Field object, its only other possible return value).

Set myField = Selection.NextField
If Not (myField Is Nothing) Then myField.Update

Word includes the global IsObjectValid property. You can use this property to determine whether an object referenced by a particular variable is valid. This property returns False if the object referenced by the variable has been deleted. The following example adds a table to the active document and assigns it to the variable aTable. The example deletes the first table from the document. If the table that aTable refers to wasn't the first table in the document (that is, if aTable is still a valid object), the example removes borders from the table.

Set aTable = ActiveDocument.Tables.Add(Range:=Selection.Range, NumRows:=2, _
	NumColumns:=3)
ActiveDocument.Tables(1).Delete
If IsObjectValid(aTable) = True Then aTable.Borders.Enable = False

Modifying Word Commands

You can modify most Word commands by turning them into macros. For example, you can modify the Open command on the File menu so that instead of displaying a list of Word document files (in Windows, files ending with the .doc file name extension), Word displays every file in the current folder.

To display the list of built­in Word commands in the Macro dialog box (Tools menu), click Word commands in the Macros in box. Every available menu, toolbar, and shortcut key command is listed in this box. Each menu command begins with the menu name associated with that command. For example, the Save command on the File menu is listed as FileSave.

You can replace a Word command with a macro by giving a macro the same name as the Word command. For example, if you create a macro named "FileSave," Word runs this macro when you do any of the following: click Save on the File menu, click the Save button on the Standard toolbar, or press the shortcut key assigned to FileSave.

To modify a Word command

  1. On the Tools menu, point to Macro, and then click Macros.

  2. In the Macros in box, click Word Commands.

  3. In the Macro name box, click the Word command you want to modify (for example, FileSave).

  4. In the Macros in box, select a template or document location where you want to store the macro. For example, click Normal.dot (global template) to create a global macro (the FileSave command will be automatically modified for all documents).

  5. Click Create.

The Visual Basic Editor opens with a module displayed that contains a new procedure whose name is the same as the command you clicked. If you clicked the FileSave command, the FileSave macro appears as shown in the following example.

Sub FileSave()
'
' FileSave Macro
' Saves the active document or template
'
    ActiveDocument.Save

End Sub

You can add additional instructions or remove the existing ActiveDocument.Save instruction. Every time the FileSave command runs, your FileSave macro runs instead of the Word command. To restore the original FileSave command, you need to rename or delete your FileSave macro.

Note   You can also replace a Word command by creating a code module whose name is the same as the Word command (for example, FileSave) with a subroutine named "Main."

Working with Events

An event is an action that's recognized by an object (such as opening a document or quitting the application) and for which you can write code to respond. Events can occur as a result of either a user action or program code, or they can be triggered by the system. Word supports the events listed in the following tables, as well as the ActiveX control events discussed in Chapter 12, "ActiveX Controls and Dialog Boxes."

For more information about working with Word events, see the following Help topics: "Using Events with the Document Object," "Using Events with ActiveX Controls," and "Using Events with the Application Object."

Document Events

Document events occur when the user opens or closes an existing document or creates a new document, as shown in the following table.

Event Description
Close Occurs when a document is closed.
New Occurs when a new document based on the template is created.
Open Occurs when a document is opened.

The scope of a document event procedure depends on where it is stored. If you store a Open or Close event procedure in a document, the procedure will run only when the user closes or opens that document; if you store a Open or Close event procedure in a template, the procedure will run when a document based on the template or the template itself is opened or closed. A New event procedure must be stored in a template; a New event procedure stored in a document will never run, because new documents can only be based on templates.

The following example maximizes the Word application window when the document is opened.

Private Sub Document_Open()
    Application.WindowState = wdWindowStateMaximize
End Sub

ActiveX Control Events

Word implements the LostFocus and GotFocus events for ActiveX controls in a Word document.

Event Description
LostFocus Occurs when the focus is moved from an embedded ActiveX control.
GotFocus Occurs when the focus is moved to an embedded ActiveX control.

The following example leaves CommandButton1 disabled until the user enters a value in TextBox1.

Private Sub TextBox1_LostFocus()
    If TextBox1.Value = "" Then
        CommandButton1.Enabled = False
    Else
        CommandButton1.Enabled = True
    End If
End Sub

Additional ActiveX control events are documented in Microsoft Forms Help. For information about using ActiveX controls in custom dialog boxes and documents, see Chapter 12, "ActiveX Controls and Dialog Boxes."

Application Events

Application events occur when the user quits the application or the focus is shifted to another document. However, unlike document and ActiveX control events, the Application object doesn't have events enabled by default. Before you can use events with the Application object, you must create a new class module and declare an object of type Application with events. You use the Class Module command (Insert menu) in the Visual Basic Editor to create a new class module.

To enable the events of the Application object, you'd add the following declaration to the class module.

Public WithEvents App As Application

After the new object has been declared with events, it appears in the Object box in the class module, and you can write event procedures for the new object. (When you select the new object in the Object box, the valid events for that object are listed in the Procedure box.)

Before the procedures will run, however, you must connect the declared object in the class module to the Application object. You can do this from any module by using the following declaration (where "EventClass" is the name of the class module you created to enable events).

Public X As New EventClass

After you've created the X object variable (an instance of the EventClass class), you can set the App object of the EventClass class equal to the Word Application object.

Sub InitializeApp()
	Set X.App = Application
End Sub

After you run the InitializeApp procedure, the App object in the EventClass class module points to the Word Application object, and the event procedures in the class module will run whenever the events occur.

After you've enabled events for the Application object, you can create event procedures for the events described in the following table.

Event Description
DocumentChange Occurs when a new document is created, when an existing document is opened, or when another document is made the active document.
Quit Occurs when the user quits Word.

The following example ensures that the Standard and Formatting toolbars are visible before the user quits Word. As a result, when Word is started again, these toolbars won't be visible.

Private Sub App_Quit()
    CommandBars("Standard").Visible = True
    CommandBars("Formatting").Visible = True
End Sub

Using Auto Macros

By giving a macro a special name, you can run it automatically when you perform an operation such as starting Word or opening a document. Word recognizes the following names as automatic macros, or "auto" macros.

Macro name When it runs
AutoExec Each time you start Word or load a global template
AutoNew Each time you create a new document
AutoOpen Each time you open an existing document
AutoClose Each time you close a document
AutoExit Each time you quit Word or unload a global template

For more information about using auto macros, see "Auto Macros" in Help.

Using Automation

In addition to working with Word data, you may want your application to exchange data with other applications, such as Microsoft Excel, Microsoft PowerPoint, or Microsoft Access. You can communicate with other applications by using Automation (formerly OLE Automation).

Automating Word from Another Application

Automation allows you to return, edit, and export data by referencing another application's objects, properties, and methods. Application objects that you can reference in another application are called Automation objects. The first step toward making Word available to another application for Automation is to create a reference to the Word type library. To create a reference to the Word type library, click References on the Tools menu in the Visual Basic Editor, and then select the check box next to Microsoft Word 8.0 Object Library.

Next, declare an object variable that will refer to the Word Application object, as in the following example.

Dim appWD As Word.Application.8

Use the Visual Basic CreateObject or GetObject function with the Word OLE Programmatic Identifier (Word.Application.8 or Word.Document.8), as shown in the following example. If you want to see the Word session, set the Visible property to True.

Dim appWD As Word.Application.8

Set appWD = CreateObject("Word.Application.8")
appWd.Visible = True

The CreateObject function returns a Word Application object and assigns it to appWD. Using the objects, properties, and methods of the Word Application object, you can control Word through this variable. The following example creates a new Word document.

appWd.Documents.Add

The CreateObject function starts a Word session that Automation won't close when the object variable that references the Application object expires. Setting the object reference to the Nothing keyword won't close Word either. Instead, use the Quit method to close Word. The following Microsoft Excel example inserts data from cells A1:B10 on Sheet1 into a new Word document and then arranges the data in a table. The example uses the Quit method to close the new instance of Word if the CreateObject function was used. If the GetObject function returns error 429, the example uses the CreateObject function to start a new session of Word.

Dim appWD As Word.Application
Err.Number = 0
On Error GoTo notloaded
Set appWD = GetObject(, "Word.Application.8")
notloaded:
If Err.Number = 429 Then
    Set appWD = CreateObject("Word.Application.8")
    theError = Err.Number
End If
appWD.Visible = True

With appWD
    Set myDoc = .Documents.Add
    With .Selection
        For Each c In Worksheets("Sheet1").Range("A1:B10")
            .InsertAfter Text:=c.Value
            Count = Count + 1
            If Count Mod 2 = 0 Then
                .InsertAfter Text:=vbCr
            Else
                .InsertAfter Text:=vbTab
            End If
        Next c
        .Range.ConvertToTable Separator:=wdSeparateByTabs
        .Tables(1).AutoFormat Format:=wdTableFormatClassic1
    End With
    myDoc.SaveAs FileName:="C:\Temp.doc"
End With
If theError = 429 Then appWD.Quit
Set appWD = Nothing

Automating Another Application from Word

To exchange data with another application by using Automation from Word, you must first set a reference to the other application's type library in the References dialog box (Tools menu). After you've done this, the other application's objects, properties, and methods will show up in the Object Browser and the syntax will be automatically checked at compile time. You can also get context­sensitive Help on these objects, properties, and methods.

Next, declare object variables that will refer to the objects in the other application as specific types. The following example declares a variable that will point to the Microsoft Excel Application object.

Dim xlObj As Excel.Application.8

You obtain a reference to the Automation object by using the CreateObject or GetObject function. Then, using the objects, properties, and methods of the other application, you add, change, or delete information. When you finish making your changes, close the application. The following Word example determines whether Microsoft Excel is currently running. If the specified Microsoft Excel task exists, the example uses the GetObject function; otherwise, it uses the CreateObject function. The example then sends the selected text to cell A1 on Sheet1 in the active Microsoft Excel workbook. Use the Set statement with the Nothing keyword to clear the Automation object variable after the task has been completed.

Dim xlObj As Excel.Application.8
If Tasks.Exists("Microsoft Excel") = True Then
    Set xlObj = GetObject(, "Excel.Application.8")
Else
    Set xlObj = CreateObject("Excel.Application.8")
End If
xlObj.Visible = True
If xlobj.Workbooks.Count = 0 Then xlobj.Workbooks.Add
xlObj.Worksheets("Sheet1").Range("A1").Value = Selection.Text
Set xlObj = Nothing

The following Word example determines whether PowerPoint is currently running. If the PowerPoint task exists, the example uses the GetObject function; otherwise, it uses the CreateObject function. The example then creates a new presentation, with the first text box including the name of the active Word document and the second text box including the text from the first paragraph in the active document. Use the Set statement with the Nothing keyword to clear the automation object variable after the task has been completed.

Dim pptObj As PowerPoint.Application.8
If Tasks.Exists("Microsoft PowerPoint") = True Then
    Set pptObj = GetObject(, "PowerPoint.Application.8")
Else
    Set pptObj = CreateObject("PowerPoint.Application.8")
End If
pptObj.Visible = True
Set pptPres = pptObj.presentations.Add
Set aSlide = pptPres.Slides.Add(Index:=1, Layout:=ppLayoutText)
aSlide.Shapes(1).TextFrame.TextRange.Text = ActiveDocument.Name
aSlide.Shapes(2).TextFrame.TextRange.Text = ActiveDocument.Paragraphs(1).Range.Text
Set pptObj = Nothing

For information about automating Microsoft Access, see Chapter 3, "Microsoft Access Objects." For information about using Data Access Objects (DAO) from Word, see Chapter 11, "Data Access Objects," and see "Using DAO from Microsoft Word" in Help.

Communicating with Embedded Word Objects

You can use the Application property of any Word object to return the Word Application object. This is useful for returning the Word Application object from a Word document embedded in another application. The following example, run from Microsoft Excel, sets an object variable to the Word Application object. (For this example to work, shape one on the active worksheet must be an embedded Word document.) The final instruction in the example adds text at the beginning of the embedded Word document.

Dim appWRD As Word.Application
Set embeddedDoc = ActiveSheet.Shapes(1)
Set appWRD = embeddedDoc.OLEFormat.Object.Object.Application
appWRD.ActiveDocument.Range(Start:=0, End:=0).InsertBefore Text:="New text "

The following example, run from PowerPoint, sets an object variable to the Word Application object. (For this example to work, shape one on slide one in the presentation must be an embedded Word document.) The final instruction in the example displays the text in the embedded Word document.

Dim appWRD As Word.Application
Set embeddedDoc = Presentations(1).Slides(1).Shapes(1)
embeddedDoc.OLEFormat.Activate
Set appWRD = embeddedDoc.OLEFormat.Object.Application
MsgBox appWRD.ActiveDocument.Content.Text