Excel VBA Try Catch: Error Handling Explained

VBA & macros · Updated November 3, 2026

Excel VBA Try Catch: Error Handling Explained

Excel VBA does not have a native Try...Catch statement. To handle runtime errors, use On Error GoTo to send execution to a labeled handler, or use On Error Resume Next briefly for an operation whose failure you will check explicitly.

Does VBA Have Try Catch?

No. VBA uses an older error-handling model based on procedure-level instructions rather than the structured Try, Catch, and Finally blocks found in some other languages. The closest general-purpose equivalent to a catch block is a label in the same procedure that VBA jumps to after an error.

That difference matters when translating code examples from C#, Java, JavaScript, or Python. You cannot put a block of VBA inside a Try statement and add a Catch clause. Instead, you decide where an error should go, what information to record, and how to leave the procedure safely. The main tools are the On Error statement and the Err object.

Error handling is useful for expected runtime problems such as a missing workbook, an invalid value, or a file that cannot be opened. It is not a substitute for checking inputs or correcting a coding mistake. A handler that hides every error can make a macro appear to succeed while leaving incomplete results behind.

How On Error Works

An On Error instruction sets the response for errors that occur later in the current procedure. It does not check whether a line will fail, and it does not automatically repair the problem. The three common forms have different purposes:

  • On Error GoTo HandlerName sends execution to a label in the same procedure when a runtime error occurs. This is the usual pattern for handling an unexpected failure and reporting it.
  • On Error Resume Next tells VBA to continue with the next statement after a statement fails. Use it only around a narrow operation, then inspect the result or Err.
  • On Error GoTo 0 disables the current procedure’s enabled error handler. It does not mean “go to line zero,” and it is not the same as clearing the error information.

The Err object describes the most recent runtime error. Its commonly used properties include Number, Description, and Source. Capture the number and description as soon as you enter a handler if later cleanup operations might themselves fail and replace the current error details.

A Basic Error Handler

Place the handler label after the normal work, and use Exit Sub before the label. That prevents a successful run from falling through into the error-handling code. The following example reads a value and reports a conversion or worksheet-related runtime failure:

Sub ReadInputValue()
    Dim amount As Double

    On Error GoTo ErrorHandler

    amount = CDbl(ThisWorkbook.Worksheets("Input").Range("B2").Value)
    Debug.Print amount
    Exit Sub

ErrorHandler:
    MsgBox "Could not read the input: " & Err.Description, vbExclamation
End Sub

Here, On Error GoTo ErrorHandler establishes the handler before the operation that may fail. If the value in cell B2 cannot be converted to a number, execution jumps to ErrorHandler. If no error occurs, Exit Sub ends the procedure before VBA reaches that label.

This is deliberately a small example, not a complete validation strategy. If a blank cell or text value is an ordinary possibility, check the cell’s content and present a useful message before converting it. Reserve error handling for failures that remain possible after reasonable validation.

Resume, Resume Next, and Labels

VBA’s Resume statements control what happens after a handler has dealt with an error. They are different from the instruction On Error Resume Next, despite the similar wording:

  • Resume returns to the statement that caused the error. Use it only if the handler has corrected the condition and retrying that statement makes sense.
  • Resume Next, when used as a statement inside an error handler, continues at the statement immediately after the one that failed.
  • Resume SomeLabel continues at a named line in the same procedure, which can be useful for a deliberate recovery path.

For example, if a handler merely displays an error message, it usually should not resume the failed operation. Continuing as though the operation succeeded could produce incorrect output. A simple procedure can end after reporting the error, or clean up and then exit. Choose a resume route only when the macro has a defined, safe way to continue.

Also remember that a label belongs to its procedure. A handler in one procedure does not automatically catch an error in every other procedure in the workbook. If a called procedure does not handle an error, the error can pass back to its caller; the caller can then handle it, or VBA can stop with an unhandled error.

Using Resume Next for One Expected Operation

On Error Resume Next can be appropriate when a particular failure is expected and the next step checks whether it happened. For example, a macro may look for a worksheet that is optional. Keep the suppressed-error area short, then turn normal handling back on immediately:

Sub CheckForSummarySheet()
    Dim summarySheet As Worksheet

    On Error Resume Next
    Set summarySheet = ThisWorkbook.Worksheets("Summary")
    On Error GoTo 0

    If summarySheet Is Nothing Then
        MsgBox "The Summary sheet is not present."
    Else
        MsgBox "The Summary sheet is available."
    End If
End Sub

The code checks the object reference rather than assuming that the lookup worked. The broad mistake is leaving On Error Resume Next active for a long section of a macro. In that state, unrelated failures may be ignored too, and later statements can run with missing objects or incomplete values.

When you use this pattern for an operation where the error number matters, inspect Err.Number immediately after the operation and before another operation can change the error information. Use Err.Clear when you need to clear the stored error details before a later check. On Error GoTo 0 turns off the current error-handling mode; it is not a general-purpose replacement for checking whether the operation worked.

