In Word, the Document object appears directly below the Application object in the object hierarchy. As you'll see in the sections that follow, you can use VBA to create new documents, open or delete existing documents, save and close open documents, and much more. Specifying a Document Object If you need to do something with a document, or if you need to work with an object contained in a specific document (such as a section of text), you need to tell Word which document to use. VBA gives you three ways to do this: Use the Documents object The Documents object is the collection of all open document files. To specify a particular document, either use its index number (where 1 represents the first document opened) or enclose the document name in quotation marks. For example, if Memo.doc was the first document opened, the following two statements would be equivalent: Documents("Memo.doc") Documents(1) Use the ActiveDocument object The ActiveDocument object represents the document that currently has the focus. Use the ThisDocument object The ThisDocument object represents the document where the VBA code is executing. If your code deals only with objects residing in the same document as the code itself, you can use the ActiveDocument object. However, if your code deals with other documents, use ThisDocument whenever you need to make sure that the code affects only the document containing the procedure. Opening a Document To open a document file, use the Open method of the Documents collection. The Open method has a dozen arguments you can use to fine-tune your document openings, but only one of these is mandatory. Here's the simplified syntax showing the one required argument (for the rest of the arguments, look up the Open method in the VBA Help system): Documents.Open( FileName ) FileName | The name of the document file, including the drive and folder that contain the file. | For example, to open a document named Letter.doc in the C:\My Documents folder, you would use the following statement: Documents.Open "C:\My Documents\Letter.doc" tip | The maximum value of Index is given by the RecentFiles.Maximum property. Note, too, that you can set this property. For example, the following statement sets the maximum value to 9 (the highest Word allows for this value): RecentFiles.Maximum = 9 | The RecentFiles Object Another way to open Word documents is to use the RecentFiles object, which is the collection of the most recently-used files displayed near the bottom of Word's File menu. Each item on this list is a RecentFile object. You specify a RecentFile object by using RecentFiles( Index ) , where Index is an integer that specifies the file you want to work with. The most-recently used file is 1, the second most recently-used file is 2, and so on. Here are some RecentFile object properties to consider: RecentFile .Name Returns the filename of the specified RecentFile . RecentFile . Path Returns the pathname of the specified RecentFile . Here's some code that tells Word to open the most-recently used file: With RecentFiles(1) Documents.Open .Path & "\" & .Name End With It would be handy to have Word open the most recently used file each time you start the program. If you want Word to run some code each time it's started, follow these steps: -
Open the Normal project in the VBA Editor's Project Explorer. -
Create a new module and rename it AutoExec . -
In this module, create a Sub procedure named Main. -
Enter your code in that procedure. Listing 7.1 shows a sample Main procedure that opens the most-recently used file at startup. Listing 7.1. A Procedure to Open the Most-Recently Used Document at Startup Sub Main() With RecentFiles(1) Documents.Open .Path & "\" & .Name End With End Sub | The code used in this chapter's listings can be found on my Web site at the following address: http://www.mcfedries.com/ABGVBA/Chapter07.doc | Creating a New Document If you need to create a new document, use the Documents collection's Add method: Documents.Add( Template, NewTemplate, DocumentType, Visible ) Template | This optional argument specifies the template file to use as the basis for the new document. Enter a string that spells out the path and name of the .DOT file. If you omit this argument, Word creates the new document based on the Normal template. | NewTemplate | If you set this optional argument to True, Word creates a new template file. | DocumentType | This optional argument determines the type of document that's created. Use one of the following constants: | | wdNewBlankDocument | Creates a new, blank Word document (this is the default). | | wdNewEmailMessage | Creates a new email message. | | wdNewFrameset | Creates a new Web frameset page. | | wdNewWebPage | Creates a new Web page. | | wdNewXMLDocument | Creates a new XML document. | Visible | This is an optional Boolean value that determines whether Word displays the new document in a visible window. True is the default; use False to create the document without displaying it in a visible window. | Since all of the Add method's arguments are optional, you can create a basic Word document based on the Normal template with the following simple statement: Documents.Add | After you create a new document, it automatically becomes the active document in the Word window, so you can use the ActiveDocument property to work with the new document (for example, to save it, as discussed in the next section). | Saving a Document The worst nightmare of any Word user is a power failure or glitch that shuts down Word or even the computer itself while you have one or more documents open with unsaved changes. I know people who have lost hours of work when this has happened . We tell ourselves to save more often, but it's easy to forget in the heat of battle. Even Word's AutoRecover feature doesn't always work as advertised, so it can't be relied upon. Using the Save Method Fortunately, VBA proves very useful in solving this problem because it's easy to set up a procedure that takes the guesswork out of saving. Before we get to that, however, let's look at a few fundamental properties and methods of Document objects. First up is the Save method: Document .Save Document | This is a reference to the document you want to save. | For example, the following statement saves the active document: ActiveDocument.Save If you're dealing with a large document, you might not want to save it unnecessarily since the Save operation may take a while. You can avoid that by first checking the document's Saved property. If this returns False, it means the document has unsaved changes. Here's an example: If ActiveDocument.Saved = False Then ActiveDocument.Save End If The Save method will fail if the document is a new one that has never been saved before. How can you tell? There are two ways: -
If you've just created the document using the Add method. -
Check the document's Path property. For a document that has been saved, Path returns the drive and folder in which the document is stored. (Note that the string returned by the Path property does not have a trailing backslash; for example, "C:\My Documents".) However, if the document has never been saved, the Path property returns an empty string (""). Here's a bit of code that checks the Path property before trying to save the active document: If ActiveDocument.Path <> "" Then ActiveDocument.Save End If Listing 7.2 presents a procedure named SafeSave that combines these two checks so that it avoids saving new or unchanged documents. Listing 7.2. A Procedure that Avoids Saving New or Unchanged Documents Sub SafeSave() With ActiveDocument If .Path <> "" And .Saved = False Then .Save End If End With End Sub Using the SaveAs Method If the document is new, use the SaveAs method instead. Document .SaveAs( FileName, FileFormat ) Document | The Document object you want to save to a different file. | FileName | (optional) The full name of the new document file, including the drive and folder where you want the file to reside. If you don't specify this value, Word uses the current folder and a default named (such as Doc1.doc). | FileFormat | (optional) The file format to which the document should be saved. You can either use a predefined wdSaveFormat constant or an integer that specifies the format ( wdWordDocument is the default): | File Format | Constant | IntegerValue | Word Document | wdFormatDocument | | Document Template | wdFormatTemplate | 1 | Text Only | wdFormatText | 2 | Text Only with Line Breaks | wdFormatTextLineBreaks | 3 | MS-DOS Text | wdFormatDOSText | 4 | MS-DOS Text with Line Breaks | wdFormatDOSTextLineBreaks | 5 | Rich Text Format | wdFormatRTF | 6 | Unicode Text | wdFormatUnicodeText | 7 | Web Page | wdFormatHTML | 8 | Web Archive | wdFormatWebArchive | 9 | XML Document | wdFormatXML | 12 | Both of the following statements are equivalent (that is, they both save the active document as a Web page): ActiveDocument.Save "index.html", wdFormatHTML ActiveDocument.Save "index.html", 8 | This is the simplified syntax for the SaveAs method. To see all 11 arguments in their full syntax, look up the SaveAs method in the VBA Help system. | Closing a Document When you no longer need a document, you can reduce clutter on the screen and within Word by closing the corresponding Document object using the Close method: Document .Close( SaveChanges, OriginalFormat, RouteDocument ) Document | The Document object you want to close. | SaveChanges | (optional) If the document has been modified, this argument determines whether Word saves those changes: | | wdSaveChanges | Saves changes before closing. | | wdDoNotSaveChanges | Doesn't save changes. | | wdPromptToSaveChanges | Asks the user if he or she wants to save changes (this is the default). | OriginalFormat | Specifies the format to use when saving the document: | | wdOriginalFormat | Saves the document using its original format (this is the default). | | wdWordDocument | Saves the document in Word format. | | wdPromptUser | Asks the user if he wants to save the document in its original format. | RouteDocument | If set to True, this argument tells Word to route the document to the next recipient. | For example, the following statement closes the active document and saves any changes: ActiveDocument.Close wdSaveChanges Example: Making Document Backups Let's put the Document object properties and methods you've learned so far to work by creating a procedure that not only saves a document, but also makes a backup copy to a floppy drive. Listing 7.3 shows a procedure named MakeBackup that does all this by using the SaveAs method, as well as a few other methods and properties of the Document object. Listing 7.3. A Procedure that Creates a Backup Copy of the Active Document on a Floppy Disk Sub MakeBackup() Dim backupFile As String Dim currFile As String With ActiveDocument ' ' Don't bother if the document is unchanged or new ' If .Saved Or .Path = "" Then Exit Sub ' ' Mark current position in document ' .Bookmarks.Add Name:="LastPosition" ' ' Turn off screen updating ' Application.ScreenUpdating = False ' ' Save the file ' .Save ' ' Store the current file path, construct the path for the ' backup file, and then save it to Drive A ' currFile = .FullName backupFile = "A:\" + .Name .SaveAs FileName:=backupFile End With ' ' Close the backup copy (which is now active) ' ActiveDocument.Close ' ' Reopen the current file ' Documents.Open FileName:=currFile ' ' Return to pre-backup position ' Selection.GoTo What:=wdGoToBookmark, Name:="LastPosition" ' ' Turn screen updating back on ' Application.ScreenUpdating = True End Sub After declaring a couple of variables , this procedure checks to see whether the backup operation is necessary. In other words, if the document has no unsaved changes (the Saved property returns True) or if it's a new, unsaved document (the Path property returns ""), bail out of the procedure (by running Exit Sub ). Otherwise, a new Bookmark object is created to save the current position in the document. (This ensures that when we reopen the document after running SaveAs later on, the user will be returned to his or her place in the document.) Bookmarks is a collection that holds all the defined bookmarks in a specified Document object. Each element of this collection is a Bookmark object. To add a bookmark, use the Add method, as follows : Document .Bookmarks.Add Name:= BookmarkName Document | The Document object you want to work with. | BookmarkName | A string that specifies the name of the bookmark. | Then the following statement turns off screen updating, which means the user won't see the opening and closing of files that occur later in the code: Application.ScreenUpdating = False Then the file is saved using the Save method. You're now ready to perform the backup. First, the currFile variable is used to store the document's full path name (that is, the document's drive, folder, and filename), which is given by the FullName property. Then the path name of the backup file is built with the following statement: backupFile = "A:\" + .Name This will be used to save the file to drive A. Note that this statement is easily customized to save the file to a different hard disk or even a network drive. The actual backup takes place via the SaveAs method, which saves the document to the path given by backupFile . From there, the procedure closes the backup file, reopens the original file, and uses the GoTo method to return to the original position within the document. Automating the Backup Procedure Rather than running the MakeBackup procedure by hand, it would be better to schedule backups at specific times or at regular intervals. You can do this by using the Application object's OnTime method, which runs a procedure at a specified time, using the following syntax: Application.OnTime( When, Name, Tolerance ) When | The time (and date, if necessary) you want the procedure to run. Enter a date/time serial number. | Name | The name (entered as text) of the procedure to run when the time given by When arrives. | Tolerance | If Word isn't ready to run the procedure at When , it will keep trying for the number of seconds specified by Tolerance . If you omit Tolerance , VBA waits until Word is ready. | The easiest way to enter a time serial number for the When argument is to use the TimeValue function: TimeValue( Time ) Time | A string representing the time you want to use (such as "5:00PM" or "17:00"). | For example, the following formula runs the MakeBackup procedure at 5:00 PM: Application.OnTime _ When:=TimeValue("5:00PM"), _ Name:="MakeBackup" That's fine, but what we really want is for the OnTime method to run after a specified time interval (for example, a half hour from now). To make this happen, use Now + TimeValue( Time ) for When (where Time is the interval you want to use). For example, the following statement schedules the MakeBackup procedure to run in five minutes: Application.OnTime _ When:=Now + TimeValue("00:05"), _ Name:="MakeBackup" More Useful Document Object Methods Besides Open , Save , SaveAs , and Close , Document objects have dozens of other methods that let you do everything from activating a document to printing it. Here are some of the methods you'll use most often: Document. Activate Activates the specified open Document . For example, the following statement activates the Tirade.doc document: Documents("Tirade.doc").Activate Document. PrintOut Prints the specified Document . The full syntax of this method has no fewer than 18 arguments (all of which are optional). Here are the first dozen: Document .PrintOut( Background, Append, Range, OutputFileName, From , _ To, Item, Copies, Pages, PageType, PrintToFile, Collate ) Document | The Document object you want to print. | Background | If True, the procedure continues while Word prints the document in the background. If False, the procedure waits until the document has spooled. | Append | If True, the output is appended to the end of the file specified by the OutputFileName argument. If False, the output overwrites the contents of the file. | Range | Specifies the range of text to print, as follows: | | wdPrintAllDocument | Prints the entire document. | | wdPrintCurrentPage | Prints only the current page. | | wdPrintFromTo | Prints a range of pages from a starting page number (see the From argument) to an ending page (see the To argument). | | wdPrintRangeOfPages | Prints a range of pages (see the Pages argument). | | wdPrintPrintSelection | Prints only the currently selected text. | OutPutFileName | The path and filename of the file to which you want the document printed. (Note that the PrintToFile argument must be set to True.) | From | If Range is wdPrintFromTo , this argument specifies the page number from which to start printing. | To | If Range is wdPrintFromTo , this argument specifies the page number of the last page to print. | Item | A constant that represents the item you want to print. Use one of the following values wdPrintAutoTextEntries , wdPrintComments , wdPrintDocumentContent , wdPrintKeyAssignments , wdPrintProperties , or wdPrintStyles . | Copies | The number of copies to print. The default value is 1. | Pages | If Range is wdPrintRangeOfPages , this argument specifies the page range (for example, 4-8,10). | PageType | Specifies which pages to print using one of the following constants wdPrintAllPages , wdPrintEvenPagesOnly , wdPrintOddPagesOnly . | PrintToFile | If True, Word prints the document to a file and prompts the user for a filename. | Collate | If True and Copies is greater than 1, prints the entire document, then prints the next copy. If False and Copies is greater than 1, prints multiple copies of the first page, then the second page, and so on. | Document. PrintPreview Displays the specified Document in the Print Preview window. Document .Redo Redoes the last action that was (or actions that were) undone: Document .Redo( Times ) Document | The Document object you want to work with. | Times | (optional) The number of actions that you want redone (the default is 1). | Document .Select Selects all the text in the specified Document . Document .Undo Undoes the last action that was (or actions that were) performed: Document .Undo( Times ) Document | The Document object you want to work with. | Times | (optional) The number of actions that you want undone (the default is 1). | |