TL;DR —
Application.EnableEvents = Falsestops your macro's writes from triggering event handlers —Worksheet_Change,Workbook_Open, and the rest. Its main job is breaking the loop where aWorksheet_Changehandler writes a cell, which firesWorksheet_Changeagain, forever. It is a correctness switch, not a speed switch. And it is the one you most need an error handler for, becauseEnableEventsis application-level and does not reset itself — crash with it off and every event in Excel stays dead until you restart:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("B:B")) Is Nothing Then Exit Sub
Application.EnableEvents = False ' our write below must NOT re-fire this handler
On Error GoTo CleanExit
Target.Offset(0, 1).Value = Now ' write - would otherwise trigger Worksheet_Change again
CleanExit:
Application.EnableEvents = True ' restore, even after an error, or events stay dead app-wide
End Sub
The other two switches in this cluster are about speed — ScreenUpdating
stops repaints, Calculation stops recalcs. EnableEvents is different. It is
about correctness: stopping your own writes from ricocheting through the event handlers that watch
the workbook. This guide is built on one idea — EnableEvents is the switch you flip so your changes
don't trigger the code that reacts to changes. You flip it for control, not for speed — and because a
crash leaves it off for the whole application, restoring it is not optional.
What you'll learn
- The mental model — writing a cell can fire event handlers, which can write more cells
- The classic bug — a
Worksheet_Changehandler that triggers itself into an infinite loop - The rule that matters most —
EnableEventsis app-level and does not auto-reset - Why "my buttons stopped working" is almost always a stranded
EnableEvents = False - The
CleanExitrestore, and why it matters more here than for the speed switches - How this pairs with Worksheet_Change and Intersect
The mental model: writes can fire events
Excel workbooks can carry event handlers — procedures that run automatically when something
happens. Worksheet_Change runs when a cell changes; Workbook_Open runs when the file opens;
Worksheet_SelectionChange runs when the selection moves. These are how a workbook reacts to the user.
The catch: your macro's actions count as "something happening" too. When your code writes to a
cell, that is a change, so Excel fires Worksheet_Change — even though it was your macro, not the
user, that made the edit. Usually you don't want your own automated writes to wake up the handlers
that were written to respond to a human.
Application.EnableEvents = False turns off that firing. While it is False, changes still happen,
but Excel does not run any event handlers in response. Set it back to True and events resume.
The classic bug: a handler that triggers itself
The failure this switch exists to prevent is the self-triggering Worksheet_Change. Consider a
handler that stamps the time whenever column B is edited — by writing to column C:
' BROKEN - infinite recursion:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("B:B")) Is Nothing Then Exit Sub
Target.Offset(0, 1).Value = Now ' writing to C is itself a change...
End Sub ' ...which fires Worksheet_Change again -> again -> crash
Writing to C is a change, which fires Worksheet_Change, which writes to C again, which fires it
again. In practice you get a stack overflow (error 28) or Excel wedged in a loop. The fix is to wrap
the write so it does not re-enter the handler:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("B:B")) Is Nothing Then Exit Sub
Application.EnableEvents = False ' the write below will not re-fire this
On Error GoTo CleanExit
Target.Offset(0, 1).Value = Now
CleanExit:
Application.EnableEvents = True
End Sub
The Intersect guard and the EnableEvents guard are siblings — a
Worksheet_Change handler that writes anything back to the sheet needs
both, one to scope the trigger and one to stop the recursion.
The rule that matters most: it does not reset itself
This is where EnableEvents earns its reputation as the switch you must handle carefully. Unlike
ScreenUpdating, which Excel sometimes restores when a macro ends,
EnableEvents never resets on its own. And it is an Application property, not a per-workbook
one — so it applies to every open workbook at once.
Put those two facts together and you get the nastiest leftover state in VBA. If a macro sets
EnableEvents = False and then errors before restoring it, events are now off everywhere — in
that workbook and every other one open — and they stay off until the user closes and reopens Excel.
No error message, no visual cue. The workbook just quietly stops reacting.
"My buttons stopped working"
That leftover state has a signature complaint: "my macro buttons / my dropdowns / my automatic
formatting stopped working, and I didn't change anything." Nine times out of ten, some earlier macro
crashed with EnableEvents = False still in effect, and now Worksheet_Change, Workbook_Open, and
every other handler are silently disabled.
The one-line rescue is to run this from the Immediate window (or any macro):
Application.EnableEvents = True
But the real fix is upstream: never set EnableEvents = False without an error handler that
restores it. Because the damage is application-wide and invisible, the CleanExit discipline that is
merely good practice for the speed switches is genuinely mandatory here.
Sub BulkImport()
Application.EnableEvents = False
On Error GoTo CleanExit
' ... writes that would otherwise trigger Worksheet_Change on every row ...
CleanExit:
Application.EnableEvents = True ' non-negotiable
End Sub
When to use it — and when not to
Reach for EnableEvents = False when your code writes to cells that have event handlers watching
them, or during a bulk operation where you don't want per-row events firing hundreds of times. Do
not reach for it as a general speed trick — if the sheet has no relevant event handlers, disabling
events changes nothing, and you have taken on the restore risk for no benefit. It is a targeted
correctness tool: use it exactly where your writes would otherwise ricochet, and leave it alone
elsewhere.
How ExcelMaster helps
EnableEvents is deceptively risky: it is application-wide, it never resets, and a crash with it off
silently kills every event in Excel until a restart. Using it safely means pairing it with an
Intersect guard inside event handlers, wrapping bulk writes so they don't fire per-row events, and
restoring it in a CleanExit handler every single time.
ExcelMaster builds the whole
safe pattern for you. Ask for "stamp the time in column C when column B changes," and it writes the
Worksheet_Change handler with the Intersect guard, the EnableEvents = False toggle around the
write, and the CleanExit restore — so the handler never loops on itself and never strands events for
the rest of the session. You get workbook automation that reacts correctly, not one that quietly
breaks after the first error.
Frequently asked questions
What does Application.EnableEvents = False do in VBA?
It stops Excel from running event handlers in response to changes your code makes. While it is
False, actions like writing to a cell still happen, but they do not trigger Worksheet_Change,
Workbook_SheetChange, or other event procedures. Set it back to True to let events fire again.
How do I stop a Worksheet_Change event from triggering itself?
Set Application.EnableEvents = False before your handler writes to any cell, then restore it to
True afterward. Without it, the handler's own write is a change that fires Worksheet_Change again,
looping until Excel raises a stack-overflow error. Combine it with an Intersect guard so the handler
only runs for the cells you care about.
Why did all my Excel events stop working?
Because some macro set Application.EnableEvents = False and never restored it — usually it errored
before the restore line. EnableEvents is application-level and does not reset on its own, so events
stay disabled for every open workbook until you set Application.EnableEvents = True or restart Excel.
Does EnableEvents reset automatically when the macro ends?
No. Unlike ScreenUpdating, which Excel may restore on its own, EnableEvents stays exactly where you
left it — across macros and even after the macro ends — until you set it back or close Excel. That is
why you must restore it in an error handler rather than relying on any automatic reset.
Is EnableEvents a speed optimization like ScreenUpdating?
Not really. ScreenUpdating and Calculation are about speed; EnableEvents is about correctness —
stopping your writes from triggering the handlers that watch the workbook. It can avoid running event
code hundreds of times during a bulk write, but its primary purpose is preventing loops and unwanted
reactions, not raw speed.
Tested in
Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-08-17.
Related guides: VBA ScreenUpdating · VBA Calculation · VBA Worksheet_Change · VBA Intersect · VBA On Error
