【VBA】ブックを閉じる・Excelを終了する完全ガイド【保存有無の制御+プロセスが残る問題の対処】

VBAでブックを閉じるだけなら、Closeと書けば一応動きます。

VB
Sub CloseBook_Quick()
    ActiveWorkbook.Close
End Sub

ところが実務でぶつかるのは、「閉じたはずなのに、なぜかExcelのプロセスが残っている」「保存確認のダイアログが出て自動化が止まる」という方の悩みだったりします。

この記事では、ブックを閉じる基本から、Excelアプリケーション自体を終了する方法、そして地味に厄介な「プロセスが残る」問題への対処までをまとめて解説します。

VBAでブックを閉じる基本(Workbooks.Close)

最短コードで閉じる

開いたブックを、そのまま閉じるだけならこれで十分です。

VB
Sub CloseBook_Min()
    Dim wb As Workbook
    Set wb = Workbooks.Open("C:\Book1.xlsx")

    ' 何らかの処理

    wb.Close
End Sub

ただし、これだと変更内容によっては保存確認のダイアログが出ます。
自動化の途中でこれが出ると、そこで処理が止まってしまうので困りものです。

保存するかどうかを明示する(SaveChanges)

ダイアログを出したくない場合は、SaveChanges引数で保存するかどうかを明示します。

VB
Sub CloseBook_NoSave()
    Dim wb As Workbook
    Set wb = Workbooks.Open("C:\Book1.xlsx")

    ' 何らかの処理(保存不要なケース)

    wb.Close SaveChanges:=False
End Sub

保存してから閉じたい場合はTrueにするだけです。

VB
wb.Close SaveChanges:=True

迷ったらこれを書くだけで、少なくとも「ダイアログで処理が止まる」問題は解決します。

確認ダイアログそのものを止める(DisplayAlerts)

SaveChangesとは別に、警告ダイアログ全般を一時的に止めたい場面もあります。
そんなときはApplication.DisplayAlertsを使います。

VB
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

Falseにしたら、処理の最後で必ずTrueに戻しておきましょう。戻し忘れると、後続のマクロや手動操作でも警告が出なくなり、保存ミスに気づけなくなります。

複数ブックをまとめて閉じる

自分自身(ThisWorkbook)以外を全部閉じたい、というケースもよくあります。
For Eachで回せば一発です。

VB
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 Sub

Workbooksコレクションはループ中に要素が減っていくので、For Eachで素直に回して問題ありません。

Excelアプリケーション自体を終了する(Application.Quit)

ここまでは「ブックを閉じる」話でした。
ですが、Workbooks.Closeはあくまでブックを閉じるだけで、Excelアプリケーション自体は起動したままです。

Excelごと終了したいときはApplication.Quitを使います。

VB
Sub QuitExcel()
    Application.DisplayAlerts = False
    Application.Quit
End Sub

Application.Quitも、保存されていないブックが残っていれば確認ダイアログを出します。
ここでもDisplayAlertsの出番、というわけです。

【実務で詰まりやすい】閉じたはずなのにプロセスが残る問題

終了処理は意外と見落としがちですが、ここを雑にやるとWorkbooks.CloseApplication.Quitを呼んだつもりでも、タスクマネージャーを開くとExcelのプロセス(EXCEL.EXE)がしぶとく残っていることがあります。

原因のほとんどは、オブジェクトへの参照を変数に持たず、そのまま使い捨てにしていることです。

たとえばこんな書き方。

VB
' NGパターン:参照を変数に保持しない
Workbooks.Open("C:\Book1.xlsx").Sheets(1).Range("A1").Value = "テスト"

これ自体はエラーなく動きますが、開いたブックへの参照がどこにも残らないまま次々にオブジェクトが生成されるので、後片付けのタイミングを自分でコントロールできません。

対策はシンプルで、Workbook・Worksheetそれぞれを変数に受けてから使い、用が済んだら明示的にNothingを代入することです。

VB
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オブジェクトなので、後片付けの発想は共通というわけです。

実務テンプレ(安全に閉じて終了する完成形)

ここまでの内容を一つにまとめると、こうなります。

VB
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

保存有無を決めて、ダイアログを黙らせて、参照を手放す。
これだけ押さえておけば、バッチ処理で何百回実行してもプロセスが積み上がることはありません。

まとめ

冒頭でも触れた通り、ブックを閉じること自体は難しくありません。
ただ、保存確認とプロセスの後片付けまで含めて初めて「閉じる処理」が完成する、という点は見落とされがちです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

普段は主にPython開発をしています。
最近はAI駆動開発にも関わっています。

コメント

コメントする