VBAで複数のブックを一括保存・一括で閉じる方法|For Each・Saved・SaveChangesの使い方

VBAで開いているすべてのブックを一括保存・一括で閉じるには、For Each wb In Workbooks でループしてWorkbookオブジェクトを操作するだけです。複数ファイルを開いて作業する業務の「終了処理」として登録しておくと、保存漏れや閉じ忘れを防げます。

この記事では、次の内容を順番に解説します。

  • 開いている全ブックを一括保存するコード
  • 自ブックを除いて全ブックを閉じるコード
  • 保存済みかどうかを判定して処理を分ける方法
  • 名前を指定して特定ブックだけ対象にする方法

開いている全ブックを一括保存するには?

Workbooks コレクションを For Each でループすると、現在開いているすべてのブックを順に処理できます。wb.SavedFalse のブックだけを保存することで、変更のないブックに余分な処理をしません。

Sub SaveAllBooks()

    Dim wb As Workbook

    For Each wb In Workbooks
        If wb.Saved = False Then
            wb.Save
        End If
    Next wb

    MsgBox "すべてのブックを保存しました。"

End Sub
プロパティ・メソッド内容
Workbooks現在開いているすべてのブックのコレクション
wb.Savedブックに未保存の変更があるか(FalseならSaveが必要)
wb.Save上書き保存する

自ブックを除いて全ブックを閉じるには?

マクロを記述しているブック(ThisWorkbook)まで閉じると実行が中断してしまいます。wb.Name <> ThisWorkbook.Name で自分自身を除外してから閉じます。

Sub CloseAllOtherBooks()

    Dim wb As Workbook

    For Each wb In Workbooks
        If wb.Name <> ThisWorkbook.Name Then
            wb.Close SaveChanges:=True   'Trueで保存して閉じる
        End If
    Next wb

    MsgBox "現在のブック以外をすべて閉じました。"

End Sub

SaveChanges の値によって閉じるときの動作が変わります。

動作
SaveChanges:=True変更を保存してから閉じる
SaveChanges:=False変更を破棄して閉じる
省略未保存の変更があれば確認ダイアログが表示される

保存済みか確認しながら閉じるには?

ブックに未保存の変更があるかどうかを確認して、あれば保存・なければそのまま閉じる、という丁寧な処理も簡単に書けます。

Sub CloseWithCheck()

    Dim wb      As Workbook
    Dim answer  As Integer

    For Each wb In Workbooks
        If wb.Name <> ThisWorkbook.Name Then

            If wb.Saved = False Then
                '未保存の変更があれば確認する
                answer = MsgBox(wb.Name & " に未保存の変更があります。保存して閉じますか?", _
                                vbYesNoCancel + vbQuestion)
                If answer = vbYes Then
                    wb.Close SaveChanges:=True
                ElseIf answer = vbNo Then
                    wb.Close SaveChanges:=False
                End If
                '「キャンセル」の場合はそのブックをスキップ
            Else
                wb.Close SaveChanges:=False
            End If

        End If
    Next wb

End Sub

特定のブックだけを対象にするには?

ファイル名や拡張子などの条件で絞って処理したい場合は、ループ内に条件を追加します。

'「売上」という文字を含むブックだけを保存する例
Sub SaveTargetBooks()

    Dim wb As Workbook

    For Each wb In Workbooks
        If InStr(wb.Name, "売上") > 0 Then
            wb.Save
        End If
    Next wb

    MsgBox "「売上」を含むブックを保存しました。"

End Sub

'xlsxファイルだけを対象にする例(xlsmは除外)
Sub SaveXlsxOnly()

    Dim wb  As Workbook
    Dim ext As String

    For Each wb In Workbooks
        ext = LCase(Right(wb.Name, 5))
        If ext = ".xlsx" Then
            wb.Save
        End If
    Next wb

End Sub

まとめ

  • For Each wb In Workbooks で開いている全ブックをループ処理できる
  • wb.Saved = False で未保存の変更があるブックだけを対象にできる
  • 自ブックを除外するには wb.Name <> ThisWorkbook.Name の条件を加える
  • wb.Close SaveChanges:=True/False で保存するかしないかを明示して閉じる
  • InStr でファイル名に特定のキーワードが含まれるブックだけを対象にできる

よくある質問

ブックを閉じようとすると「エラー」や「飛ばされるブック」が出るのはなぜ?

For Each(順番に処理する命令)を使ってブックを閉じると、Excelが「次は2番目のブックを処理しよう」と思った瞬間に、中身がズレてしまってエラーが起きたり、処理されないブックが出たりすることがあります。

例えるなら、「1列に並んでいる人を前から順に列から外していくと、途中で誰が何番目かわからなくなる」ような状態です。

確実にすべてのブックを閉じたい場合は、この記事のサンプルコードのように「自分以外のブックを閉じる」条件を正しく設定するか、少し高度ですが「番号の大きい後ろの方から順に閉じていく(Step -1)」というテクニックを使います。

ヒント】確実に閉じるための「後ろから数える」書き方

' 5番目、4番目…と後ろから順に閉じれば、列がズレても影響を受けません
For i = Workbooks.Count To 1 Step -1
    Workbooks(i).Close SaveChanges:=True
Next i

この Step -1 は「1ずつ減らす」という意味です。

新規ブック(まだ保存されていないファイル)を閉じるとエラーになります

新規ブックは wb.Path = "" になっています。If wb.Path = "" Then の条件で新規ブックを除外するか、SaveAs で保存先を指定してから閉じる処理を追加してください。

マクロを記述したブック自体も最後に閉じたいです

他のブックを全部閉じた後、最後に ThisWorkbook.Close SaveChanges:=True と書けば自分自身も閉じられます。ただしこれ以降のコードは実行されないため、最後の行に書いてください。

Workbooks.Countでブックの数を確認できますか?

できます。MsgBox Workbooks.Count & " 件のブックが開いています。" で現在開いているブックの数を確認できます。処理前に件数を表示して確認ダイアログを出す設計にすると、誤実行を防げます。

ブックを保存する前にバックアップも取りたいです

wb.Save の前に wb.SaveCopyAs "C:¥Backup¥" & wb.Name を追加すると、保存の前にバックアップコピーを別フォルダに作れます。日付をファイル名に入れる場合は Format(Now, "yyyymmdd_hhmmss") & "_" & wb.Name のようにすると重複を防げます。


動画で学びたい方へ

「記事を読んでも、実際に自分で書けるか不安…」という方には、動画で基礎からじっくり学べる講座がおすすめです。

VBAが初めての方を前提に、つまずきやすいポイントを先回りして解説しています。サンプル動画は無料でご覧いただけます。

動画で学ぶExcelマクロ|JIMOVEオンラインスクール

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール