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

VBA Close Workbook in Excel — SaveChanges, the Prompt That Hangs Your Macro, and Closing Without Saving

|

VBA Close Workbook in Excel — SaveChanges, the Prompt That Hangs Your Macro, and Closing Without Saving

TL;DRwb.Close on a workbook with unsaved changes shows the modal "Do you want to save your changes?" dialog — which freezes an unattended macro forever. Answer it in code with the SaveChanges argument:

Sub CloseWithoutPrompt()
    Dim wb As Workbook
    Set wb = Workbooks.Open("C:\Reports\March.xlsx")
    ' ... read what you need ...
    wb.Close SaveChanges:=False    ' answer the prompt in code - no dialog, no hang
    Set wb = Nothing               ' the reference is dead after Close
End Sub

Closing is where a batch macro that ran perfectly all night is found the next morning still stuck on a dialog box, having processed one file out of two hundred. wb.Close does not just shut a workbook — it asks a question, and if you do not answer it in code, Excel asks the user, and the user is not there. This guide is built on that one idea: SaveChanges is your answer, and every close bug is a version of forgetting to give it.

What you'll learn

  • The mental model — Close asks "save changes?"; the SaveChanges argument is your answer in code
  • The number-one hang — closing a dirty workbook with no SaveChanges freezes an unattended macro
  • The mirror danger — SaveChanges:=False discards silently, so decide deliberately
  • Why the object variable is dead the instant you close, and reading it errors
  • wb.Close (one workbook) vs Application.Quit (all of Excel), and the invisible EXCEL.EXE trap
  • Why close-with-save inherits every Save trap

The mental model: Close asks a question — answer it in code

When a workbook has unsaved changes, wb.Close cannot just close it — Excel does not know whether you want those changes kept. So it does what it does for a human: it pops the "Do you want to save your changes?" dialog and waits. That is fine when a person is sitting there. In a macro, you are the one who has to answer, and you answer with the SaveChanges argument:

wb.Close SaveChanges:=False    ' close and DISCARD unsaved changes
wb.Close SaveChanges:=True     ' SAVE first, then close
wb.Close                       ' no answer - Excel asks the USER (the prompt)

Give the answer in code and the dialog never appears. Omit it on a dirty book and you are back to the prompt.

The number-one hang: no SaveChanges on a dirty workbook

This is the failure behind "my scheduled macro never finished." The macro opens a file, changes something — even a recalculation or a Worksheet_Change handler marks the workbook dirty — and then:

wb.Close      ' dirty book, no SaveChanges -> "save changes?" dialog -> hangs forever

There is no one at the keyboard to click Yes or No, so the macro sits on that modal dialog indefinitely. The whole batch stalls behind it. The fix is to always pass SaveChanges on any Close that might run unattended:

wb.Close SaveChanges:=False    ' read-only processing: discard, never prompt

If you remember one line from this page, make it wb.Close SaveChanges:=False for anything you only read.

The mirror danger: False discards silently

SaveChanges:=False is the cure for the hang, and it is also its own trap. It throws away unsaved changes with no undo and no confirmation. If the macro actually did work you meant to keep, SaveChanges:=False deletes it silently. So decide on purpose:

  • Only read the file? wb.Close SaveChanges:=False — nothing to keep, never prompt.
  • Wrote results you want kept? wb.Close SaveChanges:=True — or wb.Save first, then wb.Close SaveChanges:=False, which is clearer because the save and the close are separate, visible steps.

The prompt exists to stop a human from losing work. When you suppress it with an argument, you take on that responsibility.

The reference is dead after Close

Once wb.Close runs, the workbook is gone from memory and the variable wb points at nothing. Touching it throws an error:

wb.Close SaveChanges:=False
MsgBox wb.Name          ' ERROR - wb no longer refers to an open workbook

So read everything you need before you close, and set the variable to Nothing afterward to make the intent explicit:

Dim finalName As String
finalName = wb.Name              ' capture BEFORE closing
wb.Close SaveChanges:=False
Set wb = Nothing                 ' the reference is dead; say so
MsgBox "Closed " & finalName

Close a workbook vs quit Excel — and the invisible EXCEL.EXE

