VBAとPDFCreatorによるPDF出力について


はじめに

仕事上いろいろあったので試行錯誤したので備忘録として残します。(日本語リファレンスとかないので)
おそらく、このようなことを使うことはほとんどないかと思われますが、もし誰かのお役に立てればと思いこのエントリを作成しました。

今回のお話は、Excelでのお話とさせていただきますが、おそらく他のWordなどでも同じように使えるかと思います。

ちなみに、ここでは紹介しませんが、Windows 10から搭載されている仮想プリンター「Microsoft Print to PDF」やOfficeソフト内にはPDFで保存する機能がありますので、そちらで問題なければそちらを使ったほうが賢明です。

こういう人におすすめ

  • 現在のOfficeのPDF保存機能がいまいちで別なものを探している人
  • PDF保存時、きれいに写真出なくて困っている人
  • 仮想プリンター経由でPDF出力できるようにしたい人

前提条件

始める前に以下のソフトのインストールと参照設定が必要です。

  • PDFCreator ( https://www.pdfforge.org/ )の内のPDFCreator(FreeでOK)をインストール
  • インストール後、参照設定で「PDFCreator_COM」をチェック(よく分からなかったら調べてね)

こんな感じでチェックを入れてもらえれば動きます。

  • Excelなどを開いた後プリンターをPDFCreatorに変更する。(変更しないと動かないはおろか、普通のプリンターから出力されてしまいます。)

PDFの出力方法

ここまで来たらあっという間です。
これをコピペして


Sub PDF_Output()
    Const JobTimeout As Integer = 15
    Const PDF_DPI As Integer = 300
    Const PDF_CompLevel As String = "JpegMedium"
    Const DistPath As String = "C:\Tmp\TestPDF.pdf"
    Dim PDFCreatorQueue As Queue
    Dim PrintJob As PrintJob

    Set PDFCreatorQueue = CreateObject("PDFCreator.JobQueue")

    'ここでPDFCreatorを選択する
    Application.Dialogs(xlDialogPrinterSetup).Show

    PDFCreatorQueue.Initialize

    ActiveWindow.SelectedSheets.PrintOut _
      Copies:=1, _
      Collate:=True

    If Not PDFCreatorQueue.WaitForJob(JobTimeout) Then
      MsgBox ("印刷ジョブが見つからない為、PDF出力されません。")
    Else
      Set PrintJob = PDFCreatorQueue.NextJob
      PrintJob.SetProfileByGuid ("DefaultGuid")

      'Compressionなどについて
      'ここで画像の圧縮率を変更…JpegMaximum(高圧縮)→JpegMinimum(低圧縮)

      '写真圧縮の明示
      Call PrintJob.SetProfileSetting("PdfSettings.CompressColorAndGray.Enabled", "True")

      '写真リサンプリングの明示
      Call PrintJob.SetProfileSetting("PdfSettings.CompressColorAndGray.Resampling", "True")

      '写真のリサンプリング設定(DPI 300)
      Call PrintJob.SetProfileSetting("PdfSettings.CompressColorAndGray.Dpi", PDF_DPI)

      '写真の圧縮は中圧縮設定
      Call PrintJob.SetProfileSetting("PdfSettings.CompressColorAndGray.Compression", PDF_CompLevel)

      PrintJob.ConvertTo (DistPath)

      If (Not PrintJob.IsFinished Or Not PrintJob.IsSuccessful) Then
          MsgBox ("次のファイルがPDF出力できませんでした。: " & DistPath)
      End If
    End If

    MsgBox ("オブジェクトをリリースします。")

    PDFCreatorQueue.ReleaseCom

End Sub

こんな感じです。

いろいろ書いていますが、以下だけが必要です。

  • CreateObjectでオブジェクトを作成する。
  • オブジェクトをInitializeする。
  • なにかPDFCreatorで印刷をする。(そうするとキューに溜まる)
  • WaitForJobでジョブ待ちする。(引数はintでタイムアウト時間)
  • ジョブがあったらNextJobでジョブをセットする
  • SetProfileByGuidでプロファイルを指定する。(ここでPDFやJPEGとしてプロファイルを設定する)
  • ConvertToで出力パスに出力する。
  • ReleaseComでCOMを手放す

簡単ですね。
ちなみに、いろいろ調べるとMergeなどもできるみたいですね。便利です。

参考

参考できるサイトも少ないですが、公式のリファレンスだけ見れば何となくできるかと思います。
あと、インストールしたフォルダ内に他のサンプルもあるのでそれを参考にするのもよいかと思います。