Visio VBAのPDF出力で「余白の呪い」を解く:PageSetupを掌握する極限の設計
Visioの自動化において、PDF出力は「最後の関門」だ。画面上で完璧に見える図面が、出力した瞬間に謎の余白でカットされたり、A4の枠内に豆粒のように押し込まれたりした経験はないだろうか。
多くのエンジニアは、Visioの「印刷設定」をGUIで触ることで解決しようとする。だが、プロフェッショナルであれば理解しているはずだ。「GUIでの設定は、環境が変われば崩れる」ということを。
今回は、VBAで`PageSetup`オブジェクトを完全に制御し、図面サイズにPDFを完全にフィットさせる、堅牢かつ再利用性の高い設計論を伝授する。
—
1. なぜ「PDF出力」でトラブルが起きるのか
VisioのPDF出力は、内部的に「仮想プリンタ」の挙動を模倣している。ここで陥りやすい罠は以下の2点だ。
1. プリンタ・ドライバへの依存: `Application.Printer`の設定が環境ごとに異なるため、デフォルトプリンタの用紙設定がVisioのページサイズを上書きしてしまう。
2. PageSetupの不整合: `PageSize`と`DrawingPage`が同期していない状態で`ExportAsFixedFormat`を叩くと、Visioは「印刷範囲」を正しく解釈できず、余白を強制的に付与する。
これを防ぐ唯一の解は、「出力の瞬間にプログラム側でページサイズを再定義し、印刷設定を固定する」ことだ。
—
2. 堅牢なPDF出力のためのプロダクションコード
以下のコードは、図面のサイズをページサイズに完全一致させ、余白をゼロにした状態でPDFを生成する。保守性を考慮し、エラーハンドリングを組み込んだクラスモジュール形式の関数として実装している。
Public Sub ExportDrawingToPdf(ByVal targetPage As Visio.Page, ByVal outputPath As String)
On Error GoTo ErrorHandler
Dim doc As Visio.Document
Set doc = targetPage.Document
‘ 1. ページサイズをページ上の図形に自動フィットさせる
‘ これにより、余白のない最適なサイズが算出される
targetPage.PageSheet.Cells(“PageWidth”).Formula = “Width”
targetPage.PageSheet.Cells(“PageHeight”).Formula = “Height”
‘ 2. 印刷設定の強制適用
‘ 印刷設定がプリンタドライバに引きずられないよう明示的に設定する
With targetPage.PageSheet
.Cells(“PrintPageOrientation”).Formula = “0” ‘ 0:縦, 1:横
.Cells(“PaperSize”).Formula = “0” ‘ 0:カスタムサイズ
End With
‘ 3. PDF出力実行
‘ 固定フォーマット(PDF)として書き出し
targetPage.ExportAsFixedFormat _
FixedFormat:=visFixedFormatPDF, _
OutputFileName:=outputPath, _
Intent:=visDocIntentPrint, _
PrintRange:=visPrintAll
Exit Sub
ErrorHandler:
Debug.Print “Error: ” & Err.Description
Err.Clear
End Sub
コードの重要ポイント
- PageSheetへの直接介入: `PageSetup`オブジェクトよりも、その実体である`PageSheet`(PageプロパティのShape)のセルを直接操作するほうが圧倒的に高速かつ確実だ。
- Intent設定: `visDocIntentPrint`を指定することで、画面表示用ではなく印刷用レンダリングエンジンを呼び出す。これがズレを防ぐ鍵となる。
—
3. 実務で「バグらせない」ためのアーキテクチャ設計
開発の現場でこのコードを実装する際、以下の3点を徹底してほしい。
① 常に「一時的なページ設定」を意識する
ツール実行中に元の図面設定を破壊してはならない。もし図面自体を修正したくない場合は、`Document.Pages.Add`で一時的なページを生成し、そこに図面要素をコピーしてから出力し、最後に破棄する手法をとるべきだ。
② ファイルパスとデータベース連携
PDFの保存先をデータベースやINIファイルから読み込む際は、パスのバリデーションを忘れてはならない。特にWindowsのパス長制限(260文字)や、ファイル名の不正文字(`/`, `:`, “ 等)は、VBA実行時に致命的なランタイムエラーを引き起こす。必ず `Replace` 関数等でサニタイズする処理を挟むこと。
③ 複数ページ出力時の「ページ番号」同期
もし複数ページをまとめて一つのPDFにする場合、`ExportAsFixedFormat`の単発呼び出しでは対応できない。その場合は、一度Word等のコンテナ経由にするか、あるいはAdobe Acrobat SDKなどの外部ツールを併用する必要がある。Visio単体で強引に複数ページをPDF結合しようとすると、メモリリークのリスクが高まる。
—
結論:コードは「環境の不確実性」を排除するために書く
Visio VBAにおけるPDF出力のトラブルの9割は、ソフトウェアの不具合ではなく、「環境依存の設定」に依存していることが原因だ。
「プリンタ設定がどうなっていようが、コードが意図したサイズで出力される」
この状態こそが、エンジニアが目指すべきゴールである。本稿で紹介した`PageSheet`への直接アクセス手法は、一見泥臭いかもしれないが、これが最も堅牢で、将来的なVisioのバージョンアップにも耐えうる「伝説の作法」だ。
さあ、コードを書き、余白の呪縛を解き放て。現場の生産性は、君のその一行のコードに委ねられている。
