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

Excel VBA でブックを閉じる — SaveChanges、マクロをハングさせるプロンプト、そして保存せずに閉じる方法

|

Excel VBA でブックを閉じる — SaveChanges、マクロをハングさせるプロンプト、そして保存せずに閉じる方法

TL;DR — 未保存の変更があるブックへの wb.Close は、モーダルの「変更を保存しますか」 ダイアログを出します — これが無人マクロを永遠に凍りつかせます。それにはコードで、 SaveChanges 引数を使って答えましょう。

Sub CloseWithoutPrompt()
    Dim wb As Workbook
    Set wb = Workbooks.Open("C:\Reports\March.xlsx")
    ' ... 必要なものを読む ...
    wb.Close SaveChanges:=False    ' コードでプロンプトに答える - ダイアログなし、ハングなし
    Set wb = Nothing               ' Close のあと、この参照は死んでいる
End Sub

閉じる処理は、一晩じゅう完璧に走っていたバッチマクロが、翌朝、200 ファイルのうち 1 つを 処理したきりダイアログボックスの前で立ち往生している、という形で見つかる場所です。 wb.Close はただブックを閉じるのではありません — 質問をするのです。そしてあなたが コードで答えなければ、Excel はユーザーに訊き、そのユーザーはそこにいません。本記事は このたった一つの考えの上に組み立てられています — SaveChanges はあなたの答えであり、 あらゆる close のバグは、それを渡し忘れた一形態にすぎない、ということです。

この記事で学べること

  • 考え方の軸 — Close は「変更を保存しますか」と訊くSaveChanges 引数がコードで答えるあなたの返事
  • ナンバーワンのハング — 変更ありのブックを SaveChanges なしで閉じると無人マクロが凍る
  • 裏返しの危険 — SaveChanges:=False無言で破棄するので、意図して決める
  • 閉じた瞬間にオブジェクト変数が死ぬ理由、そしてそれを読むとエラーになること
  • wb.Close(1 冊のブック)対 Application.Quit(Excel 全体)、そして見えない EXCEL.EXE の罠
  • 保存して閉じると、あらゆる Save の罠を受け継ぐ理由

考え方の軸:Close は質問をする — コードで答える

ブックに未保存の変更があると、wb.Close はただ閉じることができません — その変更を残したい のかどうかを、Excel は知らないからです。だから人間に対してするのと同じことをします — **「変更を保存しますか」*ダイアログを出して待つのです。人がそこに座っているならそれでよい。 マクロでは、答えなければならないのはあなた*で、あなたは SaveChanges 引数で答えます。

wb.Close SaveChanges:=False    ' 閉じて、未保存の変更を破棄する
wb.Close SaveChanges:=True     ' 先に保存してから閉じる
wb.Close                       ' 答えなし - Excel はユーザーに訊く(プロンプト)

コードで答えを渡せば、ダイアログは決して現れません。変更ありのブックでそれを省けば、また プロンプトに逆戻りです。

ナンバーワンのハング:変更ありのブックに SaveChanges がない

これが「スケジュールしたマクロが終わらなかった」の裏にある失敗です。マクロがファイルを開き、 何かを変え — 再計算や Worksheet_Change ハンドラーですらブックを変更ありにします — そして。

wb.Close      ' 変更ありのブック、SaveChanges なし -> 「変更を保存しますか」ダイアログ -> 永遠にハング

キーボードの前で「はい」も「いいえ」もクリックする人がいないので、マクロはそのモーダル ダイアログの前に無期限に座り込みます。バッチ全体がその後ろでつかえます。直し方は、無人で 走りうるあらゆる Close必ず SaveChanges を渡すことです。

wb.Close SaveChanges:=False    ' 読み取りだけの処理:破棄する、決してプロンプトを出さない

このページから一行だけ覚えるなら、読むだけのものには wb.Close SaveChanges:=False に してください。

裏返しの危険:False は無言で破棄する

SaveChanges:=False はハングの治療薬であり、同時にそれ自身の罠でもあります。それは元に 戻す手段も確認もなしに、未保存の変更を捨てます。 もしマクロが実際に、残したかった仕事を していたなら、SaveChanges:=False はそれを無言で消します。だから意図して決めましょう。

  • ファイルを読むだけ? wb.Close SaveChanges:=False — 残すものはない、決してプロンプト を出さない。
  • 残したい結果を書き込んだ? wb.Close SaveChanges:=True — あるいは先に wb.Save、 それから wb.Close SaveChanges:=False。保存と close が別々の見える手順になるので、 こちらのほうが明快です。

プロンプトは、人間が仕事を失うのを止めるために存在します。それを引数で抑止するとき、その 責任を引き受けるのはあなたです。

Close のあと参照は死んでいる

wb.Close が走ると、ブックはメモリから消え、変数 wb は何も指さなくなります。それに触れる とエラーになります。

wb.Close SaveChanges:=False
MsgBox wb.Name          ' エラー - wb はもう開いているブックを指していない

だから閉じる前に必要なものをすべて読み、そのあと変数を Nothing に設定して意図を はっきりさせましょう。

Dim finalName As String
finalName = wb.Name              ' 閉じる前に取得する
wb.Close SaveChanges:=False
Set wb = Nothing                 ' 参照は死んでいる。そう明言する
MsgBox "Closed " & finalName

ブックを閉じる対 Excel を終了する — そして見えない EXCEL.EXE

