In earlier days, a macro consisted of a series of keystrokes that was recorded and assigned to a hotkey. When a user invoked the hotkey, the recording would play and the recorded keystrokes would be executed.
These days, macros (at least for Microsoft Office) are much more sophisticated. In fact, a Word macro is just a special type of subroutine—one that does not have any parameters. (I discuss subroutines and parameters in Chapter 6, Functions and Subroutines.)
For example, suppose you record a macro that does a find and replace, replacing the word “macro” with the word “subroutine.” When you look in the Projects window under the project in which the macro was recorded (usually the attached template), you will find a new standard module called NewMacros containing the following subroutine:
Sub AMacro() ' AMacro Macro Macro recorded 04/27/98 by sr ' Selection.Find.ClearFormatting Selection.Find.Replacement.ClearFormatting With Selection.Find .Text = "macro" .Replacement.Text = "subroutine" .Forward = True .Wrap = wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False End With Selection.Find.Execute Selection.Find.Execute Replace:=wdReplaceAll End Sub
This is the same code that someone might have written in order to perform this find and replace operation.
Word does a very thorough job of translating keystrokes into VBA code, essentially matching in code every item in the Find and Replace dialog box shown in Figure 4-14—even the ones that we have not changed—because it has no way of knowing what we have and have not changed!
In certain situations, the macro recorder can serve as a useful learning tool. If we can’t figure out how to code a certain action, we can record it in a macro and cut and paste the resulting code into our own program.
However, before you get too excited about this cut-and-paste approach to programming, we should point out that it is not anywhere near the panacea one might hope. First (and least serious), since the macro recorder does such a thorough job of translating our actions into code, it tends to produce very bloated code, which can run very slowly. For instance, the previous search and replace can also be done using the following code, which is considerably more compact:
Sub AMacro() Selection.Find.ClearFormatting Selection.Find.Replacement.ClearFormatting With Selection.Find .Text = "macro" .Replacement.Text = "subroutine" .Wrap = wdFindContinue End With Selection.Find.Execute Selection.Find.Execute Replace:=wdReplaceAll End Sub
Second (and more serious), the macro recorder is capable of recording only very simple procedures. Most useful Word programs are far too complicated to be recorded automatically by the macro recorder.
As you may know, to run a macro from the user interface, you just choose Macros from the Macro submenu of the Tools menu (or hit Alt-F8). This displays the Macro dialog box shown in Figure 4-15. This dialog box lists all macros in the current document or in any attached templates (including normal.dot and any other attached global templates). From here, we can do several things, including running, editing, creating, or deleting macros. (Choosing Edit or Create places you in the VB Editor.)
We should also comment on what appears and does not appear in the Macro list box. All written macros will appear in the Macros dialog box (as will all recorded macros). However, there are a few variations. If you give the macro a unique name (within the context given in the Macros In list box), then only the name of the macro will appear in the list box. If the name is not unique, then it must be qualified by the name of the module in which the macro appears, as in:
in Figure 4-15. (It happens that I have another FindBullets macro, in another module, that is not visible in Figure 4-15.) Finally, note that if the macro is one that has been converted by Word from WordBasic (which is used by Word 95), then Word calls the procedure Main. Hence, if there are several such macros, their names must be qualified (as in ColorBlue.Main, ColorGreen.Main, and so on).
Note that we can prevent a macro procedure from appearing in the Macros list box by making the procedure private, using the
Private keyword, as in:
Private Sub HideThisMacro()
I discuss private and public procedures in Chapter 6.
Finally, if you are like me, you will collect a great many macros over the years. As time goes by, you may forget the names of some of these macros and thus have trouble finding a macro when you need it. I strongly advise you to give some careful thought to creating a consistent naming convention for macros. I begin the names of all macros with a word that categorizes the macro. For instance, all of my macros that deal with tables begin with the word Table, as in:
Table_AutoFit Table_MakeMultiColumn Table_DeleteCellandCloseUp