ワークシートの軽量PDF化(Excel)

アクティブシートのPDF化

akashi-keirin.hatenablog.com

このときにも書いたように、アクティブシートをPDF化するときにはWorksheet.ExportAsFixedFormatメソッドを使う。

ただ、この場合、やたらファイルサイズがデカくなってしまうのが悩みのタネだった。かといって、いちいちJUST PDFなんかを使ってPDF化するのは死ぬほどダルいので、仕方がないなあと思っていた。

ところが、ひょんなことから、VBAでプリンタを指定できると知り、ちょっとやってみた。

Application.ActivePrinterプロパティ

Application.ActivePrinterプロパティというものを使えば、カンタンにプリンタを切り替えることができる。

まず、イミディエイト・ウインドウで現在のApplication.ActivePrinterプロパティを調べてみる。

イミディエイト・ウインドウに、

?Application.ActivePrinter

と入力して[Enter]。

f:id:akashi_keirin:20180428105851j:plain

自宅の環境では、

Canon MP470 series Printer on Ne06:

が返った。

んで、Excelの「ファイル」タブから「印刷」メニューを選び、「プリンター」で「JUST PDF 3」を選んでから、再度イミディエイト・ウインドウに

?Application.ActivePrinter

と入力して[Enter]してみると、今度は

f:id:akashi_keirin:20180428105900j:plain

JUST PDF 3 on Ne03:

が返っている。

このことを踏まえて、コーディングしてみた。

軽量PDFを出力するメソッド

リスト1 標準モジュール宣言セクション
Private Const MAIN_PRINTER As String = "Canon MP470 series Printer on Ne06:"
Private Const PDF_PRINTER As String = "JUST PDF 3 on Ne03:"

まず、プリンタ名を定数にしておく。これはあくまでもウチの環境のもの。環境が変わったら、その環境でのプリンタ名を調べて、定数を書き換えたらよい。

スト2 標準モジュール
Public Sub convertActiveSheetToLightPDF()
  Dim Sh As Worksheet
  Set Sh = ActiveSheet
  With Application
    Dim tmp As String    '……(1)'
    tmp = .ActivePrinter
    Dim printerNameLength As Long
    printerNameLength = InStrRev(tmp, " on ") - 1
    tmp = Left(tmp, printerNameLength)
    If tmp <> Left(PDF_PRINTER, printerNameLength) Then    '……(2)'
      .ActivePrinter = PDF_PRINTER
      Sh.PrintOut
      .ActivePrinter = MAIN_PRINTER
    Else
      Sh.PrintOut
    End If
  End With
End Sub

まず、(1)からの5行

Dim tmp As String    '……(1)'
tmp = .ActivePrinter
Dim printerNameLength As Long
printerNameLength = InStrRev(tmp, " on ") - 1    '……(*)'
tmp = Left(tmp, printerNameLength)

で、変数tmpに、ポートを除いたプリンタ名を格納している。

ポートは、「on ……」の形で表されるので、前後の半角スペースを含めた「 on 」で後ろから検索したら〈プリンタ名+1文字〉目が返るので、返り値から1を引いた数をプリンタ名の文字数として変数printerNameLengthに格納する。

あとは、Left関数で切り出しているだけ。

なぜこんなことをするのか。

実は、Application.ActivePrinterの返り値では、ポートの所が「Ne0X:」となっているんだが、ネットワーク上のプリンタの場合、ポートの所を「Ne0X:」で指定するとエラーになる(プリンタのIPアドレスで指定しないとダメ。「JUST PDF 3」の場合だと、「on JUST PDF 3 Port:」と指定する)。

しかも、ウチみたいにプリンタをジカで接続している場合は、逆にポートを「Ne0X:」で指定しないとエラーになるんである(たとえば、「Canon MP470 series Printer on Ne06:」を「Canon MP470 series Printer on USB001:」にするとエラーになる)。

従って、プリンタ名を比較するときにApplication.ActivePrinterの返り値をそのまま使うことができないのだ。

そんなわけで、仕方なく純粋なプリンタ名だけをまず切り出して、比較しているのだ。

あとは、(2)以下の7行

If tmp <> Left(PDF_PRINTER, printerNameLength) Then
  .ActivePrinter = PDF_PRINTER
  Sh.PrintOut
  .ActivePrinter = MAIN_PRINTER
Else
  Sh.PrintOut
End If

でメインの処理を行う。

プリンタがJUST PDF 3でなかったら、一旦プリンタをJUST PDF 3に切り替えてからプリントアウトし、メインのMP470に戻す。

もともとプリンタがJUST PDF 3になっているのなら、単純にプリントアウトするだけ。

使ってみる

f:id:akashi_keirin:20180428105908j:plain

こんなシートを準備して実行する。

ただし、JUST PDF 3の設定がデフォルトのままだと、保存先を指定したり、ファイル名を指定したりせにゃんらんわ、PDF化後、PDFファイルが開いてしまうわ、といろいろめんどくさいので、コントロールパネルのプリンタの設定のところへ行って、

f:id:akashi_keirin:20180428105916j:plain

f:id:akashi_keirin:20180428105923j:plain

こんなふうに設定しておくとよい(「保存先」は、好きなところを指定したらよい)。

これで黙って指定したフォルダにPDFを保存してくれる。

f:id:akashi_keirin:20180428105932j:plain

フォルダ内の「test.pdf」というのが、できあがったPDF。ファイルサイズは15KB。もう一つの「hoge.pdf」というのが、同じシートをWorksheet.ExportAsFidxedFormatメソッドでPDF化したもの。38KBもある。

おわりに

Application.ActivePrinterプロパティの指定の仕方(プリンタのポートの所)なんかがまだよく分からないのだが、まあ、個人使用する限りでは使えるレベルかな。

追記

f:id:akashi_keirin:20180501220411j:plain

コントロール・パネルのプリンタのところでJUST PDF 3 のアイコンを右クリックして「印刷設定」を選び、

f:id:akashi_keirin:20180501221118j:plain

「詳細セットの選択・設定」をクリック。

f:id:akashi_keirin:20180501220432j:plain

「フォント」のドロップダウンリストで「埋め込まない」を選択すると、

f:id:akashi_keirin:20180501220442j:plain

なんと、わづか3KBに!!!!!!!!

追記

実は、Application.ActivePrinterの返り値では、ポートの所が「Ne0X:」となっているんだが、ネットワーク上のプリンタの場合、ポートの所を「Ne0X:」で指定するとエラーになる(プリンタのIPアドレスで指定しないとダメ。「JUST PDF 3」の場合だと、「on JUST PDF 3 Port:」と指定する)。

と書いていたのだが、現在、自宅(USBジカ付け)でも職場(ネットワーク上)でも「[プリンタ名] on Ne0X:」の形でフツーに指定できている。何がどうなっているのか、よく分からないのだが……。

akashi-keirin.hatenablog.com

プリンタ名の取得については、コチラもどうぞ。