VBAでブックを閉じるだけなら、Closeと書けば一応動きます。
Sub CloseBook_Quick()
ActiveWorkbook.Close
End Subところが実務でぶつかるのは、「閉じたはずなのに、なぜかExcelのプロセスが残っている」「保存確認のダイアログが出て自動化が止まる」という方の悩みだったりします。
この記事では、ブックを閉じる基本から、Excelアプリケーション自体を終了する方法、そして地味に厄介な「プロセスが残る」問題への対処までをまとめて解説します。
VBAでブックを閉じる基本(Workbooks.Close)
最短コードで閉じる
開いたブックを、そのまま閉じるだけならこれで十分です。
Sub CloseBook_Min()
Dim wb As Workbook
Set wb = Workbooks.Open("C:\Book1.xlsx")
' 何らかの処理
wb.Close
End Subただし、これだと変更内容によっては保存確認のダイアログが出ます。
自動化の途中でこれが出ると、そこで処理が止まってしまうので困りものです。
保存するかどうかを明示する(SaveChanges)
ダイアログを出したくない場合は、SaveChanges引数で保存するかどうかを明示します。
Sub CloseBook_NoSave()
Dim wb As Workbook
Set wb = Workbooks.Open("C:\Book1.xlsx")
' 何らかの処理(保存不要なケース)
wb.Close SaveChanges:=False
End Sub保存してから閉じたい場合はTrueにするだけです。
wb.Close SaveChanges:=True迷ったらこれを書くだけで、少なくとも「ダイアログで処理が止まる」問題は解決します。
確認ダイアログそのものを止める(DisplayAlerts)
SaveChangesとは別に、警告ダイアログ全般を一時的に止めたい場面もあります。
そんなときはApplication.DisplayAlertsを使います。
Sub CloseBook_Silent()
Dim wb As Workbook
Set wb = Workbooks.Open("C:\Book1.xlsx")
' 何らかの処理
Application.DisplayAlerts = False
wb.Close SaveChanges:=True
Application.DisplayAlerts = True
End Sub複数ブックをまとめて閉じる
自分自身(ThisWorkbook)以外を全部閉じたい、というケースもよくあります。For Eachで回せば一発です。
Sub CloseAllExceptThis()
Dim wb As Workbook
For Each wb In Workbooks
If Not wb Is ThisWorkbook Then
wb.Close SaveChanges:=False
End If
Next wb
End SubWorkbooksコレクションはループ中に要素が減っていくので、For Eachで素直に回して問題ありません。
Excelアプリケーション自体を終了する(Application.Quit)
ここまでは「ブックを閉じる」話でした。
ですが、Workbooks.Closeはあくまでブックを閉じるだけで、Excelアプリケーション自体は起動したままです。
Excelごと終了したいときはApplication.Quitを使います。
Sub QuitExcel()
Application.DisplayAlerts = False
Application.Quit
End SubApplication.Quitも、保存されていないブックが残っていれば確認ダイアログを出します。
ここでもDisplayAlertsの出番、というわけです。
【実務で詰まりやすい】閉じたはずなのにプロセスが残る問題
終了処理は意外と見落としがちですが、ここを雑にやるとWorkbooks.CloseやApplication.Quitを呼んだつもりでも、タスクマネージャーを開くとExcelのプロセス(EXCEL.EXE)がしぶとく残っていることがあります。
原因のほとんどは、オブジェクトへの参照を変数に持たず、そのまま使い捨てにしていることです。
たとえばこんな書き方。
' NGパターン:参照を変数に保持しない
Workbooks.Open("C:\Book1.xlsx").Sheets(1).Range("A1").Value = "テスト"これ自体はエラーなく動きますが、開いたブックへの参照がどこにも残らないまま次々にオブジェクトが生成されるので、後片付けのタイミングを自分でコントロールできません。
対策はシンプルで、Workbook・Worksheetそれぞれを変数に受けてから使い、用が済んだら明示的にNothingを代入することです。
Dim wb As Workbook
Dim ws As Worksheet
Set wb = Workbooks.Open("C:\Book1.xlsx")
Set ws = wb.Sheets(1)
ws.Range("A1").Value = "テスト"
wb.Close SaveChanges:=True
Set ws = Nothing
Set wb = NothingちなみにPythonからwin32com経由でExcelを操作するときも、根っこはまったく同じ問題が起きます。

言語が変わっても、Excel側から見れば同じCOMオブジェクトなので、後片付けの発想は共通というわけです。
実務テンプレ(安全に閉じて終了する完成形)
ここまでの内容を一つにまとめると、こうなります。
Sub CloseAndQuit_Template()
Dim wb As Workbook
Set wb = Workbooks.Open("C:\Book1.xlsx")
' ここに自動化したい処理を書く
Application.DisplayAlerts = False
wb.Close SaveChanges:=True
Application.Quit
Application.DisplayAlerts = True
Set wb = Nothing
End Sub保存有無を決めて、ダイアログを黙らせて、参照を手放す。
これだけ押さえておけば、バッチ処理で何百回実行してもプロセスが積み上がることはありません。
まとめ
冒頭でも触れた通り、ブックを閉じること自体は難しくありません。
ただ、保存確認とプロセスの後片付けまで含めて初めて「閉じる処理」が完成する、という点は見落とされがちです。



コメント