Error Handling 101

Home Up Odds & Ends Photo Gallery Search Contact Me

 

 

The information in this website is provided without risk or obligation and free of charge.  However, if you have benefitted from my efforts here and would like to make a contribution to help me continue and maintain this work then any donation will be greatly appreciated. Please click the adjacent button to access PayPal.  Thank you.
 

This Microsoft Word Help & Tips page provides a basic introduction to error handling and gives you some examples of error handling methods.  A more detailed discussion of the material can be found in the VBA Help file under the topics "On Error Statement" and "Resume Statement."

Why use error handling?  VBA help puts it like this:

What is a run-time error?  A run-time error is an error that occurs when code is running. A run-time error results when a code statement attempts an invalid operation.  For a lengthy list of things that can cause a run-time error see: "Trappable Errors" in the VBA Help file. 

With the following example macros you can produce some rather obvious run-time errors and then use On Error and Resume statements to illustrate some of the error handling methods.  To use these examples, start with a new blank document and copy the example macros to the document VBA project.  If you need help copying or applying a macro see fellow MVP Graham Mayor's tips here:  Installing Macros From Listings

Once you have the macros copied to the document VBA project, step through the lines of code using the F8 key or the Debug toolbar Step Into command and observe the results.

Sub BacicA()
Dim i As Integer
ActiveDocument.Variables("Test2").Value = "Testing"
For i = 1 To 3
    ActiveDocument.Variables("Test" & i).Delete
Next
End Sub

In this first example there is no error handler statement.   The procedure creates a variable named "Test2" then starts a For ... Next loop to delete variables named "Test1, Test2 and Test3." 

Go ahead and step through the procedure.  You will see that when the procedure attempts to delete the Variable "Test1" (an object that does not exist) the attempt is an "invalid operation" and a run-time error is generated.

Whenever you know, expect, or even suspect that a procedure will produce a run-time error, and in this case it is obvious, then one or more error handling statements can be used to complete execution and achieve the desired result.

In the next example an "On Error Resume Next" statement enables the error handler in the procedure and allows execution to continue with the "next" statement immediately following the statement that caused the error.  Run-time error messaging and subsequent fatal stops are suspended while the error handler is enabled.  Step through this procedure to observe that the expected errors (attempts to delete Varialbles1 and Variables3) are handled by simply continuing through the procedure until completion.

Sub BacicB()
Dim i As Integer
ActiveDocument.Variables("Test2").Value = "Testing"
For i = 1 To 3
    On Error Resume Next
'Enable error handler
    ActiveDocument.Variables("Test" & i).Delete
    MsgBox "If present, variable Test" & i & " was deleted."
Next
End Sub

In the example above the On Error Resume Next statement works as intended without complications.  However, as you have seen the On Error Resume Next enables an error handler and suspends the run-time error messaging and subsequent fatal stops.  Therefore it is not a good practice to use On Error Resume Next by itself if additional errors could occur in the procedure.  Consider this example:

Sub BacicC()
Dim i As Integer
ActiveDocument.Variables("Test2").Value = "Testing"
For i = 1 To 3
    On Error Resume Next
'Enable error handler
    ActiveDocument.Variables("Test" & i).Delete
    If i = 2 Then
        MsgBox "You have won a million dollars>." _
            & ActiveDocument.Variables("Test2").Value
'No longer exists.
    End If
Next
End Sub

Here the On Error Resume Next statement enables the procedures error handler when the procedure tries to delete the non-existent Test1 variable.  Run-time messaging and fatal stop is suspended.  Next the variable Test2 is deleted.  You would certainly be interested in getting that fanciful message about the million dollars.  However, the attempt to display that message will fail because the message requires a result from variable Test2 which has been deleted.   Unfortunately since the procedures error handler was previously enabled the run-time messaging and fatal stops are suspended.  The failed attempt to deliver the message passes without a whisper!

By adding another simple statement to your procedure, you can clear the err object and thereby reset the error handler that had been so recklessly left to go on unabated:

Sub HandlingErrorsBacicD()
Dim i As Integer
ActiveDocument.Variables("Test2").Value = "Testing"
For i = 1 To 3
    On Error Resume Next
