Excelで複数シートを一括印刷するマクロ|ON選択・PDF出力・ボタン化

エクセルの一括印刷をマクロのボタンで自動化する作成ガイド

SkillStack Lab 運営者の「スタック」です。

Excelで月別帳票や支店別資料を管理していると、10枚、20枚とシートを開いて一つずつ印刷する作業が発生することがあります。

印刷するシートが毎回同じならまだしも、「今回は1月・3月・5月だけ」「この支店は対象外」のように対象が変わると、手作業では印刷漏れや二重印刷も気になります。

複数シートを一括印刷するなら、「印刷設定」シートに対象シート名とONフラグを並べ、ONになっているシートだけVBAで順番に印刷する方法が管理しやすいです。

この方法なら、印刷対象を変更するたびにVBAコードを書き換える必要がありません。

この記事では、私が試して便利だと感じた「一覧で印刷対象を管理する」考え方をベースに、複数シートの一括印刷、PDF一括出力、ボタンへの登録、エラー対策までまとめます。

掲載するVBAコードはサンプルです。最初から本番帳票を大量印刷せず、元ファイルを複製し、ONにするシートを1枚だけにしてテストしてください。会社でマクロの利用ルールがある場合は、そのルールを優先してください。

この記事で分かること
  • ONにしたシートだけ一括印刷するVBAコード
  • 印刷対象をシート上の一覧から変更する方法
  • 対象シートをPDFへまとめて一括出力する方法
  • 非表示・存在しないシートを誤印刷しないための確認方法
  • PrintCommunicationを使うべき場面と注意点
目次

Excelで複数シートを一括印刷する仕組み

今回作る仕組みはシンプルです。

ブック内に「印刷設定」というシートを1枚作り、A列へシート名、B列へ印刷フラグを入力します。

シート名印刷フラグ
1月分請求書ON
2月分請求書
3月分請求書ON
4月分請求書

この例なら、「1月分請求書」と「3月分請求書」だけが印刷対象です。

Excelの印刷設定シートにシート名とONフラグを入力し対象シートだけVBAで一括印刷する仕組み

メリットは、印刷対象を変える人がVBAを編集しなくてよいことです。

「今月はこの3シートだけ」といった変更も、B列のONを入れ替えるだけで対応できます。

ONのシートだけ一括印刷するVBAコード

次のコードは、「印刷設定」シートのA列にシート名、B列に「ON」を入力して使用します。

対象として認識するのは、次の条件を満たしたシートです。

  • B列が「ON」になっている
  • A列に記載したシートが実際に存在する
  • シートが表示状態になっている
  • 「印刷設定」シート自身ではない
Option Explicit

Public Sub BatchPrintFromList()

    Const SETTING_SHEET As String = "印刷設定"
    Const FIRST_ROW As Long = 2

    Dim wsSetting As Worksheet
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim rowNo As Long
    Dim sheetName As String
    Dim flag As String
    Dim targetCount As Long
    Dim printedCount As Long
    Dim skippedCount As Long
    Dim answer As VbMsgBoxResult

    On Error GoTo ErrorHandler

    Set wsSetting = ThisWorkbook.Worksheets(SETTING_SHEET)

    lastRow = wsSetting.Cells( _
        wsSetting.Rows.Count, "A").End(xlUp).Row

    ' 印刷対象数を事前確認
    For rowNo = FIRST_ROW To lastRow

        flag = UCase$(Trim$(CStr( _
            wsSetting.Cells(rowNo, "B").Value2)))

        If flag = "ON" Then

            sheetName = Trim$(CStr( _
                wsSetting.Cells(rowNo, "A").Value2))

            Set ws = GetWorksheetIfExists( _
                ThisWorkbook, sheetName)

            If Not ws Is Nothing Then

                If ws.Visible = xlSheetVisible _
                   And ws.Name <> SETTING_SHEET Then

                    targetCount = targetCount + 1

                End If

            End If

        End If

    Next rowNo

    If targetCount = 0 Then

        MsgBox "印刷対象のシートがありません。" & vbCrLf & _
               "印刷設定シートを確認してください。", _
               vbExclamation

        Exit Sub

    End If

    answer = MsgBox( _
        targetCount & _
        "シートを現在の印刷設定で出力します。" & _
        vbCrLf & _
        "用紙・印刷範囲・プリンターを確認しましたか?", _
        vbYesNo + vbQuestion, _
        "一括印刷の確認")

    If answer <> vbYes Then Exit Sub

    ' ONのシートだけ印刷
    For rowNo = FIRST_ROW To lastRow

        flag = UCase$(Trim$(CStr( _
            wsSetting.Cells(rowNo, "B").Value2)))

        If flag = "ON" Then

            sheetName = Trim$(CStr( _
                wsSetting.Cells(rowNo, "A").Value2))

            Set ws = GetWorksheetIfExists( _
                ThisWorkbook, sheetName)

            If Not ws Is Nothing Then

                If ws.Visible = xlSheetVisible _
                   And ws.Name <> SETTING_SHEET Then

                    ws.PrintOut _
                        Copies:=1, _
                        Preview:=False, _
                        Collate:=True

                    printedCount = printedCount + 1

                Else

                    skippedCount = skippedCount + 1

                End If

            Else

                skippedCount = skippedCount + 1

            End If

        End If

    Next rowNo

    MsgBox _
        "一括印刷が完了しました。" & vbCrLf & _
        "印刷:" & printedCount & "シート" & vbCrLf & _
        "スキップ:" & skippedCount & "件", _
        vbInformation

    Exit Sub

