When you first start to write macros, you'll probably be satisfied with simply getting the job done. However, when you write a macro that will be used many times or that will be used by other people, you should consider optimizing the macro so that it requires less time and memory to run. The following techniques will help you write smaller, faster macros.
- Specify only the arguments you need. The macro recorder explicitly sets all available arguments. For example, the macro recorder records the following instruction when you close the Paragraph dialog box.
FormatParagraph .LeftIndent = "0" + Chr$(34), .RightIndent = "0" + Chr$(34), .Before = "0 pt", .After = "0 pt", .LineSpacingRule = 2, .LineSpacing = "", .Alignment = 0, .WidowControl = 1, .KeepWithNext = 0, .KeepTogether = 0, .PageBreak = 0, .NoLineNum = 0, .DontHyphen = 0, .Tab = "0", .FirstIndent = "0" + Chr$(34)
However, if you only want to change the line spacing to double, you can delete the additional arguments from the FormatParagraph instruction. For example:
FormatParagraph .LineSpacingRule = 2
- A macro that changes the appearance of a document — such as a macro that changes the formatting of every table in a large document — will run faster when screen updating is turned off. Use the ScreenUpdating statement at the beginning of your macro to prevent screen updates while the macro is running. You can use the Print statement to let the user know the progress of the macro (for example, Print "Working...").
If you want to show changes on the screen while a macro is running, you can improve performance by switching to normal view, using picture placeholders, disabling background repagination, and using the draft font, all of which are accomplished by the following instructions:
ViewNormal
ToolsOptionsView .PicturePlaceHolders = 1, .DraftFont = 1
ToolsOptionsGeneral .Pagination = 0
At the end of the macro, be sure to restore the settings back to the user's original settings.
- Minimize the use of global variables. Reuse local or temporary variables instead of defining additional variables. Also, reuse arrays and dialog records by using the Redim statement to reset the variables.
- Keep variable names, label names, and text between quotation marks short. These items don't "tokenize" when a macro is run and can slow down processing time. Remark statements (REM) and blank lines also don't tokenize and can slow down a macro.
Note that while these tips may improve performance, your macro will lose readability. For this reason, it may be best to make these changes just before distributing a macro.
- The Select Case control structure executes faster than a complex If...Then...Else condition. The For...Next loop is faster than the While...Wend loop.
- The GetText$() function is faster than selecting text and using the Selection$() function. You can often use GetSelStartPos(), GetSelEndPos(), and SetSelRange instead of bookmarks. These commands are faster than setting and using bookmarks.
- Calling a subroutine in another macro is slower than calling a subroutine in the same macro. You may want to copy frequently called subroutines into the same macro.
- You cannot turn off the Undo or Redo commands on the Edit menu, nor can you change the maximum number of actions Word stores in the Undo or Redo lists (Word stores up to approximately 100 or the total number of actions in one document). If you are experiencing out-of-memory errors or slow performance, try periodically clearing the Undo and Redo lists by calling the following subroutine.
Sub ClearUndoList
Dim Dlg As ToolsRevisions
GetCurValues Dlg
ToolsRevisions .MarkRevisions = Abs(Dlg.MarkRevisions - 1)
ToolsRevisions .MarkRevisions = Dlg.MarkRevisions
End Sub
- If you are experiencing out-of-memory errors with a macro that makes extensive edits to a document, save the document periodically without fast saves active. For example, the following macro replaces all semicolons with tabs in a document. The If statement and count variable are used to save the document after every 50 replacements.
Sub MAIN
ToolsOptionsSave .FastSaves = 0
StartOfDocument
count = 0
EditFindClearFormatting
EditFind .Find = ";", .Direction = 0
While EditFindFound()
count = count + 1
EditClear
Insert Chr$(9)
If count = 50 Then
FileSave
count = 0
End If
RepeatFind
Wend
End Sub
- If possible, move commonly used routines into a Word add-in library (WLL). Word add-in libraries are faster and more efficient than thier equivalent WordBasic macros. For information on creating Word add-in libraries, see Appendix C, "Microsoft Word Application Programming Interface."