Word Hacks [Electronic resources]

Andrew Savikas

نسخه متنی -صفحه : 162/ 94
نمايش فراداده

Hack 63 Use Word Dialogs in a Macro

Using Word's own dialogs in your macros allows the person using the macros to work with a familiar interface, which can make even complicated macros seem easy to use.

Macros that must interact with the person using them are generally harder to write than those that just run from start to finish without needing any user input. In many cases, however, Microsoft has already done the work of designing a useful interface for modifying the same sorts of things your macro probably does (i.e., parts of a Word document).

For example, if you've got a macro that inserts a particular kind of table into your document, you might want to let the user choose the number of rows and columns to put in the table each time the macro is run. Rather than create your own user form in the Visual Basic Editor, you can use Word's InsertTable dialogjust show the dialog and capture the row and column numbers selected, and your macro can insert the right-sized table.

This hack shows you two different ways of exploiting Word dialogs from within a macro.

Put the macros in this hack into the template of your choice [Hack #50] and run them from the ToolsMacroMacros dialog.

7.8.1 Use Dialogs to Execute Commands Interactively

Say you've created a macro to open a new file and fill it with useful information, such as a table of available system fonts [Hack #15] . But before the macro finishes, you want it to prompt the user to save the new document. The following code creates a new, blank document, and then displays Word's own FileSaveAs dialog (the same one that appears whenever you save a new document for the first time):

Sub ShowFileSaveAsDialog( )
Dim dial As Dialog
Dim doc As Document
Set dial = dialogs(wdDialogFileSaveAs)
Set doc = Documents.Add
dial.Show
MsgBox "Thanks! You either saved the document or canceled the dialog."
End Sub

When the FileSave dialog appears, the user can click either the Save button or the Cancel button, but this version of the macro has no way of knowing which one the user clicked. If you want your macro to behave differently depending on which button the user clicks, you can evaluate the dialog's return value, which is like the answer to a question. As an example of using a return value, the following macro displays the number of currently open documents, which it finds by getting the return value from the Count property:

Sub HowManyDocumentsAreOpen( )
Dim iNumberOfDocuments As Integer
iNumberOfDocuments = Documents.Count ' Getting a return value
MsgBox iNumberOfDocuments ' Displaying that return value
End Sub

A dialog used in a macro returns a value that indicates which button in the dialog the user clicked to exit the dialog. If the user clicked the Cancel button, or the Close button in the top corner of the dialog, the return value is 0. You can use this information to modify the ShowFileSaveAsDialog macro so that it "knows" whether the user clicked the Save or Cancel button and reacts accordingly:

Sub ShowFileSaveAsDialog
Dim dial As Dialog
Dim doc As Document
Set dial = dialogs(wdDialogFileSaveAs)
Set doc = Documents.Add
If dial.Show <> 0 Then
' Didn't press Cancel
MsgBox "Thanks for saving the document."
Else
' Pressed Cancel
MsgBox "Afraid of commitment?"
End If
End Sub

In this version, if the user clicks the Save button, the macro displays its gratitude. If the user clicks the Cancel button, it displays a sarcastic message.

If you also want to suggest a specific name for the new document created by the macro, you can supply values for certain dialog components. For the FileSaveAs dialog, you can suggest a name by assigning a value to the Name property before showing the dialog:

Sub ShowFileSaveAsDialogAndSuggestName
Dim dial As Dialog
Dim doc As Document
Set dial = dialogs(wdDialogFileSaveAs)
Set doc = Documents.Add
dial.Name = "YourNewDocument.doc"
If dial.Show <> 0 Then
MsgBox "Thanks for saving the document."
Else
MsgBox "Still afraid of commitment?"
End If
End Sub

To find the names of the properties available in each dialog, do a search in the VBA help files for "built-in dialog arguments," as shown in Figure 7-8.

Figure 7-8. Getting a list of arguments for the built-in dialogs

7.8.2 Use Dialogs Just to Get Input

Sometimes a Word dialog is the best way to get certain types of information from the person running your macro, even if you don't want the dialog to "do" its usual duty.

For example, the following macro displays the FileSaveAs dialog from the previous section. But after you click the Save button, a message box appears showing the filename you chose instead of saving the document. The difference is that instead of using the Show method, as in the previous section, this macro uses the Display method, as indicated in bold.

Sub ShowFileSaveAsDialog( )
Dim dial As Dialog
Set dial = dialogs(wdDialogFileSaveAs)
dial.Display
MsgBox "You asked to save the file as: " & dial.Name & ". Too bad."
End Sub

With Show, the dialog does what you expect; in the case of FileSaveAs, clicking the Save button saves the current document with the name you provide. But with Display, the dialog captures the name you entered but doesn't actually do the save.

To return to the scenario of inserting a table described at the beginning of this hack, the following macro inserts a two-row, three-column table at the insertion point. The first row is styled as "Heading 1," and the rest of the table is styled as "Heading 2":

Sub TableWithSpecialHeadings( )
Dim tbl As Table
Set tbl = Selection.Tables.Add(Range:=Selection.Range, _
NumRows:=2, NumColumns:= 3)
tbl.Range.Style = wdStyleHeading3
tbl.Rows(1).Range.Style = wdStyleHeading2
End Sub

This macro becomes more versatile if you can choose the number of rows and columns each time you run it. The following macro prompts the user with the InsertTable dialog, captures the column and row numbers chosen, and then inserts the special table:

Sub TableWithSpecialHeadings( )
Dim tbl As Table
Dim dial As Dialog
Set dial = Dialogs(wdDialogTableInsertTable)
If dial.Display = 0 Then
' User pressed Cancel, so quit now
Exit Sub
End If
Set tbl = Selection.Tables.Add(Range:=Selection.Range, _
NumRows:=dial.NumRows, _
NumColumns:=dial.NumColumns)
tbl.Range.Style = wdStyleHeading3
tbl.Rows(1).Range.Style = wdStyleHeading2
End Sub