ErrorHandler:

    MsgBox _
        "一括印刷を中断しました。" & vbCrLf & _
        "完了済み:" & printedCount & "シート" & vbCrLf & _
        Err.Description, _
        vbExclamation

End Sub


Private Function GetWorksheetIfExists( _
    ByVal wb As Workbook, _
    ByVal sheetName As String) As Worksheet

    On Error Resume Next

    Set GetWorksheetIfExists = _
        wb.Worksheets(sheetName)

    On Error GoTo 0

End Function

Excel VBAのWorksheet.PrintOutは、ワークシートを印刷するためのメソッドです。

今回のコードではプリンター名をコードへ固定していません。

そのため、実行前にExcelとOS側で現在の出力先プリンターを確認してください。

最初のテストでは、ONを1シートだけにしてください。いきなり10枚・20枚をONにすると、印刷範囲やプリンターを間違えた場合にもまとめて出力されます。

PrintOutメソッドのCopies、Preview、ActivePrinter、IgnorePrintAreasなどの引数は、Microsoft Learn「Worksheet.PrintOut メソッド」で確認できます。

一括印刷マクロをボタンへ登録する

コードがテストできたら、「印刷設定」シートへボタンを配置しておくと利用者がVBEを開かずに実行できます。

  1. ブックをExcelマクロ有効ブック(.xlsm)で保存します。
  2. [開発]タブを開きます。
  3. [挿入]からフォームコントロールの[ボタン]を選択します。
  4. 「印刷設定」シートへボタンを配置します。
  5. マクロ一覧からBatchPrintFromListを登録します。
  6. ボタン名を「一括印刷」などへ変更します。

図形へマクロを登録してボタンのように使う方法もあります。

フォームコントロールと図形の違い、印刷ボタン自体を紙やPDFへ出さない設定、マクロが反応しない場合の確認方法は、Excelマクロで印刷ボタンを作る方法で詳しく解説しています。

新しく単純な印刷ボタンを作る目的なら、ActiveXコントロールを選ぶ必要性は高くありません。MacではActiveXがサポートされず、新しいExcel環境ではセキュリティ上の制限もあるため、フォームコントロールまたは図形を優先すると管理しやすくなります。

複数シートをPDFへ一括出力するVBA

紙へ印刷する代わりに、「ONにしたシートをそれぞれPDFとして保存したい」という場合も自動化できます。

次のコードでは、Excelファイルと同じフォルダーへ、実行日時付きのPDFフォルダーを作成します。

その中へ、ONにした各シートを1ファイルずつPDF保存します。

