Excel VBA Error Handling

This guide treats “excel vba error handling” the way busy spreadsheet users actually want it: answer first, then the reasoning. It is written for Excel but calls out every place Google Sheets differs, and the platform toggle at the top switches all shortcuts between Windows and Mac so nothing here assumes the keyboard you are not on.

Exact answer

In Excel: Put On Error GoTo ErrHandler at the top of the Sub, Exit Sub before the label, and report Err.Number and Err.Description inside the handler.

VBA macro: Error Handling in VBA

Sub SafeDivide()
    Dim ws As Worksheet
    Dim result As Double
    On Error GoTo ErrHandler
    Set ws = ActiveSheet
    result = CDbl(ws.Range("A1").Value) / CDbl(ws.Range("A2").Value)
    MsgBox "Result: " & result, vbInformation
    Exit Sub
ErrHandler:
    MsgBox "Error " & Err.Number & ": " & Err.Description, vbCritical, "SafeDivide failed"
    Err.Clear
End Sub

The Exit Sub before the label is essential — without it, execution falls straight into the handler after a successful run and reports an error that never happened. Err.Number and Err.Description carry the details; 11 is division by zero and 13 is a type mismatch.

How to run this macro

  1. Press Alt + F11 to open the VBA editor.
  2. Insert > Module.
  3. Paste the code above.
  4. Press F5, or close the editor and run it from Developer > Macros.
  5. Save the file as .xlsm so the macro is kept.
Annotated stepsExcel
1

Put On Error GoTo ErrHandler near the top of the Sub, before the first line that could fail.

2

Write the normal logic underneath.

3

Add Exit Sub after the last normal statement so a successful run never enters the handler.

4

Add the label — ErrHandler: on its own line — and report Err.Number and Err.Description there.

5

For a deliberate probe, wrap only the risky line in On Error Resume Next and restore with On Error GoTo 0 immediately afterwards.

Ctrl+CthenCtrl+Shift+V+Cthen+Ctrl+VPaste values · WindowsMac

What this does

By default a runtime error stops a macro dead and shows the end user a debug dialog they cannot act on. Error handling replaces that with something deliberate. On Error GoTo Label redirects execution to a label in the same procedure when anything fails; the Err object then carries Number and Description so the handler can explain what happened. The structural rule people get wrong is the Exit Sub immediately before the label — without it, a successful run simply continues into the handler and reports a phantom error. On Error Resume Next is the other form: it ignores errors and moves to the next line, which is legitimate for exactly one pattern — attempting something that may fail, then checking Err.Number yourself — and is otherwise the most damaging habit in VBA, because it hides every subsequent failure too. Whenever you use it, restore normal behaviour with On Error GoTo 0 as soon as the risky line is past. Resume Next inside a handler continues after the offending line; Resume retries it, which loops forever unless something has changed. Keep the inputs visible and clearly labelled and the whole thing stays auditable — anyone who opens the file later, including you, can see at a glance exactly what feeds the result and change one assumption without hunting through the formula. Treat “excel vba error handling” as a small repeatable workflow rather than a one-off click you hope to remember next time. Use a small test block before the live file, so any surprise in the affected cells shows up while it is still harmless. When this is a ribbon command, the selection matters more than the button: confirm the range, apply the command, then spot-check the output before saving. That turns a workflow that saves repeating the same clicks every week into a method you can reuse, explain, and defend when the workbook leaves your screen.

A worked example

Sub SafeDivide() reads two cells and divides them. On live data that fails in at least two ways: A2 empty or zero gives error 11, division by zero, and text in either cell gives error 13, type mismatch. Without a handler the user sees a debug prompt naming a line of code they have never read. With one, they see which error occurred and why. The Exit Sub before ErrHandler is what keeps the success path out of the handler. The other common pattern is the deliberate probe: On Error Resume Next, Set ws = ThisWorkbook.Sheets("Summary"), On Error GoTo 0, then If ws Is Nothing Then create it. Here suppression is the point — asking for a sheet that may not exist — and the immediate On Error GoTo 0 is what stops the suppression leaking into the rest of the procedure. Error handling is what separates a macro that works on your machine from one that survives other people's data. The choice is not whether errors happen but who sees them: a debug dialog aimed at the author, or a message aimed at the person actually running it. One habit worth forming early: name the cells that hold your inputs, so the formula reads in plain language instead of a string of cell addresses. A reviewer — or you in three months — can then follow the logic without decoding what B7 and D2 were supposed to mean, which is most of what makes a sheet maintainable.

In Google Sheets

Google Sheets handles this almost identically to Excel. The formula syntax above is the same, and the menu lives under a slightly different label rather than a ribbon tab. Use the platform toggle at the top of the page to switch every keyboard shortcut between Windows and Mac, and expect at most cosmetic differences in naming. The aim was to get you unstuck fast and leave you a little more capable than a copy-paste would. The answer is at the top, the tool proves it, and the detail above shows why it holds — so the next time a colleague asks, you can answer without reaching for search. Treat “excel vba error handling” as a small building block rather than a chore. Once the inputs sit in their own cells and the formula reads from them, the same setup answers a dozen related questions with a tweak, and Excel keeps every dependent figure current as the data changes. The tool above is there so you can rehearse and verify before committing anything to a real workbook; the steps and worked example are there so the logic sticks. Get it right once and it stops costing you time — it starts saving it, every time the question comes back around.

Common mistakes

  • Forgetting Exit Sub before the handler label. The successful path runs straight into the error message, so every clean run reports a failure — usually error 0 with an empty description.
  • Leaving On Error Resume Next switched on for a whole procedure. It suppresses every later error too, so the macro finishes "successfully" having silently done nothing, which is far harder to diagnose than a crash.
  • Using Resume instead of Resume Next by reflex. Resume retries the line that failed; if nothing has changed, it fails again and the macro loops forever.
  • Writing a handler that only says "an error occurred". Err.Number and Err.Description cost nothing to include and are the difference between a report someone can act on and one they cannot.
  • Adding error handling while still developing. Suppressed errors hide the bugs you are trying to find — write the logic first, get it correct, and add the handler last.

Frequently asked questions

What is the difference between On Error GoTo and On Error Resume Next?

GoTo jumps to a labelled handler so you can react. Resume Next ignores the error and continues with the following line. Use GoTo for real handling; use Resume Next only around a single line you are deliberately probing.

How do I turn error handling back off?

On Error GoTo 0 restores the default behaviour for the rest of the procedure. It is what should follow every On Error Resume Next, ideally on the very next line.

How do I find out which error occurred?

Read Err.Number and Err.Description in the handler. Common ones: 9 subscript out of range, 11 division by zero, 13 type mismatch, 91 object variable not set, 1004 application-defined error.

Does an error handler in one Sub cover the Subs it calls?

Yes, if the called procedure has none of its own — the error propagates up to the nearest active handler. If the callee handles it, the caller never sees it.