Getting help with calling Word's built-in dialogs using VBA (and why doing so can be much more useful than you'd think)

Article contributed by Jonathan West and Dave Rado

Where to find Help on them
There are two Help topics in Word VBA Help that are required reading to get you started with built-in dialogs: Displaying built-in Word dialog boxes and Built-in dialog box argument lists. Unfortunately, in the latter article, Microsoft listed the arguments you can use but forgot to mention what the arguments mean or what values they can take!

Fortunately, the dialog box arguments are almost identical to the arguments of the commands of WordBasic, so if you know one, you can work out the other. Therefore, the WordBasic Help file is at present by far the best resource for programmers wanting to use the dialogs. It is an absolute must-have. 


Download WordBasic Help File
Microsoft has made the old WordBasic help file available online. For further information about WordBasic commands, you can download it here..


Why use built-in dialogs?
There are four reasons to use them.


One obvious use is in order to display them to the user. 


You can execute a built-in dialog without actually displaying it, thus allowing you to execute all of the relevant settings simultaneously; whereas with VBA, each statement executes one at a time. As a result, using the wdDialog method can sometimes make your code run much faster and use far less memory. 

A good example is wdDialogFormatBordersAndShading. Using this, you can execute all your borders and shading arguments with one Execute statement; whereas using native VBA, you have to set many separate properties one at a time (top border, bottom border etc.). As a result, not only will your code run much faster if you execute the built-in dialog, but you are far less likely to get Formatting too complex errors while your code is running. Consider the following, for instance:

With Dialogs(wdDialogFormatBordersAndShading)
    .ApplyTo = 3
    .Shadow = 0
    .Shading = 0
    .Foreground = 0
    .Background = 0
    .LeftStyle = 0
    .RightStyle = 0
    .TopStyle = 0
    .BottomStyle = 0
    .HorizStyle = 0
    .VertStyle = 0
End With

All the above properties are executed in one go by the .Execute statement, whereas if you use native VBA as shown below, each line executes before the next line starts to run, and so the macro runs far more slowly and uses far more memory:

With Selection.Tables(1)
    With .Shading
        .Texture = wdTextureNone
        .ForegroundPatternColor = wdColorAutomatic
        .BackgroundPatternColor = wdColorAutomatic
    End With
    .Borders(wdBorderLeft).LineStyle = wdLineStyleNone
    .Borders(wdBorderRight).LineStyle = wdLineStyleNone
    .Borders(wdBorderTop).LineStyle = wdLineStyleNone
    .Borders(wdBorderBottom).LineStyle = wdLineStyleNone
    .Borders(wdBorderHorizontal).LineStyle = wdLineStyleNone
    .Borders(wdBorderVertical).LineStyle = wdLineStyleNone
    .Borders(wdBorderDiagonalDown).LineStyle = wdLineStyleNone
    .Borders(wdBorderDiagonalUp).LineStyle = wdLineStyleNone
    .Borders.Shadow = False
End With


A third reason for using the wdDialogs is that in a few cases, it does much of the work for you that you would otherwise have to write a lot of code to do – for instance, if you want to change the page setup for the current selection, if you use wdDialogPageSetup, and set .ApplyPropsTo = 3, the section breaks are inserted for you. Doing the equivalent in native VBA is much more involved because you have to check whether there is already a section break before or after the selection, and whether the selection begins at the start of the doc and or ends at the end of the doc. Why write the code to do that in VBA when it's already been written in C++ by Microsoft? For instance, the following code snippet creates a landscape section at the selection (Chr$(34) is how you specify the inch (") symbol in WordBasic):

With Dialogs(wdDialogFilePageSetup)
    .ApplyPropsTo = 3
    .PageWidth = 11.69 & Chr$(34)
    .PageHeight = 8.27 & Chr$(34)
    .TopMargin = -1.7 & Chr$(34)
    .BottomMargin = 0.81 & Chr$(34)
    .LeftMargin = iLeftMargin & Chr$(34)
    .RightMargin = 0.95 & Chr$(34)
    .Orientation = wdOrientLandscape
    .DifferentFirstPage = False
    .HeaderDistance = 0.28 & Chr$(34)
    .FirstPage = 0
    .OtherPages = 0
End With


You can get and set information that would be difficult or, in some cases, impossible to get using native VBA”, by looking (in code) at the settings of a built-in dialog – without having to display the dialog. 

For some very useful examples, see:

Finding and replacing symbols

How to change the behaviour of Word's document protection, so users formfields don't get reset when they unprotect and reprotect

How to get the column number of the selection (in a document containing snaking, or newspaper-style, columns)

How to retrieve Word's default Documents path or Pictures path setting

How to assign a Name to a FormField that doesn't already have a Name, using VBA

Changing the selected (current) printer in Word without changing the system default printer

How to set the default suggested filename to be displayed by the Save As dialog the first time a user saves a new document

How to safely update a document's styles from its template without using the Organizer (and how to make the Tools + Templates and Add-ins dialog safe)

Note that a fair number of the wdDialog arguments simply don't work. For example, the Context argument (the Look in setting) for the Autotext dialog has no effect, and there are many other arguments which don't work.

There are also well-known bugs with several of the wdDialogs. For example, the wdDialogFileOpen dialog won't allow the user to open more than one file at a time, although there is a workaround – see: Calling FileOpen dialog in VBA does not allow opening of multiple files.

But at least with the aid of the WordBasic Help file you can find out what the dialogs are meant to do!

Click to view Terms of Use page

Click to view Disclaimer page