Rob,
To supplement what Gonzalo just said (and to amplify his earlier post):
If you have set
or you have not run an On Error line in the procedure, an error will terminate the current routine, and go back to the calling routine in an error state.
If you have set
Code:
On Error Resume Next
if an error transpires your code will continue to run as if nothing has happened, with the exception that the Error object will have its properties set to reflect the error that has happened. This is generally a really bad idea. A lot of people do it, but it is rife with potential bombs.
If you set
Code:
On Error GoTo <Label_Within_Routine>
and an error transpires, code execution will move immediately to the first executable line following the named label.
Once there, you can re-raise an error, causing program flow to leave the routine, returning to the calling routine in an error state, clear the error to just ignore it (Err.Clear), or Resume in 1 of 3 ways.
Resume Next will clear the error, and send the program flow to the first executable line following the line that caused the error. You can use this to âstep overâ the offending line. Often I will have a line that might raise an error, followed by a line that tests a Boolean that the error handler sets to indicate what the error was:
Code:
On Error GoTo Er
Dim a() As Integer
Dim NoElems As Boolean ' Initializes to False
a(0) = 0
If NoElems = True Then
NoElems = False
ReDim a(0)
a(0) = 0
End If
...
Rs:
Exit Sub/Function
Er:
If Err.Number = <Whatever 'subscript out of range is> Then
NoElems = True
Resume Next
End If
' Handle other errors here
Resume (with no argument) clears the error, then re-runs the line that caused the error in the 1st place. You can use this for cases where you can correct the cause of the error and try again. One example might be that you tried to .Open a recordset that has not yet been instantiated. So you can add Set RecSet = New ADODB.RecordSet to the error handler, then Resume. Since the recordset now is instantiated, the line should run without error.
Finally, you can Resume <Label>, such as
for my example above.
I usually have Resume Rs as the last line to run in my error handlers, but I follow that with a Resume:
Code:
...
Resume Rs
Resume
End Sub
The last Resume never gets run, because the Resume Rs before it shifts the program flow before the Resume is ever reached.
But when debugging, if I make the code stop in the error handler, I can set the Resume as the next statement to run, then single step, and the execution point will jump to the line that caused the error, allowing me to examine the situation at that point. (Hover over variables to see what their value is, try running statements in the immediate window, etc.)
As Gonzalo has suggested, you can use this to find just exactly which line is raising the error.
Before single-stepping on the Resume, you can type
in the immediate window to see what the problem is. (Once you run Resume, the Err object will be cleared.)
Or you can
Code:
errors:
Stop
Debug.Print Err.Description
Resume