wb.Close1 冊のブックを閉じます。Application.QuitExcel そのものを閉じます。 両者は交換可能ではなく、2 つの落とし穴が噛みついてきます。

  • ThisWorkbook.Close は、そのマクロが走っているブックを閉じます。 その行より後の コードは実行されないかもしれません。マクロからはほかのブックを閉じ、自分自身は最後に、 あるいはまったく閉じないこと。
  • 最後のブックを閉じると、見えない EXCEL.EXE が走り続けることがあります。 最後の ウィンドウが閉じるときにコードがまだ ApplicationWorkbook オブジェクトへの参照を 握っていると、Excel は完全にシャットダウンできず、タスクマネージャーの中にゴースト プロセスとして残ります。参照を解放しましょう(Set wb = NothingSet xlApp = Nothing) — そうすればプロセスは終了できます。これが「マクロが終わっても Excel が動き続ける」の 裏にある古典的なバグです。

保存して閉じると、あらゆる Save の罠を受け継ぐ

wb.Close SaveChanges:=True は、閉じる途中で Save を走らせます — だから VBA Save Workbook のあらゆる罠を受け継ぎます。

  • 一度も保存していないブックでは、保存して閉じてもパスがないので、名前を付けて保存 ダイアログにフォールバックします(ハングする)。先に SaveAs でパスを与えるか、残す 必要がなければ SaveChanges:=False で閉じましょう。
  • 間違った FileFormat で保存したマクロブックでは、保存して閉じるときにマクロ剥がしの 警告が再び出ることがあります。コードが大事なら、ファイルは .xlsm です。

迷ったら、手順を分けましょう — wb.Save(または wb.SaveAs path, format)を独立した行に、 それから wb.Close SaveChanges:=False。見える 2 つの操作は、無言で両方をこなす 1 つより 勝ります。

正直な結論:バッチループのパターン

以上のすべては、一つの信頼できる形にまとまります。フォルダーループでは、ファイルロックを 握った開いたままのブックをためこまないよう、ループの内側で開いて閉じます。

Dim name As String
name = Dir("C:\Reports\*.xlsx")
Do While name <> ""
    Dim wb As Workbook
    Set wb = Workbooks.Open("C:\Reports\" & name)
    ' ... 合計を読む ...
    wb.Close SaveChanges:=False       ' 反復ごとにコードで答える
    Set wb = Nothing
    name = Dir                        ' 次のファイル
Loop

SaveChanges:=False は読み取りだけの処理の既定、SaveChanges:=True は結果を書き込んだとき。 プロンプトに寄りかからず、つねに答え、閉じる前に読み、参照を解放する。そうすれば、無人 ジョブを静かに止めるあの close のステップは、あなたが開いた どのファイルにとっても、退屈で信頼できる終わりになります。

ExcelMaster の活用

close のステップは、見かけによらず危険です — SaveChanges を忘れればスケジュールした マクロがダイアログでハングし、True のつもりで False を渡せば仕上げた仕事が消え、迷子の 参照を握れば Excel がゴーストプロセスとして居座ります。これらは、誰も見ていない午前 3 時に だけ姿を現すバグです。

ExcelMaster は、 慎重な自動化エンジニアが書くように close を書きます。ジョブを説明すれば — 「このフォルダーの 全ファイルを処理して、それぞれ保存せずに閉じて」 — それが Set wb = Workbooks.Open(...) で 開き、閉じる前に必要なものを読み、すべての wb.Close に明示的な SaveChanges を渡し、 Set wb = Nothing で参照を解放し、ブックを開いたままにも Excel プロセスをゴースト化する こともありません。ハングなし、無言のデータ損失なし。

よくある質問

VBA で保存せずにブックを閉じるには?

SaveChanges:=False を渡します:wb.Close SaveChanges:=False。これは「変更を保存しますか」 プロンプトにコードで「いいえ」と答えるので、ダイアログは決して現れず、ブックは未保存の変更を 破棄して閉じます。残すものがない読み取り専用の処理には、これが正しい close です。

ブックを閉じるときにマクロがハングするのはなぜですか?

未保存の変更があるブックに対して、SaveChanges 引数なしで wb.Close を呼んだからです。 Excel はモーダルの「変更を保存しますか」ダイアログを出し、無人実行では決して来ないクリックを 待ちます。人が見ていない状態で走るあらゆる close では、つねに SaveChanges:=FalseSaveChanges:=True を渡しましょう。

wb.Close と Application.Quit の違いは何ですか?

wb.Close は 1 冊のブックを閉じ、Excel は走ったままです。Application.Quit は、開いている すべてのブックを含めて、Excel を丸ごと閉じます。ループの中で 1 つのファイルを終えるには Close を、コードが自前の Excel インスタンスを起動してそれをシャットダウンする必要がある ときにだけ Quit を使いましょう。

VBA マクロがブックを閉じても Excel が動き続けるのはなぜですか?

コードがまだ WorkbookApplication オブジェクトへの参照を握っているため、Excel が 完全にシャットダウンできず、見えない EXCEL.EXE プロセスとして残るからです。閉じたあとに 参照を解放しましょう — Set wb = NothingSet xlApp = Nothing — そうすればプロセスは きれいに終了できます。

VBA でブックを閉じたあと、そのプロパティを読めますか?

いいえ。wb.Close が走ると、ブックはメモリから消え、変数はもう何も指さなくなります。 wb.Namewb.Sheets はエラーになります。必要なものは Close を呼ぶ前に変数へ取得し、 それから Set wb = Nothing しましょう。

検証環境

検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-08-20。

関連ガイド: VBA Open Workbook · VBA Save Workbook · VBA Workbook_BeforeClose Event · VBA DisplayAlerts · VBA DoEvents