ExcelVBAで複数のシートを結合PDFファイルへ出力する
久しぶりにExcelのシートをPDFに出力する案件をやってみたら、おいマジかよ今PDFへの出力ってそんなに楽なのかよってショックを受けました。
背景
昔こういう記事を書いたんですけどね。これを初めてやろうとしたのってもう軽く10年くらい前でOffice2003だったわけで。
現在ではPDFへの出力がたった1行で済む世界になっておりました。前のコードの供養のためにも新しい案件で書いたコードを残しておきます。
ざっくりした仕様
罫線とか見出しとか必要なテンプレートが入っている「原紙」シートが1枚ありまして。リストとかからループさせて、条件に合ったとき(11月だけとか)、原紙をコピーしてそのテンプレの中身を埋めて…、というシートを複数作って、PDF化します。
印刷したいシートを全部選択した状態でPDFへ変換すれば、1つのファイルに結合されたPDFになります。VBAで複数シートを選択するには、シート名を全部配列へ格納する必要があるみたいだったので、そのあたりを盛り込んでます。
PDF変換後は印刷用に作ったシートは消しちゃいます。描画を非表示にして実行すれば、原紙コピーして削除して、というところが見えないので、なんかスマートにPDFにできちゃった感があっていいかもしれません。
コード
Sub SheetsToPdf() Dim i As Integer Dim list As Worksheet: Set list = ActiveSheet 'アクティブシート(リストがある)を取得 Dim base As String: base = "原紙" '原紙のシート名 Dim file As String: file = ThisWorkbook.path & "\Sample.pdf" '出力するPDFのファイル名 If Dir(file, 0) <> "" Then '同じ名前のpdfファイルが存在していたら If MsgBox(file & " は既に存在しています。上書きしますか?", vbOKCancel) <> 1 Then Exit Sub 'OK以外なら途中終了 End If End If Application.ScreenUpdating = False '画面描画を非表示に Dim n As Integer: n = 0 '原紙のコピー回数 For i = 1 To 100 '目的の回数繰り返す If Format(list.Cells(i, 1), "yyyy/mm") = Format(Date, "yyyy/mm") Then '例:A列の日付が今月だったら n = n + 1 'コピー数カウントアップ Sheets(base).Copy after:=Worksheets(Worksheets.Count) '原紙をシートの最後にコピー Sheets(base & " (2)").Name = n 'コピーしたシートの名前を「回数」にしておく 'コピーしたシートの所定の位置にリストから値を入れたり With Sheets(CStr(n)) .Range("B2") = list.Cells(i, 1) .Range("C3") = list.Cells(i, 2) .Range("C4") = list.Cells(i, 3) .Range("C5") = list.Cells(i, 4) End With End If Next i If n = 0 Then 'コピー数がゼロだったら MsgBox "印刷するシートがありません。" Exit Sub '途中終了 End If '印刷シートを配列に格納 ReDim ary(n - 1) As String '印刷シートの数で配列を定義 For i = 0 To n - 1 ary(i) = i + 1 'シート名を配列へ格納 Next i Worksheets(ary).Select '印刷シートを選択 ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=file 'PDF出力 Application.DisplayAlerts = False 'アラート一時停止 ActiveWindow.SelectedSheets.Delete '印刷シート削除 Application.DisplayAlerts = True 'アラート復活 list.Select '最初のシートを選択し直す Application.ScreenUpdating = True '非表示OFF MsgBox "pdfファイルを出力しました。" '完了メッセージ End Sub
印刷用のシートは原紙をコピーして、いったん1, 2, 3…という名前のシートにします。印刷用シート名を配列に入れて全部選択してPDF化したら削除しちゃう、という流れになってます。
ExcelVBAに興味をお持ちの方は、こちらの記事もどうぞ!
- これからExcelのマクロを始めたいという方に!簡単な練習問題作りました。
- 私がExcelVBAでよく使う便利なコード・スニペットまとめ
- プログラム初心者さんへ贈る、エラーが起きたら試してみて欲しいこと
- ExcelVBAのクラスモジュールって何?という人向けの使い方まとめ
書籍を執筆しています。
コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)
YouTubeでQ&Aコンテンツを企画しています
運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。