In the code listings that accompany a couple of my Outlook VBA on Demand columns, you might have noticed the On Error Resume Next statement. Until now, I haven't explained the statement's purpose, except that it lets Outlook continue running code after an error occurs. Any good program that goes beyond the sample stage into production use has some mechanism for dealing with errors. In this installment, I explain more about error handling—specifically, when you need it and how to implement it.
You can categorize potential Outlook code errors into five types:
- Simple syntax errors that occur when you type code. VBA's programming environment typically gives you a pop-up message to alert you to typos.
- Errors that appear when you use the Debug, Compile command to compile your Outlook VBA project, or when you first try to run a procedure. For example, you might have a series of nested If...End If statements without an End If to match each If.
- Runtime errors. Outlook alerts you to runtime errors only when it executes your code's problem statement. Outlook developers' most common runtime error is forgetting to use the Set statement while assigning a value to an object variable or to an Outlook item's object property. For example, code in the ThisOutlookSession module that sets which folder to display in the current Outlook window requires a Set statement such as
Set Application.ActiveExplorer .CurrentFolder = objFolder
because the CurrentFolder property is an object property. Failure to use Set in this statement results in a runtime error.
- Logic errors. These are the dumb mistakes you make—the flaws in the logic of your program. We all make them, but finding them can be difficult. Outlook VBA contains many debugging tools that help you monitor the current values of different variables and rerun certain segments of code. You can find the tools on the Debug menu. You can also use the Immediate window to test code statements; simply type or copy the statements, then press Enter.
- Outlook application bugs. Microsoft failed to fix (or discover) these bugs before the scheduled release date. Eventually, Microsoft's Knowledge Base documents most of these bugs. If you want to be able to quickly search the Knowledge Base, place a link to http://support.microsoft.com/kb/c.asp on your desktop or in your Favorites list.
Now I want to give you a few pointers for handling runtime errors. In the process, you'll see a handy Outlook VBA routine to display the built-in dialog box that lets the user pick a folder.
Before you start, you need to have an OutlookFunctions module in which you can store the new routines you'll build. If necessary, use the Insert, Module command to create the module. You'll use the Outlook Functions module to store procedures that you want to reuse, calling them from new VBA subroutines and functions that you create in other modules.
How do you get Outlook to display its built-in dialog box for picking a folder (i.e., the dialog box that users see when they use Outlook's commands for moving and copying items between folders or creating new folders)? Outlook provides the PickFolder method of the NameSpace object—an object that represents the folder hierarchy in the current session. Add the code you see in Listing 1 to your OutlookFunctions module.
Use Insert, Module to add a new module in which you can create some test code. You can either leave the name as it is or rename the module Tests. You can use this module for your VBA experiments, then cut and paste the successful test code to other modules (e.g., OutlookFunctions) for permanent use.
Add the code you see in Listing 2 to the new test module. To run the code, click the Run button on the toolbar. In the Select Folder dialog box that appears, choose a folder, then click OK. After the Select Folder dialog box closes, you'll see a message box that shows the name of the folder you selected. (The MsgBox statement is a handy way to pop up data from your program so you can see the precise order of the program's actions.)
Run the ShowNameOfFolder subroutine again, but this time click Cancel to close the Select Folder dialog box without choosing a folder. A message box (which Screen 1 shows) informs you that you have a runtime error. If you click Debug on the message box, VBA highlights the problem statement, as Screen 2 shows.
The MsgBox objFolder.Name statement is a problem because, by canceling the Select Folder dialog box, you removed the UserPickFolder() function's ability to return a valid MAPIFolder object representing an Outlook folder. Instead, the function returned Nothing, a VBA keyword signifying that no object is associated with the particular object variable. Because no valid MAPIFolder object exists, Outlook can't return a Name property that the MsgBox statement can use.
How can you avoid this type of runtime error? Your approach largely depends on whether you want to interact with the user after an error occurs, whether more than one type of error is likely to occur, and whether you want to handle each type of error separately. Listing 3 shows the simplest type of error handling. The On Error Resume Next statement tells Outlook to ignore any errors and continue running the procedure's code, beginning with the first statement following the one that triggered the error. With the ShowNameOfFolderIgnoreErrors procedure, if you cancel the Select Folder dialog box, Outlook doesn't display a message box with the runtime error.
If you want to interact with the user and you're aware of the errors that might arise (e.g., the user canceling the selection of the folder in this example), you can build code to explicitly handle those runtime errors. The code you see in Listing 4 tests the object that the UserPickFolder() method returns to determine whether a valid MAPIFolder object is present. If a valid MAPIFolder object isn't present (If objFolder Is Nothing Then), the code displays a message box informing the user that he or she forgot to pick a folder. If a valid MAPIFolder object exists, a message box displays the name of the folder.
With these basics, you can start adding some rudimentary error handling to your VBA routines. As we develop more complicated procedures that require you to handle several different possible errors, I'll introduce other error-handling techniques.