Public Sub BatchExportPdfFromList()

    Const SETTING_SHEET As String = "印刷設定"
    Const FIRST_ROW As Long = 2

    Dim wsSetting As Worksheet
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim rowNo As Long
    Dim sheetName As String
    Dim flag As String

    Dim targetCount As Long
    Dim exportedCount As Long
    Dim skippedCount As Long

    Dim baseFolder As String
    Dim outputFolder As String
    Dim pdfPath As String
    Dim folderNo As Long

    On Error GoTo ErrorHandler

    If Len(ThisWorkbook.Path) = 0 Then

        MsgBox _
            "先にExcelファイルを保存してください。", _
            vbExclamation

        Exit Sub

    End If

    If InStr(1, ThisWorkbook.Path, _
             "://", vbTextCompare) > 0 Then

        MsgBox _
            "このサンプルはローカルまたは" & _
            "同期済みフォルダーへの保存を前提としています。" & _
            vbCrLf & _
            "保存先を自社環境に合わせて変更してください。", _
            vbExclamation

        Exit Sub

    End If

    Set wsSetting = _
        ThisWorkbook.Worksheets(SETTING_SHEET)

    lastRow = wsSetting.Cells( _
        wsSetting.Rows.Count, "A").End(xlUp).Row

    ' PDF対象数を確認
    For rowNo = FIRST_ROW To lastRow

        flag = UCase$(Trim$(CStr( _
            wsSetting.Cells(rowNo, "B").Value2)))

        If flag = "ON" Then

            sheetName = Trim$(CStr( _
                wsSetting.Cells(rowNo, "A").Value2))

            Set ws = GetWorksheetIfExists( _
                ThisWorkbook, sheetName)

            If Not ws Is Nothing Then

                If ws.Visible = xlSheetVisible _
                   And ws.Name <> SETTING_SHEET Then

                    targetCount = targetCount + 1

                End If

            End If

        End If

    Next rowNo

    If targetCount = 0 Then

        MsgBox _
            "PDF出力対象のシートがありません。", _
            vbExclamation

        Exit Sub

    End If

    ' 実行ごとに新しいフォルダーを作成
    baseFolder = _
        ThisWorkbook.Path & _
        Application.PathSeparator & _
        "PDF_" & _
        Format(Now, "yyyymmdd_hhnnss")

    outputFolder = baseFolder
    folderNo = 1

    Do While Len(Dir(outputFolder, vbDirectory)) > 0

        outputFolder = _
            baseFolder & "_" & CStr(folderNo)

        folderNo = folderNo + 1

    Loop

    MkDir outputFolder

    ' ONのシートをPDF出力
    For rowNo = FIRST_ROW To lastRow

        flag = UCase$(Trim$(CStr( _
            wsSetting.Cells(rowNo, "B").Value2)))

        If flag = "ON" Then

            sheetName = Trim$(CStr( _
                wsSetting.Cells(rowNo, "A").Value2))

            Set ws = GetWorksheetIfExists( _
                ThisWorkbook, sheetName)

            If Not ws Is Nothing Then

                If ws.Visible = xlSheetVisible _
                   And ws.Name <> SETTING_SHEET Then

                    pdfPath = _
                        outputFolder & _
                        Application.PathSeparator & _
                        SafeFileName(ws.Name) & _
                        ".pdf"

                    ws.ExportAsFixedFormat _
                        Type:=xlTypePDF, _
                        Filename:=pdfPath, _
                        Quality:=xlQualityStandard, _
                        IncludeDocProperties:=True, _
                        IgnorePrintAreas:=False, _
                        OpenAfterPublish:=False

                    exportedCount = _
                        exportedCount + 1

                Else

                    skippedCount = _
                        skippedCount + 1

                End If

            Else

                skippedCount = skippedCount + 1

            End If

        End If

    Next rowNo

    MsgBox _
        "PDF出力が完了しました。" & vbCrLf & _
        "出力:" & exportedCount & "ファイル" & vbCrLf & _
        "スキップ:" & skippedCount & "件" & vbCrLf & _
        "保存先:" & outputFolder, _
        vbInformation

    Exit Sub

ErrorHandler:

    MsgBox _
        "PDF出力を中断しました。" & vbCrLf & _
        "完了済み:" & exportedCount & "ファイル" & vbCrLf & _
        Err.Description, _
        vbExclamation

End Sub


