Excel VBA on Error

This guide treats “excel vba on error” 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. For “excel vba on error”, the reliable version is a short checking loop, not just the first command that appears to work. Run it on a deliberately small range first, watch how the affected cells change, and only then apply the same setup to the full sheet. 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 is what makes a workflow that saves repeating the same clicks every week useful in real work: repeatable, auditable, and not dependent on memory or luck.

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. If there is any chance you will reuse this, drop it into a small template tab right now: a labelled input area on the left and the formula beside it, checked once against the tool above. Next time the same question comes up, the answer is a single paste away instead of a rebuild from memory.

In Google Sheets

If you are in Google Sheets rather than Excel, the good news is that the formula shown here is identical and the workflow barely changes — menus sit across the top instead of in a ribbon, and a few function names differ slightly, but anything you build here moves across with little or no rework. Nothing on this page is behind a login: the tool runs entirely in your browser, the formula is shown in full with one-click copy, and the steps work the same on Windows and Mac. That is the whole promise here — the exact answer, a way to prove it on your own numbers, and just enough context to make it stick. Treat “excel vba on error” 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.