t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA マクロで失敗して大量のブックを開いてしまった場合に一気に閉じる方法

先ほど次のようなコードを書いていた。

Sub test()
    Dim x As 発注, y As 明細
    For Each x In 注文リスト.発注コレクション
        納品書.Copy
        Range("a3").Value = x.顧客名
        For Each y In x.明細リスト
            Debug.Print vbTab & y.商品名, y.単価, y.数量
        Next y
    Next
End Sub

※処理の中身はこちらの話なので気にしないでください。

問題は納品書.Copyの一文である。納品書というのは納品書シートのオブジェクトで、シートのCopyメソッドを引数なしで実行すると新規ブックにコピーされるが、テスト中に大量に開いてしまって困った。

これを一度に閉じるために、マクロで対処したので記録しておく。

以下のマクロを実行すると、そのマクロを書いたブック以外は強制的に閉じられる。
Application.DisplayAlertsをFalseにして保存確認を非表示にしているため実行は十分注意が必要だ。

Sub CloseBooks()
    Dim wb As Workbook
    For Each wb In Workbooks
        If Not wb Is ThisWorkbook Then
            Application.DisplayAlerts = False
            wb.Close
            Application.DisplayAlerts = True
        End If
    Next
End Sub

応用すれば、特定のファイル名から始まるブックをすべて閉じたり、保存して最新になっているブックだけを閉じたりできる。

以下、例

Sub Bookで始まるファイル名のBookを閉じる()
    Dim wb As Workbook
    For Each wb In Workbooks
        If Left(wb.Name, 4) = "Book" Then
            Application.DisplayAlerts = False
            wb.Close
            Application.DisplayAlerts = True
        End If
    Next
End Sub
Sub 保存済みのブックを閉じる()
    Dim wb As Workbook
    For Each wb In Workbooks
        If wb.Saved Then
            Application.DisplayAlerts = False
            wb.Close
            Application.DisplayAlerts = True
        End If
    Next
End Sub

ついでに、コードでミスっても大量のブックが開かないようにする方法も紹介しておこう。
初心者のうちは、バグを一発で仕留めることができず、修正しては実行を繰り返すものだ。そのたびに大量のブックが開いていては効率が悪い。

冒頭で紹介したコードに一行「Debug.Assert Workbooks.Count < 5」と入れるだけ。

Sub test()
    Dim x As 発注, y As 明細
    For Each x In 注文リスト.発注コレクション
        納品書.Copy
        Debug.Assert Workbooks.Count < 5
        Range("a3").Value = x.顧客名
        For Each y In x.明細リスト
            Debug.Print vbTab & y.商品名, y.単価, y.数量
        Next y
    Next
End Sub

Assert(アサート)とは、表明・断言・主張などの意味をもつ英単語である。
このDebug.Assertというのは、「こうなるはず!」という条件を指定して、もしそうならなかったときにプログラムを中断させる機能だ。
つまり「Debug.Assert Workbooks.Count < 5」というのは、「ブックの数が5未満のはず」というアサートを埋め込んでおき、実行中にブックの数が5に達したらプログラムが中断モードになる。

これで間違ったコードで大量のブックが開くのを抑止できるので活用してみてほしい。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。