'Enable error handler
    ActiveDocument.Variables("Test" & i).Delete
    On Error GoTo 0
'Clear the err object
    If i = 2 Then
        MsgBox "You have one a million dollars>." _
            & ActiveDocument.Variables("Test2").Value
        MsgBox "Aren't you glad you handled that error!"
    End If
Next
End Sub

When you step through this time you will experience a run-time error and fatal stop when the procedure tries to display the message about your windfall!  The added On Error GoTo 0 statement cleared the err object and reset the error handler so the default run-time error messaging and fatal stop was restored.  You should make it a practice to use an  On Error GoTo 0 in your procedures as soon as the expected error stage following the On Error Resume Next statement is completed to ensure other unrelated errors are not missed or improperly handled.

Of course you don't want to really see that jarring new error message.  You just want it properly handled behind the scene and you want to get your important message.

This next example uses the GoTo (line) method to achieve both of your goals:

Sub BacicE()
Dim i As Integer
ActiveDocument.Variables("Test2").Value = "Testing"
For i = 1 To 3
    On Error Resume Next
'Enable error handler
    ActiveDocument.Variables("Test" & i).Delete
    On Error GoTo BasicE_Error '
Clears the previous err object and enables error handler
    If i = 2 Then
        MsgBox "You have one a million dollars>." _
            & ActiveDocument.Variables("Test2").Value
        MsgBox "Aren't you glad you handled that error!"
    End If
Next
Exit Sub
BasicE_Error:
    If Err.Number = 5825 Then
        MsgBox "You have won a million dollars."
        Resume Next
    Else
        MsgBox "Unexpected error. Type: " & Err.Description
   End If
End Sub

Here the GoTo ErrHandler statement enables the error handler and directs execution to the line labeled ErrHandler:  The error is evaluated and if the error is 5825 or "Object has been deleted" as expected, then the important message is delivered and execution is returned to next line following the line that caused the error to occur. 

Note:  The line label "ErrHandler:" is arbitary.  If can be called anything you like to make reading your code convienient.    The important thing is that the lable must  be unique to the project and end with a colon(:).   You should place a Exit Sub line above the line lable so that the error handling procedure is bypassed when an error does not occur.

In each of the preceding examples you established conditions that would repeatedly fail.  You can never delete a variable or display the value of a varialbe that does not exist.   You have seen how On Error and Resume statements can be used to complete the execution of your prodecures seamlessly despite known errros. 

The next example demonstates using error handling to identify and help "resolve" the problem that caused the run-time error in the first place.  Once resolved, execution is returned to the line that caused the failure and run again.

Sub BacicF()
Dim i As Double
Dim j As Double
i = 6
j = 0
'Setting it up for initial failure
On Error GoTo BasicF_Error
MsgBox i / j
'Error occurs if j = 0
Exit Sub
BasicF_Error:
    If Err.Number = 11 Then
        j = InputBox(Err.Description & " is not allowed." _
            & " Enter a non-zero denominator.")
        Resume
    Else
        MsgBox "Unexpected error. Type: " & Err.Description
    End If
End Sub

Here an error is generated by establishing the denominator in a simple calculation as zero.  Division by zero is illogical.  When the error occurs, the error handler is enabled and the error evaluated.  The error handler routine provides an input box for the user to provide a non-zero denominator.  With the new denominator defined, the "Resume" statement directes execution back to the step in the procedure that caused the error.  If the user entered a non-zero value in the input box then the procedure executes to completion.
For humans, the word 'error' has connotations of 'bad' and 'mistake'; the computer has no such preconceptions: an error is an just a condition, same as 'no error'.

                                                                                  --Regular Word newsgroup contributor Jezebel

Err is an object, with properties and methods.  Using the err object is often useful to simplify or speed up your code.  Consider the task of determining if a particular style exists in a document.  An error free example would look something like this:
Sub ErrorFree()
Dim oStyle As Style
Dim styleName As String
styleName = "Goobledygook"
For Each oStyle In ActiveDocument.Styles
    If oStyle.NameLocal = styleName Then
        MsgBox styleName & " style exists in this document."
        Exit Sub
    End If
Next oStyle
    MsgBox styleName & " style is not found in this document."
