Even without an Error, the code for "Line3:" still gets run on On Error GoTo Line3

Viewed 85

Example Code:

On Error GoTo Line3

More code

Line3:
    Some code
    Some code

More code

Even when there is no error, the "some code" underneath Line3 still gets run even though I don't want it to run. Otherwise when there is an error, Line3 gets run appropriately (skipping code that comes before it like it should).

3 Answers

Your code runs as it should. Code dealing with errors should be written outside of the main procedure, keeping in mind that your code should also try and spot potential errors and deal with them before they cause an error.

At the moment your error isn't being cleared when you jump to it, and because it's in the main body of code it's executed when your first set of More Code is finished and it reached the Line3 label.

Sub Test1()
    'Ignore the error.
    'MsgBox won't appear, but code won't know an error occured.
    'MsgBox says all's good anyway, even though the error is still present.
    Dim Rng As Range
    On Error GoTo SkipLineWithError
    MsgBox Rng.Address
SkipLineWithError:
    MsgBox "All good, error number is " & Err.Number
End Sub 

A better way is to try and catch the error before it happens:

Sub Test2()

    'Checks that Rng won't throw an error if referenced.
    'Code has dealt with the error and says all's good.
    Dim Rng As Range
    If Not Rng Is Nothing Then
        MsgBox Rng.Address
    Else
        MsgBox "Range not set"
    End If
    MsgBox "All good, error number is " & Err.Number

End Sub

Sometimes, errors do occur though and they need to be dealt with properly. For this you jump out of the main procedure, deal with the error and jump back in again.
With this code notice the Exit Sub - the code between Exit Sub and End Sub is where your error handling goes. The main body of code ends when it reaches Exit Sub.
Resume tells your code where to jump back to - on its own it jumps back to the line that caused the error, Resume Next is the line after the error and Resume <label> jumps back to a label you've entered such as Resume Line3

Sub Test3()
    Dim Rng As Range

    On Error GoTo ErrorHandler
    MsgBox Rng.Address
    MsgBox "All good, error number is " & Err.Number
    
TidyExit:
    'Close connections, general tidy up before ending procedure.
    
Exit Sub
ErrorHandler:
    Select Case Err.Number
        Case 91 'Deal with the error if it happens.
                'For this we'll give Rng a default address.
            Set Rng = Sheet1.Range("A1")
            Resume
        Case Else
            MsgBox "Error couldn't be handled... display an error message."
            Resume TidyExit 'Jump to end of main body of code.
    End Select

End Sub

Edit: Have updated code based on comment by @VBasic2008. Was being lazy with my first code and missed a key point.

I've barely scraped the surface here, the links below should help.
on-error-statement
vba-error-handling

Using Gotos to manage execution paths is almost always a poor design choice. You could consider the following approach that does not rely so heavily on Goto labels. It is easier to see the intended logic flow (and error handling) without having to visually parse any Goto statements.

Sub Example()
    If Not TryMorecode1() Then
        Somecode1
        Somecode2
    End If

    Morecode2
End Sub

Private Function TryMorecode1() As Boolean
    'catch errors locally within this function
    'return False if an error is generated
End Function

Private Sub Morecode2()
End Sub

Private Sub Somecode1()
End Sub

Private Sub Somecode2()
End Sub

The code will still run, it's just a label you can point the execution to if need be.

Try this to avoid your problem but without knowing your exact requirement, you’ll likely need to tweak the code structure to suit your needs.

My suggestion would be to put Line3 at the bottom, not in the middle of the routine. That way you just do a clean up and then get out. It tends to make more sense from a readability perspective. Of course, you should only do that if it makes sense to get out after the error occurs.

    On Error GoTo Line3

    More code

    Goto Line4

Line3:
    Some code
    Some code

Line4:
     On Error GoTo 0

     More code

The trick with GoTo statements (if you intend to use them) is to use them sparingly.

Related