Fix Word Crashes When Closing Documents via MACROBUTTON
A user in the Microsoft Tech Community recently posted a frustrating issue: “I created a template with a MACROBUTTON that allows users to close the document once they are finished. Every time the button is clicked, the macro runs, but Word immediately freezes or crashes to the desktop. It works fine when I run the code manually from the VBA editor, but fails when triggered from the document body.”
This is a classic “rug-pull” error in Word VBA. When you trigger a macro from a field (like MACROBUTTON), Word is still technically “processing” that field while the macro is running. If the macro tries to destroy the document object (the parent of the field) using ThisDocument.Close, Word loses its reference point mid-process and crashes.
The Minimal Working Example
Section titled “The Minimal Working Example”To fix this, you must tell Word to wait until it has finished processing the field interaction before attempting to close the file. We achieve this using the Application.OnTime method.
Tested on Microsoft Word for 365 (Version 2408) as of 2024.
The “Broken” Code (Do NOT use)
Section titled “The “Broken” Code (Do NOT use)”Sub CloseDoc() ' This will likely cause a crash when called from a MACROBUTTON ThisDocument.Close SaveChanges:=wdDoNotSaveChangesEnd SubThe Fixed Code (Use this)
Section titled “The Fixed Code (Use this)”Place this code in a standard Module (not in ThisDocument).
Sub TriggerClose() ' Schedule the actual close routine to run 1 second from now Application.OnTime When:=Now + TimeValue("00:00:01"), Name:="ActualCloseRoutine"End Sub
Sub ActualCloseRoutine() ' This runs after the MACROBUTTON has finished its cycle On Error Resume Next ThisDocument.Close SaveChanges:=wdPromptToSaveChangesEnd SubWhy This Works
Section titled “Why This Works”The Application.OnTime function acts as a “fire and forget” timer. By scheduling ActualCloseRoutine for one second in the future, the TriggerClose sub finishes instantly. Word completes its internal housekeeping for the MACROBUTTON field, and then, a second later, the closure happens safely in a new execution thread.
| Component | Role | Why it’s necessary |
|---|---|---|
TriggerClose |
The Entry Point | This is what your MACROBUTTON calls. It hands off the task. |
TimeValue("00:00:01") |
The Delay | Provides a 1-second buffer for the UI to settle. |
ActualCloseRoutine |
The Executor | Performs the actual Close command once the field is no longer “active.” |
On Error Resume Next |
Safety Net | Prevents errors if the user manually closes the doc during that 1-second gap. |
Step-by-Step Implementation
Section titled “Step-by-Step Implementation”- Open your Word document and press
Alt + F11to open the VBA Editor. - Go to Insert > Module.
- Copy and paste the Fixed Code provided above into the window.
- Return to your Word document.
- Press
Ctrl + F9to insert a new field. You will see curly braces:{ }. - Inside the braces, type:
MACROBUTTON TriggerClose Click Here to Close. - Press
F9to update the field. It will now display as “Click Here to Close.” - Double-click the text to test the fix.
Adapting to Your Workflow
Section titled “Adapting to Your Workflow”What if I want to save automatically without prompting?
Section titled “What if I want to save automatically without prompting?”Change the line in ActualCloseRoutine to:
ThisDocument.Close SaveChanges:=wdSaveChanges
This is useful for automated logs or form submissions where you don’t want the user to be interrupted by a “Do you want to save?” dialog.
Can I use this with a Ribbon button instead?
Section titled “Can I use this with a Ribbon button instead?”Interestingly, Ribbon buttons (XML-based) do not usually suffer from this specific crash because they operate on a different UI layer than Field Codes. However, using the OnTime method is still considered a “best practice” if you notice any instability when a macro’s final action is to kill its own host.
How do I handle multiple open documents?
Section titled “How do I handle multiple open documents?”If your macro is meant to close the active document (which might not be the one containing the code), use ActiveDocument.Close instead of ThisDocument.Close. ThisDocument always refers to the file where the VBA code is stored, whereas ActiveDocument refers to the file currently in focus.
Common Traps
Section titled “Common Traps”- Macro Security: Ensure that File > Options > Trust Center > Trust Center Settings > Macro Settings is set to “Disable all macros with notification” so you can enable the code when the doc opens.
- Double-Click vs Single-Click: By default,
MACROBUTTONrequires a double-click. If you want it to trigger on a single click, you must addOptions.ButtonFieldClicks = 1to aDocument_Open()procedure in theThisDocumentobject.