Cleanup When a Macro Fails

Many procedures need to release or restore something even when an error occurs: a workbook opened by the macro, a file handle, or an application setting temporarily changed for performance. VBA has no Finally block that runs automatically. Use a shared cleanup section or a handler that performs cleanup before it exits.

This example opens an input workbook and makes sure it is closed if a later operation fails. Save a copy of the workbook before running a macro: VBA changes cannot be undone with Ctrl+Z.

Sub OpenAndProcessInput()
    Dim sourceWb As Workbook
    Dim savedNumber As Long
    Dim savedDescription As String

    On Error GoTo ErrorHandler

    Set sourceWb = Workbooks.Open( _
        Filename:=ThisWorkbook.Path & Application.PathSeparator & "input.xlsx", _
        ReadOnly:=True)

    ' Replace this comment with the required processing.
    sourceWb.Close SaveChanges:=False
    Set sourceWb = Nothing
    Exit Sub

ErrorHandler:
    savedNumber = Err.Number
    savedDescription = Err.Description

    On Error Resume Next
    If Not sourceWb Is Nothing Then sourceWb.Close SaveChanges:=False
    On Error GoTo 0

    MsgBox "The operation failed (" & savedNumber & "): " & _
        savedDescription, vbExclamation
End Sub

The handler saves the original error details before attempting to close the workbook. Cleanup is performed under On Error Resume Next so a second failure during closing does not prevent the message from appearing. That suppression is limited to cleanup, and the original error number and description are retained in separate variables.

Real procedures may need more careful cleanup. For example, if code changed Application.ScreenUpdating or Application.EnableEvents, store each original setting and restore it on both success and failure. Do not blindly set a setting to a presumed default if it may have been off before the macro began.

Common Mistakes and How to Avoid Them

  • Forgetting Exit Sub before the handler: A successful procedure may run straight into the handler label. Add an exit statement before the label, or structure the routine so normal and error paths are clearly separated.
  • Ignoring errors across the whole macro: On Error Resume Next can conceal a failed assignment or missing object. Limit it to the statement or small operation you expect to fail, and check the outcome.
  • Reporting an error after overwriting it: A cleanup failure may change the contents of Err. Save the original number, description, and, when useful, source before cleanup.
  • Confusing compile errors with runtime errors: A misspelled variable or malformed statement is generally a compile-time problem. An error handler is mainly for runtime failures while the procedure is executing; it cannot make invalid code compile.
  • Showing a vague message: “Something went wrong” gives little help. Include the operation or context, and record useful details such as Err.Number and Err.Description. Avoid exposing sensitive information in messages intended for ordinary users.
  • Assuming a handler fixes the workbook: Handling an error only controls what the macro does next. It does not roll back cell changes already made, restore a deleted sheet, or undo a partially completed import.

Testing and Debugging Error Handling

Test both the success path and realistic failure paths. For a file-opening routine, try a valid file and a missing or inaccessible file. For a worksheet routine, try both a workbook that has the expected sheet and one that does not. Confirm that cleanup happens, that messages identify the problem, and that the macro does not leave Excel settings altered.

In the Visual Basic Editor, F8 steps through code one statement at a time on Windows; on a Mac keyboard, the function-key setting may mean you need Fn+F8. A breakpoint lets you pause before a risky operation and inspect variables. In the editor, Tools > Options > General includes the Error Trapping setting. For normal development, “Break on Unhandled Errors” is generally more useful than having the editor break on every error that code is designed to handle. Class modules can have different break behavior when the related option is selected.

During debugging, avoid adding a blanket handler just to make a macro stop showing errors. That can hide the line and condition that need fixing. A useful handler should make failure understandable, preserve necessary information, and leave the workbook in a known state. For macros that change important data, work on a copy until the procedure has been checked against both ordinary and failure cases.

Frequently Asked Questions

What is the VBA equivalent of try/catch?
Use On Error GoTo LabelName to send a runtime error to a handler label in the current procedure. VBA does not provide native Try and Catch blocks.

Can I use On Error Resume Next for the whole macro?
You can, but it is usually a poor choice because unrelated errors may be silently ignored. Apply it narrowly, check the result or Err, and then restore normal error handling.

How do I get the error message in VBA?
Inside the handler, read Err.Description for the description and Err.Number for the numeric error code. Save them before cleanup if later statements could cause another error.

Does VBA have a finally block?
No. Put necessary cleanup on both normal and error paths, or route both paths through a shared cleanup section. Restore settings and close resources explicitly.

Can an error handler catch errors in another Sub?
A handler is associated with the procedure where it is declared. An unhandled error in a called procedure can pass back to its caller, where a caller-level handler may handle it; otherwise, VBA reports an unhandled error.

Related

Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.

More in VBA & macros

Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources

Spotted an error in this guide? Let us know.