🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA End in Excel — End vs End Sub vs Exit Sub vs Stop

|

VBA End in Excel — End vs End Sub vs Exit Sub vs Stop

TL;DR — The bare End statement stops the whole macro immediately: it wipes every variable (including module-level and Static), closes UserForms, and skips any cleanup you had queued. That is a different thing from End Sub (which just marks where a Sub finishes), from Exit Sub (which returns from one procedure and lets the program continue), and from Stop (which pauses in the debugger). You almost never want the bare End. To leave a procedure, use Exit Sub.

Sub WhyEndIsDangerous()
    Application.ScreenUpdating = False
    ' ... work ...
    If somethingWrong Then End       ' stops NOW - ScreenUpdating is left False!
    ' ... more work ...
    Application.ScreenUpdating = True ' this cleanup line never runs after End
End Sub

Four constructs in VBA contain the word end, and confusing them causes real bugs. Only one of them — the bare End — actually stops your program, and it does so in the most heavy-handed way possible. The others simply close a block or return from a procedure. Knowing which is which is the difference between a macro that cleans up after itself and one that leaves Excel in a half-configured state.

What you'll learn

  • What the bare End statement actually does — and how much state it destroys
  • Why End, End Sub, End If, Exit Sub, and Stop are five different things
  • The real bug: how End skips your cleanup and leaves ScreenUpdating or events off
  • Why End wipes module-level and Static variables that a normal return would keep
  • When (if ever) End is the right call, and what to use instead
  • How Stop differs from End — pausing to debug versus terminating

The mental model: End is the plug, not the door

Line up the four look-alikes by how much they stop:

End If      ' closes an If block          - stops nothing; a structural marker
End Sub     ' marks the end of a Sub       - the procedure ends here anyway
Exit Sub    ' returns from THIS procedure  - the program keeps running
End         ' terminates the ENTIRE macro  - everything stops, nothing cleans up

End Sub and End If are punctuation: they tell VBA where a block finishes. They do not "run." Exit Sub is a door out of one procedure — you leave, the caller continues, your cleanup runs. The bare End is the plug: it halts the whole call stack at once, as if you had hit the Reset button in the editor. Everything downstream — the caller, the caller's caller, the cleanup line you wrote two lines below — is simply abandoned. That single distinction, door versus plug, is the whole page.

What the bare End statement actually destroys

End does far more than "stop the code." When it fires, VBA tears down the entire run-time state of your project:

  • All variables are reset — local, module-level, and Static variables lose their values.
  • All open UserForms are unloaded, without their QueryClose or cleanup events running normally.
  • The call stack is discarded — no procedure on it gets to finish or run its remaining lines.
  • On Error handlers are cleared, and the VBA project's run-time state resets as if freshly started.

What it does not do is undo anything already done to the workbook or to Application. That is the crux of the danger. If you turned Application.ScreenUpdating = False at the top and hit End in the middle, screen updating stays off — because the line that would have turned it back on is one of the many lines End just abandoned.

The real bug: End skips your cleanup

Most non-trivial macros set some Excel state up front and restore it at the end:

Sub Report()
    Application.ScreenUpdating = False
    Application.EnableEvents = False

    If Not FileExists() Then End    ' <-- the trap

    ' ... build the report ...

    Application.EnableEvents = True     ' never reached if End fired
    Application.ScreenUpdating = True   ' never reached if End fired
End Sub

If FileExists returns False, that End stops everything on the spot. EnableEvents and ScreenUpdating are left False, so the user's Excel now silently ignores worksheet events and does not repaint — a "frozen Excel" support ticket that looks like a crash but is really just skipped cleanup. The fix is to return, not terminate: replace End with Exit Sub, and put the restore lines where they always run (a single exit path, or an error handler). Exit Sub leaves the procedure but lets your cleanup — and the rest of the program — run.

End wipes Static and module-level variables

There is a subtler consequence worth its own note. A normal return (Exit Sub, or just reaching End Sub) leaves module-level and Static variables intact — that is the whole point of them, to persist across calls. The bare End throws them away along with everything else:

' Module level
Dim gRunCount As Long

Sub Tick()
    gRunCount = gRunCount + 1     ' meant to accumulate across runs
    If gRunCount > 100 Then End   ' End resets gRunCount back to 0!
End Sub

If any part of your design relies on state surviving between macro runs — a counter, a cached object, a loaded configuration — a stray End silently resets it, and the bug shows up much later as "the count keeps starting over." One more reason the bare End should be rare and deliberate.

Stop is not End: pause to debug, do not terminate

Stop looks related but does the opposite of terminate. It suspends execution and drops you into the VBA editor at that line, in break mode, with every variable still alive so you can inspect them — exactly like a breakpoint you wrote into the code:

Sub Investigate()
    Dim total As Double
    total = ComputeTotal()
    Stop                     ' pause here in the editor; total is still readable
    Range("A1").Value = total
End Sub

Use Stop while debugging and remove it before you ship (unlike an F9 breakpoint, Stop lives in the source, so a forgotten one will halt a user's macro in the editor). End terminates; Stop pauses. Neither is something you want firing in code your users run — for observing a running macro without halting it, see VBA Debug.Print.

When is End ever the right call?

Rarely, and always deliberately. The honest use cases are narrow: a catastrophic, unrecoverable condition in a standalone tool where you would rather stop everything than risk continuing with bad state, or tearing down a modeless UserForm-driven app where you genuinely want to reset the whole project. Even then, prefer to reach a single clean exit — restore Application settings, close what you opened — and then stop. In day-to-day macros, the answer to "how do I stop here?" is Exit Sub (leave this procedure) or restructuring so the code reaches End Sub on its own. If you are typing the bare End, pause and make sure you really mean terminate everything, skip all cleanup.

How ExcelMaster helps

The bare End is a small word with an outsized blast radius, and its damage is invisible until a user reports a "frozen" Excel that is really just ScreenUpdating left off. The mistakes are using End when you meant Exit Sub, and leaving a Stop in shipped code.

ExcelMaster writes procedures that leave through a single clean exit: Exit Sub to return, restore lines that always run, and no stray End or Stop in code your users touch. When a macro needs to bail out early, it does so without leaving Excel half-configured. You keep the workbook and the code.

Frequently asked questions

What does the End statement do in VBA?

The bare End statement immediately terminates the entire macro. It resets all variables (including module-level and Static), unloads open UserForms, discards the call stack, and clears On Error handlers — but it does not undo changes already made to the workbook or to Application, so any cleanup you had queued is skipped. To leave a procedure without this, use Exit Sub.

What is the difference between End and End Sub?

End Sub simply marks where a Sub procedure finishes — it is a structural marker, and the procedure would end there anyway. The bare End, written on its own, terminates the whole program on the spot, wherever it appears. End Sub closes a block; End stops everything.

Should I use End to stop a macro?

Usually no. To leave the current procedure, use Exit Sub, which returns to the caller and lets your cleanup run. The bare End skips all cleanup and can leave ScreenUpdating off or events disabled, producing an Excel that looks frozen. Reserve End for rare, deliberate, unrecoverable situations.

What is the difference between End and Stop?

End terminates the macro and clears its state. Stop pauses execution and drops you into the VBA editor in break mode, with all variables still alive, so you can debug — like a breakpoint written into the code. Remove Stop before shipping, because unlike an F9 breakpoint it lives in the source and will halt a user's macro.

Why is ScreenUpdating still off after my macro ran?

Most likely a bare End (or an unhandled error) stopped the macro before the line that sets Application.ScreenUpdating = True back on. Because End skips remaining code, the restore never ran. Replace End with Exit Sub and put your restore lines on a single exit path or in an error handler so they always execute.

Tested in

Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-09-24.

Related guides: VBA Exit For · VBA GoTo · VBA On Error · VBA Debug.Print · VBA Sub