2024年3月18日月曜日

VBAからPDFファイルの特定のページを印刷する PDF-Xchange Viewer を使用

 ExcelやAccessのVBAからPDFファイルの特定のページを印刷するためには、一般的には「Acrobat」が必要で、「Acrobat Reader」ではなかなか上手くいかない。

「Acrobat」があっても、結構複雑な処理を書かないとだめ。

そこで、「PDF-Xchange Viewer」に行き着いた。
これは結構前に開発が終了していて、「PDF-Xchange Editer」になっているが、今でも窓の杜からダウンロードすることができた。

EditerではなくてViewerがいい点は、インストールが必要なく、「PDFXCview.exe」だけで動くこと。
EditerはEXE単体では動かない。

Shell "c:\pro****\PDFXCview.exe /print:pages='3-5' 'c:\target.pdf'"

これだけで標準プリンターから指定ページ(例なら3,4,5ページ)を出力して、自動的にViewerを終了する。そもそもバックグラウンドで動くので、終了したかどうかは画面上は不明です。

「pages='1-5'」とすれば1から5ページまでを印刷する。
「pages='3,5,7'」とすれば、3と5と7ページを印刷する。
「pages='1-3,5'」とすれば1から3ページまでと、5ページを印刷する。

まあ想像通りの動作です。

これを一つのプリントキューとして流すので、両面印刷設定済みのプリンターに対して、「pages='1-3,5'」と指定すれば、1枚目の紙の表に1ページ、裏に2ページ、2枚目の紙の表に3ページ、2枚目の紙の裏に5ページを印刷します。

これも想像通りの動作です。

もし、上記の例で、5ページを3枚目の表に印刷したければ、処理を分けて、1-3で1回流して、5ページだけを2回目として流すことになります。

追記
PDF-Xchange Viewer はダウンロードのあと、一度インストール作業が必要で、インストール後は、 「PDFXCview.exe」だけをどこか他のフォルダや、他のパソコンに移動させても使えます。
その際にPDFXCview.exeを置いているフォルダの下に、「language」フォルダと、その中の「pdfxvw_jpn.xml」ファイルを持ってきておくと、日本語メニューが使えるので助かります。

さらに追記
表題のとおり、VBAを使って、PDF-Xchange Viewerで連続印刷をすると、VBAからはじゃんじゃんプリント命令が送られて、スプーラーに溜まっていく。
スプーラーは、送られてきた順番に印刷するんだと思っていたら、そうではなくて、大量のスプールがされていると、スプーラーが気に入った(?)データからプリンターに送られるようです。
したがって、予期しない順番で紙が出てきます。
(もちろん、1個のスプールデータの中はきちんと指示通りに出ます。)
例えば、
1個のPDFファイルの、1-3ページ、5-7ページ、10ページ、15-20ページ、25ページを印刷みたいな処理を流すと、プリンターから1-3ページの次に10ページの紙が出てきたりします。
これを完全に回避する方法は無いような感じです。
仕方ないので、VBA側で処理にウエイトを入れて、スプーラーにデータが溜まらないようにするぐらいで逃げています。ウエイトを入れすぎると全ての印刷が完了するまでの時間が伸びるので、ちょうどいいウエイトをどう考えるか?
プリンターの印刷速度(30枚/分とか)と、プリンター本体のバッファー(メモリー)を勘案しながら、試行錯誤ですね。