Chapter 29. Debugging Macros and Custom Functions

Using Design-Time Tools

Dealing with Run-Time Errors

IF you made it through the previous two chapters, you now have at least a smattering of Microsoft Visual Basic for Applications (VBA) at your command—as well as, we hope, an appetite for learning more. The best ways to acquire more expertise in this versatile programming language are to read a book on the subject, such as Microsoft Visual Basic 2008 Step by Step by Michael Halvorson (Microsoft Press, 2008), and to experiment. As you do your everyday work in Microsoft Excel 2010, look for chores that are ripe for automating. When you come across something macro-worthy, record your actions. Then inspect the code generated by the macro recorder. Be sure you understand what the recorder has given you (read the Help text for any statements you don’t understand), and see whether you can find ways to make the code more efficient. Eliminate statements that appear unnecessary, and then see whether the code still does what you expect it to do. Look for statements that select ranges or other objects, and see whether you can make your code perform the essential tasks without first selecting those objects.

As you experiment and create larger, more complex macros and functions, you will undoubtedly produce some code that either doesn’t run at all or doesn’t give you the results you want. Missteps of this kind are an inevitable aspect of programming. Fortunately, the VBA language and the Visual Basic Editor provide tools to help you trap errors and root out bugs. These tools are the subject of this chapter.

In this chapter, you’ll look at two kinds of error-catching tools: those that help you at design time, when you’re creating or editing code, and those that work at run time, while the code is running.

The Visual Basic Editor design-time error-handling tools let you correct mistakes in VBA syntax and catch misspellings of variable names. They also let you follow the “flow” of a macro or function (seeing each line of code as it is executed) and monitor the values of variables during the course of a procedure’s execution.

If you type a worksheet formula incorrectly in Excel, Excel alerts you to the error and refuses to accept the entry. The VBA compiler (the system component that converts your English-like VBA code into the machine language that actually executes the macro on your computer) ordinarily performs the same service for you if you type a VBA expression incorrectly. If you omit a required parenthesis, for example, the compiler beeps as soon as you press Enter. It also presents an error message and displays the offending line of code in a contrasting color (red, by default).

Certain kinds of syntax errors don’t become apparent to the compiler until you attempt to run your code. For example, if you write the following:

With Selection.Border
    .Weight = xlThin
    .LineStyle = xlAutomatic

and attempt to run this code without including an End With statement, you see this error message:

image with no caption

Your procedure halts, and you are now in break mode. (You can tell you’re in break mode by the appearance of the word break in brackets in the Visual Basic Editor title bar. The line the compiler was attempting to execute will be highlighted—in yellow, by default.) Break mode lets you fix your code and then continue running it. For example, if you omit an End With statement, you can add that statement while in break mode, and then press F5 (or select Run, Continue) to go on with the show. If you want to exit from break mode rather than continue with the execution of your procedure, select Run, Reset.

If you don’t like having the compiler complain about obvious syntax errors the moment you commit them, you can turn off that functionality. Click Tools, Options, click the Editor tab (shown in Figure 29-1), and clear the Auto Syntax Check check box. With automatic syntax checking turned off, your syntax errors will still be flagged when you try to run your code.

Auto Syntax Check is on by default. So are three other “auto” options: Auto List Members, Auto Quick Info, and Auto Data Tips. These options are all useful, and you should leave them on, especially if you’re relatively new to VBA. Auto List Members and Auto Quick Info help you complete a line of VBA code by displaying available options at the current insertion point or the names of arguments required by the function you’re currently entering. Auto Data Tips is relevant only in break mode. If you rest your pointer on a variable name in break mode, the Auto Data Tips feature displays the current value of that variable as a ScreenTip.

The VBA compiler doesn’t care about the capitalization style of your variable names. MyVar, myVar, and myvar are identical names as far as the compiler is concerned. (If you’re inconsistent about the capitalization of a variable name, the Visual Basic Editor adjusts all instances of that variable to make them the same.) If you change the spelling of a variable name in mid-program, however, the compiler creates a new variable, and havoc for your program ensues. An error in programming introduced by a misspelled variable can be especially treacherous because the program might appear to behave normally.

You can virtually eliminate the possibility of having inconsistently spelled variable names in a module by adding a single statement at the top of that module (before any Sub or Function statement):

Option Explicit

The Option Explicit statement forces you to declare any variables used in the current module. You declare variables with Dim statements. (For complete details about Dim, type Dim in a module, and then press F1.) With Option Explicit in place, if you use a variable without first declaring it, you get a compile error at run time. If you accidentally misspell a variable name somewhere in your program, the compiler flags the misspelled variable as an undeclared variable, and you’ll be able to fix the problem forthwith.

You can add Option Explicit to every new module you create by clicking Tools, Options, going to the Editor tab, and then selecting the Require Variable Declaration check box. This option is off by default, but it’s good programming practice to turn it on. Option Explicit does more for you than eliminate misspelled variable names. By forcing you to declare your variables, it also encourages you to think ahead as you work.

The Visual Basic Editor step commands cause the compiler to execute either a single instruction or a limited set of instructions and then pause in break mode, highlighting the next instruction that will be executed. Execution is suspended until you take another action—such as issuing another step command, resuming normal execution, or terminating execution. By issuing step commands repeatedly, you can follow the procedure’s execution path. You can see, for example, which way the program branches when it comes to an If statement or which of the alternative paths it takes when it encounters a Select Case structure. (A Select Case structure causes the program to execute one of a set of alternative statements, depending on the value of a particular variable. For details, type case in a module, and press F1.) You can also examine the values of variables at each step along the way.

You have four step commands at your disposal. You’ll find these commands—and their keyboard shortcuts—on the Debug menu:

You can run an entire procedure one step at a time by repeatedly pressing F8 (the keyboard shortcut for Debug, Step Into). To begin stepping through a procedure at a particular instruction, move your cursor to that instruction, and press Ctrl+F8 (the shortcut for Debug, Run To Cursor). Alternatively, you can force the compiler to enter break mode when it reaches a particular instruction, and then you can use any of the step commands.

The Watch Window shows the current values of selected variables or expressions and the current property settings for selected objects. You can use the Watch Window to monitor the status of variables and objects as you step through a procedure.

To display the Watch Window, click View, Watch Window. (To close the window, click its Close button.) To add a variable or object to the Watch Window, you can select it in the Code window and drag it to the Watch Window. You can add expressions, such as a + 1, to the Watch Window in this manner. Alternatively, you can add something to the Watch Window by clicking Debug, Add Watch. In the Expression text box in the Add Watch dialog box (see Figure 29-4), type a variable name or other valid VBA expression.

As Figure 29-4 shows, you can use the Add Watch dialog box to set a conditional breakpoint. Click Debug, Add Watch; specify the name of a variable or a VBA expression; and then select either Break When Value Is True or Break When Value Changes. Selecting Break When Value Is True for an expression is comparable to using a Debug.Assert statement to set a conditional breakpoint. The difference is that Debug.Assert causes a break when an expression becomes false, and Break When Value Is True does the opposite.