Private Function SafeFileName( _
    ByVal sourceName As String) As String

    Dim invalidCharacters As Variant
    Dim targetCharacter As Variant

    invalidCharacters = _
        Array("\", "/", ":", "*", "?", _
              """", "<", ">", "|")

    For Each targetCharacter In invalidCharacters

        sourceName = Replace( _
            sourceName, _
            CStr(targetCharacter), _
            "_")

    Next targetCharacter

    sourceName = Trim$(sourceName)

    If Len(sourceName) = 0 Then
        sourceName = "Sheet"
    End If

    SafeFileName = sourceName

End Function

ExportAsFixedFormatは、ExcelからPDFなどの固定形式ファイルを書き出すためのVBAメソッドです。

Excel VBAで複数の対象シートをPDFファイルとして一括出力しフォルダーへ保存する流れ

今回のサンプルでは、シートごとに別々のPDFへ出力します。

請求書や支店別報告書のように、ファイル単位で配布・保管する帳票では管理しやすい方法です。

PDF出力で指定できるファイル名、品質、印刷範囲などの引数は、Microsoft Learn「Worksheet.ExportAsFixedFormat method」で確認できます。

非表示・存在しないシートは自動でスキップする

一括処理では、印刷設定シートへ古いシート名が残っていることがあります。

また、計算用・マスター用のシートを非表示にしているブックもあるでしょう。

今回のサンプルでは、

  • 存在しないシート
  • 非表示シート
  • 印刷設定シート自身

を印刷・PDF出力の対象から外しています。

「非表示シートは必ず印刷エラーになる」という意味ではありません。

利用者が画面上で確認できないシートを誤って大量出力しないよう、今回のサンプルでは表示状態のワークシートだけを対象にする安全側の設計にしています。

PrintCommunicationは印刷自体を高速化する機能ではない

Excel VBAの印刷高速化として、Application.PrintCommunicationを見かけることがあります。

このプロパティは便利ですが、役割を正しく理解しておきましょう。

PrintCommunicationをFalseにすると高速化できるのは、主にVBAからPageSetupプロパティを連続設定する処理です。プリンターが100ページを物理的に出力する時間そのものを数十倍速くする機能ではありません。

例えば、複数シートについて毎回、用紙の向き、余白、拡大縮小などを変更しているコードでは効果が期待できます。

On Error GoTo CleanUp

Application.PrintCommunication = False

With Worksheets("請求書").PageSetup

    .Orientation = xlLandscape
    .Zoom = False
    .FitToPagesWide = 1
    .FitToPagesTall = False

End With

CleanUp:

Application.PrintCommunication = True

If Err.Number <> 0 Then

    MsgBox _
        "ページ設定中にエラーが発生しました。" & _
        vbCrLf & _
        Err.Description, _
        vbExclamation

End If

PrintCommunication=Falseのまま処理を終わらせないことも重要です。

ページ設定を変更しない一括印刷マクロなら、無理に追加する必要はありません。

Microsoft Learnでも、PrintCommunicationをFalseにする目的は「PageSetupプロパティを設定するコードの実行を高速化する」と説明されています。設定後はTrueへ戻して、キャッシュされたPageSetupコマンドを確定します。詳しくはApplication.PrintCommunication propertyを確認してください。

プリンター名をコードへ固定しすぎない

VBAのPrintOutではActivePrinterを指定することもできます。

ただし、社内PCごとにプリンター名やポート名が違う場合、コードへ特定の文字列を直書きすると別のPCで動かなくなる原因になります。

今回のコードではActivePrinterを指定せず、各PCで現在選択されている印刷環境を利用する形にしています。

「ボタンを押せば正しいプリンターへ必ず出る」という設計にはしないでください。大量印刷の前に、利用者がプリンター名、用紙、給紙トレイなどを確認できる運用を残しておく方が安全です。

マクロボタンが動かないときの確認項目

ボタンを押しても一括印刷が始まらない場合は、コードだけでなくExcelの実行環境も確認します。

症状確認すること
マクロが保存されない.xlsm形式になっているか
ボタンを押しても動かないBatchPrintFromListが登録されているか
「印刷設定」が見つからないシート名とコードが一致しているか
一部だけ印刷されないA列のシート名、ON、表示状態を確認
VBA自体を実行できないマクロのセキュリティ設定・会社ルールを確認
Web版で動かないデスクトップ版Excelで開く

Excel for the webでは、VBAマクロを作成・編集・実行できません。

また、インターネットやメールなどから取得したOfficeファイルでは、安全対策としてマクロがブロックされる場合があります。

マクロがブロックされたからといって、共有フォルダーやダウンロードフォルダー全体を安易に「信頼できる場所」へ設定しないでください。ファイルの作成者・入手経路・コード内容と、勤務先のセキュリティルールを確認してください。

マクロを本番ファイルで使う前のチェック方法や、ほかの実務向けVBAはExcel便利マクロ8選でも解説しています。

一括印刷マクロを安全に運用するチェックリスト

一括印刷は、1回の操作で多くの出力を実行できる分、設定ミスの影響も大きくなります。

  1. 元ファイルを残す:最初はコピーした.xlsmでテストします。
  2. ONを1件だけにする:印刷結果を確認してから件数を増やします。
  3. 印刷プレビューを確認する:用紙、向き、余白、改ページを確認します。
  4. シート一覧を確認する:古いシート名や重複した行が残っていないか確認します。
  5. プリンターを確認する:通常使うプリンターや給紙設定を確認します。
  6. 実行後の枚数を照合する:対象件数と実際の出力を確認します。

特に印刷設定シートへ同じシート名を2回登録して両方をONにすると、そのシートを2回印刷します。

印刷対象一覧そのものも、業務ルールの一部として管理してください。

Excel一括印刷マクロに関するよくある質問

Excelの複数シートをまとめて印刷できますか?

できます。VBAのPrintOutを使って対象シートを順番に印刷できます。本記事では「印刷設定」シートでONにしたシートだけを処理する方法を紹介しています。

一括印刷するシートを毎回変更できますか?

できます。コードへシート名を直接書かず、シート上の一覧でON・空欄を切り替える方式なら、VBAを編集せず印刷対象を変更できます。

複数シートをPDFへ一括保存できますか?

できます。ExportAsFixedFormatを使えば、ONにした各シートをPDFへ出力できます。本記事のサンプルでは、シートごとに別のPDFファイルとして保存します。

PrintCommunicationを使えば印刷が数十倍速くなりますか?

印刷そのものを高速化する機能ではありません。Microsoftは、PageSetupプロパティを設定するコードの実行を高速化するためのプロパティとして案内しています。

非表示シートも一括印刷できますか?

本記事のサンプルでは誤印刷を避けるため、xlSheetVisibleのシートだけを対象にしています。非表示シートも出力する仕様へ変更する場合は、意図した帳票か十分に確認してからコードを変更してください。

Macでも一括印刷マクロを使えますか?

対応するデスクトップ版Excel for MacではVBAとフォームコントロールを利用できます。ただしActiveXコントロールはMacではサポートされていません。

Excel for the webでもボタンからVBAを実行できますか?

できません。Excel for the webではVBAマクロを作成・編集・実行できないため、今回の一括印刷マクロはデスクトップ版Excelで使用します。

まとめ|複数シート印刷は対象一覧をコードから分離する

Excelで複数シートを一括印刷するマクロを作るなら、単純に「すべてのシートを印刷する」コードを書くより、印刷対象を一覧で管理できる仕組みにしておくと運用しやすくなります。

  • 「印刷設定」シートへ対象シート名を並べる
  • ONにした表示シートだけを印刷する
  • 印刷前に対象件数を確認する
  • PDF一括出力も同じ対象一覧を利用する
  • PrintCommunicationはPageSetup変更時だけ検討する
  • 本番前に1シートだけでテストする

一括印刷だけでなく、転記、PDF保存、複数ファイル処理なども手作業で繰り返している場合は、VBA以外の方法も含めて自動化手段を比較してみてください。


次は、仕事で使えるスキルをもう一段積み上げる

SkillStack Labでは、Excel・生成AI・自動化・オンライン学習を、実務で使うことを前提に解説しています。今の課題に近いテーマから次の記事へ進んでみてください。

生成AIを仕事で使いたい

ChatGPTなどを「触ったことがある」から、実際の仕事で使えるレベルへ進みたい方へ。

生成AIの勉強方法・学習順序を見る →

Excel作業を自動化したい

関数だけでは限界を感じてきたら、Power Query・VBA・Pythonなども含めて自動化を考えます。

Excel業務を自動化する方法を見る →

体系的にスキルを学びたい

Excel・VBA・Python・生成AIなどを、動画講座で効率よく学びたい方へ。

社会人向けUdemy講座の選び方を見る →

何から始めるか迷ったら、今の仕事で最も時間がかかっている作業や、身につけたいスキルに近いテーマから選んでください。

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