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月分請求書」だけが印刷対象です。

メリットは、印刷対象を変える人が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にすると、印刷範囲やプリンターを間違えた場合にもまとめて出力されます。
一括印刷マクロをボタンへ登録する
コードがテストできたら、「印刷設定」シートへボタンを配置しておくと利用者がVBEを開かずに実行できます。
- ブックをExcelマクロ有効ブック(.xlsm)で保存します。
- [開発]タブを開きます。
- [挿入]からフォームコントロールの[ボタン]を選択します。
- 「印刷設定」シートへボタンを配置します。
- マクロ一覧から
BatchPrintFromListを登録します。 - ボタン名を「一括印刷」などへ変更します。
図形へマクロを登録してボタンのように使う方法もあります。
フォームコントロールと図形の違い、印刷ボタン自体を紙や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メソッドです。

今回のサンプルでは、シートごとに別々のPDFへ出力します。
請求書や支店別報告書のように、ファイル単位で配布・保管する帳票では管理しやすい方法です。
非表示・存在しないシートは自動でスキップする
一括処理では、印刷設定シートへ古いシート名が残っていることがあります。
また、計算用・マスター用のシートを非表示にしているブックもあるでしょう。
今回のサンプルでは、
- 存在しないシート
- 非表示シート
- 印刷設定シート自身
を印刷・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のまま処理を終わらせないことも重要です。
ページ設定を変更しない一括印刷マクロなら、無理に追加する必要はありません。
プリンター名をコードへ固定しすぎない
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回の操作で多くの出力を実行できる分、設定ミスの影響も大きくなります。
- 元ファイルを残す:最初はコピーした.xlsmでテストします。
- ONを1件だけにする:印刷結果を確認してから件数を増やします。
- 印刷プレビューを確認する:用紙、向き、余白、改ページを確認します。
- シート一覧を確認する:古いシート名や重複した行が残っていないか確認します。
- プリンターを確認する:通常使うプリンターや給紙設定を確認します。
- 実行後の枚数を照合する:対象件数と実際の出力を確認します。
特に印刷設定シートへ同じシート名を2回登録して両方をONにすると、そのシートを2回印刷します。
印刷対象一覧そのものも、業務ルールの一部として管理してください。
Excel一括印刷マクロに関するよくある質問
まとめ|複数シート印刷は対象一覧をコードから分離する
Excelで複数シートを一括印刷するマクロを作るなら、単純に「すべてのシートを印刷する」コードを書くより、印刷対象を一覧で管理できる仕組みにしておくと運用しやすくなります。
- 「印刷設定」シートへ対象シート名を並べる
- ONにした表示シートだけを印刷する
- 印刷前に対象件数を確認する
- PDF一括出力も同じ対象一覧を利用する
- PrintCommunicationはPageSetup変更時だけ検討する
- 本番前に1シートだけでテストする
一括印刷だけでなく、転記、PDF保存、複数ファイル処理なども手作業で繰り返している場合は、VBA以外の方法も含めて自動化手段を比較してみてください。
