Visio VBAの深淵:混在するページサイズを「A4」に強制統一してPDF化する極意
業務現場において、Visioで作成された図面が「継ぎ接ぎ」の歴史を辿っていることは珍しくない。A3で描かれたフロー図、A4の帳票、さらには謎のカスタムサイズが混在するファイルを、そのままPDF出力して配布する……それはプロの仕事ではない。
今回は、Visioのオブジェクトモデルを掌握し、「PDF出力時のみ、全ページを動的にA4サイズへ再定義し、美しく出力する」という実務直結のソリューションを授ける。
1. なぜ「設定変更」は危険なのか?
多くの初心者は、UI上の「ページ設定」をVBAで愚直に叩きに行こうとする。だが、これは罠だ。
Visioのページサイズは`PageSheet`オブジェクトの`PageWidth`および`PageHeight`セルに依存しており、これを安易に変更すると、グループ化された図形の位置関係や、コネクタの端点が崩壊するリスクがある。
真のアーキテクトが採るべき戦略は、「非破壊的アプローチ」だ。
元の図面データを改変せず、PDFエクスポートの直前に、一時的なページ設定の書き換え(あるいはPDF出力設定の制御)を行い、処理終了後に元に戻す。この「トランザクション」の概念こそが、バグを生まない唯一の道である。
2. 極限のプロダクションコード
このコードは、全ページのサイズを一時的にA4(210mm x 297mm)としてPDF化し、直後に元の状態へ復元する設計だ。
Option Explicit
‘ 定数定義:保守性を高めるためにハードコードを避ける
Private Const A4_WIDTH As Double = 210 / 25.4 ‘ インチ換算
Private Const A4_HEIGHT As Double = 297 / 25.4
Public Sub ExportAllPagesToA4PDF()
Dim doc As Visio.Document
Dim pg As Visio.Page
Dim originalSizes As Object
Set originalSizes = CreateObject(“Scripting.Dictionary”)
Set doc = ActiveDocument
‘ 1. 現在のページ設定を退避(復元用)
For Each pg In doc.Pages
originalSizes.Add pg.Name, Array(pg.PageSheet.Cells(“PageWidth”).ResultIU, _
pg.PageSheet.Cells(“PageHeight”).ResultIU)
‘ 2. A4サイズへ強制変更
pg.PageSheet.Cells(“PageWidth”).ResultIU = A4_WIDTH
pg.PageSheet.Cells(“PageHeight”).ResultIU = A4_HEIGHT
Next pg
‘ 3. PDFエクスポート実行
‘ PDF出力はPrintOutではなくExportメソッドを使用するのが現代のベストプラクティス
On Error GoTo Cleanup
doc.Export visExportFormatPDF, “C:\Temp\Output_Fixed.pdf”
Cleanup:
‘ 4. 必ず元に戻す(重要:エラーが発生してもここを通す設計)
Dim key As Variant
For Each pg In doc.Pages
If originalSizes.Exists(pg.Name) Then
pg.PageSheet.Cells(“PageWidth”).ResultIU = originalSizes(pg.Name)(0)
pg.PageSheet.Cells(“PageHeight”).ResultIU = originalSizes(pg.Name)(1)
End If
Next pg
If Err.Number <> 0 Then MsgBox “PDF出力中にエラーが発生しました: ” & Err.Description
End Sub
3. 開発現場で生き残るための設計思想
このコードをそのまま使うだけでなく、以下の「現場の知見」を設計に組み込んでほしい。
① `ResultIU`の重要性
Visio VBAにおいて、単位を意識するのは時間の無駄だ。常に`ResultIU`(内部単位であるインチ)を使用せよ。これで、ユーザーがミリ設定だろうがインチ設定だろうが、ロジックは常に一定の結果を返す。
② `Dictionary`による状態管理
今回のコードでは`Scripting.Dictionary`を用いて元のページサイズを保持している。これを配列で管理しようとすると、ページ削除や追加があった瞬間にインデックスがズレてバグの温床となる。キーバリュー形式で管理するのは、安全なコードを書くための定石だ。
③ データベース連携時の落とし穴
もしこの自動化ツールが、データベース(AccessやSQL Server)から図面を生成・更新するパイプラインの一部なら、`Application.ScreenUpdating = False`を冒頭に入れることを推奨する。描画更新を止めるだけで、数分かかる処理が数秒に短縮されることもある。
結論:プロの自動化とは「隠れた副作用」を消すこと
業務自動化エンジニアの仕事は、コードを書いて終わりではない。「ユーザーが元のファイルが変更されたとすら気づかない」レベルで、静かに、かつ確実に結果を残すことだ。
今回紹介した「サイズ強制リサイズ」の手法は、一見強引に見えるが、`Cleanup`ラベルによる確実な復元処理を組み合わせることで、極めて堅牢なツールとなる。この設計思想を、貴方の自動化ライブラリの核として活用してほしい。
次は、どのような難問を解決しようか?君たちの挑戦を待っている。