End Sub
The code above is looking at every style in the document to determine if that style is the style sought. The time taken to do this for a few dozen sytels is inconsequential, but consider iterating a few thousand items and an approach using error handling:
Sub UsingErrorHandling()
Dim oStyle As Style
Dim styleName As String
styleName = "Goobledygook"
Set oStyle = Nothing
On Error Resume Next
Set oStyle = ActiveDocument.Styles(styleName)
On Error GoTo 0
If Not oStyle Is Nothing Then
    MsgBox StyleName & " style exists in this docuement"
Else
    MsgBox StyleName & " style is not found in this docuement"
End If
End Sub
The code above attempts to set the object variable oStyle to the style Goobledygook.  If the sytle does not exist an error occurs.  The Resume Next statement suspends run-time messaging.  The On Error GoTo 0 resets error handling and restores run time messaging.  An error occurred but you the user were unaware of it.  oStyle is "still" Nothing and the Else statement is executed.  If "Goobledygook" style where present and regardless if it was the first or last style is a collection of a billion, we would know it immediately and end the process.

Remember: 
   "Err" is an object with methods and properties.
   All "On Error" and "Resume" statements clear the Err object.  

 
Sub BasicG()
On Error Resume Next
Err.Raise 6
'Create an overload error
MsgBox Err.Number
'Display the error number using the err.numbernumber property
On Error GoTo 0
'Clear the err oject and resets run time messaging/fatal stop
If Err.Number <> 0 Then
    MsgBox Err.Number
'If it is still 6 you would see this message
Else
    MsgBox "You see the err object has been cleared. All " _
        & "On Error and Resume statements clear the " _
        & "err object."
End If
On Error GoTo BasicG_Error:
Err.Raise 6
BasicG_Exit:
If Err.Number <> 0 Then
    MsgBox Err.Number
Else
    MsgBox "You see the err object has been cleared. All " _
        & "On Error and Resume statements clear the " _
        & "err object."
End If
Exit Sub
BasicG_Error:
    MsgBox Err.Number
    Resume BasicG_Exit
End Sub
  The error handler doesn't have to be in the procedure that throws the error:
  Sub A()
On Error GoTo A_Error:
Call B
A_Exit:
Exit Sub
A_Error:
MsgBox "Error number: " & Err.Number & " , Description: " & Err.Description
Resume A_Exit
End Sub

Sub B()
Call C
End Sub

Sub C()
Err.Raise 6
'Throw error here
End Sub
You can use the err object to raise your own errors with all the object properties.  The following main procedure asks the user to open a Word file.  Notice how the error handler raises custom errors to deal with uncooperative user actions ;-)
  Sub Main()
Dim oFile As String
On Error GoTo Main_Error
oFile = PickFile
'Pick a Word file to open
Documents.Open (oFile)
Main_Exit:
Exit Sub
Main_Error:
Select Case Err.Number
    Case Is = vbObjectError + 1
        'Do nothing. User canceled
    Case Is = vbObjectError + 2
       
'User is having problems picking a Word file. Create a new file.
        Documents.Add
        MsgBox "A new document was created for you."
End Select
Resume Main_Exit
End Sub

Function PickFile() As String
Dim pFileName As String
Dim i As Long
For i = 1 To 3
    With Dialogs(wdDialogFileOpen)
    .Display
    pFileName = .Name
    End With
    If Len(pFileName) = 0 Then
        Err.Raise Number:=vbObjectError + 1, Description:="User cancelled file selection"
    ElseIf Not Right(pFileName, 5) = ".doc""" And i < 3 Then
        MsgBox "That is not a Word file. Try again.", vbOKOnly, "Wrong file type"
    ElseIf Not Right(pFileName, 5) = ".doc""" And i = 3 Then
        Err.Raise Number:=vbObjectError + 2, Description:="Slow user."
    ElseIf Right(pFileName, 5) = ".doc""" Then
        Exit For
    End If
Next i
PickFile = pFileName
End Function
I hope that you have found these examples informative and useful.  There is plenty of additional information available in the VBA Help menu that you can review to expand on the basics presented here.  You can download a document with all the above macros here:  Download

Looking for something else?

Google