wb.Close closes one workbook. Application.Quit closes Excel itself. They are not interchangeable, and two edge cases bite:

  • ThisWorkbook.Close closes the workbook whose macro is running. Any code after that line may not execute. Close other workbooks from a macro; close your own last, or not at all.
  • Closing the last workbook can leave an invisible EXCEL.EXE running. If your code still holds a reference to an Application or Workbook object when the last window closes, Excel cannot fully shut down and lingers as a ghost process in Task Manager. Release your references (Set wb = Nothing, Set xlApp = Nothing) so the process can exit. This is the classic bug behind "Excel keeps running after my macro ends."

Close-with-save inherits every Save trap

wb.Close SaveChanges:=True runs a Save on the way out — so it inherits every trap from VBA Save Workbook:

  • On a never-saved book, close-with-save has no path and falls back to the Save As dialog (hangs). Give it a path with SaveAs first, or close with SaveChanges:=False if you do not need it kept.
  • On a macro workbook saved with the wrong FileFormat, close-with-save can re-raise the macro-stripping warning. If code matters, the file is .xlsm.

When in doubt, split the steps: wb.Save (or wb.SaveAs path, format) on its own line, then wb.Close SaveChanges:=False. Two visible operations beat one that silently does both.

The honest verdict: the batch-loop pattern

Everything above collapses into one reliable shape. In a folder loop, open and close inside the loop so you never accumulate open workbooks holding file locks:

Dim name As String
name = Dir("C:\Reports\*.xlsx")
Do While name <> ""
    Dim wb As Workbook
    Set wb = Workbooks.Open("C:\Reports\" & name)
    ' ... read the totals ...
    wb.Close SaveChanges:=False       ' answer in code every iteration
    Set wb = Nothing
    name = Dir                        ' next file
Loop

SaveChanges:=False is the default for read-only processing; SaveChanges:=True when you wrote results. Never rely on the prompt, always answer it, read before you close, and release the reference. Do that and the close step — the one that quietly stalls unattended jobs — becomes the boring, reliable end of every file you open.

How ExcelMaster helps

The close step is deceptively dangerous: forget SaveChanges and a scheduled macro hangs on a dialog; pass False when you meant True and finished work vanishes; hold a stray reference and Excel lingers as a ghost process. These are the bugs that only show up at 3 a.m. when no one is watching.

ExcelMaster writes the close the way a careful automation engineer would. Describe the job — "process every file in this folder and close each without saving" — and it opens with Set wb = Workbooks.Open(...), reads what it needs before closing, passes an explicit SaveChanges on every wb.Close, releases the reference with Set wb = Nothing, and never leaves a workbook open or an Excel process ghosted. No hang, no silent data loss.

Frequently asked questions

How do I close a workbook without saving in VBA?

Pass SaveChanges:=False: wb.Close SaveChanges:=False. This answers the "save changes?" prompt in code with "no," so the dialog never appears and the workbook closes discarding any unsaved changes. It is the correct close for read-only processing where there is nothing to keep.

Why does my macro hang when it closes a workbook?

Because you called wb.Close on a workbook with unsaved changes without a SaveChanges argument. Excel shows the modal "Do you want to save your changes?" dialog and waits for a click that never comes in an unattended run. Always pass SaveChanges:=False or SaveChanges:=True on any close that runs without a person watching.

What is the difference between wb.Close and Application.Quit?

wb.Close closes a single workbook and leaves Excel running. Application.Quit closes Excel entirely, including every open workbook. Use Close to finish with one file in a loop; use Quit only when your code launched its own Excel instance and needs to shut it down.

Why does Excel keep running after my VBA macro closes the workbook?

Your code still holds a reference to a Workbook or Application object, so Excel cannot fully shut down and lingers as an invisible EXCEL.EXE process. Release the references — Set wb = Nothing and Set xlApp = Nothing — after closing, so the process can exit cleanly.

Can I read a workbook's properties after closing it in VBA?

No. Once wb.Close runs, the workbook is out of memory and the variable no longer refers to anything; wb.Name or wb.Sheets will error. Capture whatever you need into variables before calling Close, then Set wb = Nothing.

Tested in

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

Related guides: VBA Open Workbook · VBA Save Workbook · VBA Workbook_BeforeClose Event · VBA DisplayAlerts · VBA DoEvents