【テクニカル・上級編】【中級者向け】PDF出力時にページサイズが混在する図面を、全ページA4サイズに強制リサイズして出力する – Visio VBA解析バイブル

スポンサーリンク

序論:不揃いな矩形を統制せよ ―― Visioドキュメントにおける「動的正規化」の真髄

現場の第一線で戦うアーキテクト諸君なら、Visioというアプリケーションの「特異性」を熟知しているはずだ。Excelのようにセルという格子に縛られず、PowerPointのようにスライドサイズという絶対的な枠組みにも固執しない。Visioの真骨頂は、ページごとに異なる物理寸法とスケール(縮尺)を内包できる柔軟性にある。

しかし、その柔軟性は「配布物」というフェーズにおいて牙を剥く。
A3、A4、果てはカスタムサイズが混在した図面をそのままPDF化すれば、閲覧者のUXを著しく損なうだけでなく、物理印刷時の事故を誘発する。

我々に課せられたミッションは、「元のレイアウトを破壊することなく、出力時のみ全ページをA4サイズへ強制的に正規化する」ことだ。

これは単にPageWidth/Heightを書き換えるだけの単純作業ではない。ShapeSheetのジオメトリ、印刷設定、そしてCOMオブジェクトのライフサイクル管理を完璧に統制する、高度な「動的正規化」の実装である。

—

1. ページ設定の深淵:ShapeSheetとPageオブジェクト

Visioのすべてのページは、その背後に「PageSheet」と呼ばれる隠れたデータ構造を持っている。
ページサイズを制御するには、単なるプロパティ操作ではなく、このPageSheet内のセル値を、単位(Unit)を厳密に定義した上で操作する必要がある。

考慮すべき3つのセル

1. PageWidth / PageHeight: ページの物理的な大きさ。
2. PrintPageOrientation: 印刷方向(縦・横)。
3. DrawingResizeType: ページサイズ変更時の振る舞い。

ここで重要なのは、「強制リサイズ」を行う際に図形がページからはみ出すリスクをどう制御するかだ。今回は「出力用の一時的な変換」に焦点を当て、エンジニアリングの観点から最も堅牢な「一時ドキュメント生成方式」を採用する。

—

2. 実装:PDF出力用「A4正規化」エンジン

以下のコードは、既存のドキュメントを汚染しないよう、メモリ上にクローンを作成し、全ページをA4(297mm x 210mm)に統一した上でPDFを出力する、実戦仕様のプロシージャである。

Option Explicit

‘
‘ @Description: 全ページをA4サイズに強制リサイズし、PDFとして出力する
‘ @Context: ページサイズ混在図面の統制出力
‘ @Note: 既存のファイルを書き換えないよう、一時的なコピーに対して処理を行う
‘
Public Sub ExportUnifiedA4PDF()
Dim targetDoc As Visio.Document
Set targetDoc = ActiveDocument

If targetDoc Is Nothing Then Exit Sub

‘ パフォーマンス最適化:画面更新とイベントの抑制
Dim app As Visio.Application
Set app = Application
app.ScreenUpdating = False
app.EventsEnabled = False

Dim tempDoc As Visio.Document
Dim pg As Visio.Page
Dim pgSheet As Visio.Shape

‘ 1. 出力用の一時コピーを作成(元のファイルを保護)
‘ ※保存済みのファイルである必要がある。未保存の場合はSaveAsを先行させること。
Set tempDoc = app.Documents.Add(targetDoc.FullName)

On Error GoTo ErrHandler

‘ 2. 全ページを走査し、ジオメトリをA4に強制適合させる
For Each pg In tempDoc.Pages
Set pgSheet = pg.PageSheet

‘ ページサイズ設定のロックを解除(必要に応じて)
‘ A4横 (297mm x 210mm) を基準とする
‘ visMillimeters (64) を明示的に指定し、地域設定による差異を排除

‘ 横持ち(Landscape)を基本とする設計思想
pgSheet.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesPaperKind).FormulaForceU = “9” ‘ A4
pgSheet.CellsSRC(visSectionObject, visRowPage, visPageWidth).FormulaForceU = “297mm”
pgSheet.CellsSRC(visSectionObject, visRowPage, visPageHeight).FormulaForceU = “210mm”

‘ 3. スケールの調整(オプション)
‘ 図形がはみ出す場合、ここでPageScale/DrawingScaleを操作して「図枠に合わせる」ロジックを挿入可能
‘ 本稿ではシンプルにキャンバスサイズのみを統制する
Next pg

‘ 4. PDF出力の実行
‘ 固定フォーマット書き出しメソッドを使用
Dim pdfPath As String
pdfPath = CreatePDFPath(targetDoc.FullName)

tempDoc.ExportAsFixedFormat visFixedFormatPDF, pdfPath, visDocExIntentPrint, visDocExPrintAll

Debug.Print “PDF Export Completed: ” & pdfPath

CleanUp:
‘ 5. 後処理:一時ドキュメントを保存せずに閉じる
If Not tempDoc Is Nothing Then
tempDoc.CloseSaveNoChanges
Set tempDoc = Nothing
End If

‘ 環境の復元
app.ScreenUpdating = True
app.EventsEnabled = True
Exit Sub

ErrHandler:
MsgBox “Critical Error in PDF Export: ” & Err.Description, vbCritical
Resume CleanUp
End Sub

‘ ——————————————————————————
‘ 保存パスの生成(デスクトップ等)
‘ ——————————————————————————
Private Function CreatePDFPath(originalFullName As String) As String
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)

Dim baseName As String
baseName = fso.GetBaseName(originalFullName)

‘ デスクトップにパスを生成
CreatePDFPath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & “\” & baseName & “_A4_Unified.pdf”

Set fso = Nothing
End Function

—

3. 卓越したエンジニアが押さえるべき急所

3.1 `FormulaForceU` の選択理由

VBAからShapeSheetを操作する際、`Result` プロパティではなく `FormulaForceU` を使用している。これは、ユーザーによる保護設定やガード(GUARD関数)がかかっているセルに対しても、アーキテクトの意志を強制的に反映させるためだ。また、単位系を文字列(”297mm”)で渡すことで、内部的な数値変換による端数誤差を最小限に抑えている。

3.2 メモリリークとCOM参照の切断

Visio VBAは、オブジェクトの参照を掴み続ける傾向が強い。`tempDoc.CloseSaveNoChanges` を呼び出した後、即座に `Set tempDoc = Nothing` を行うのは、大規模な図面を扱う際の「作法」である。これを怠ると、バックグラウンドでVisioプロセスがゾンビ化し、システムリソースを食いつぶす原因となる。

3.3 スケール調整(オートフィット)の拡張性

上記のコードはキャンバスサイズをA4に変えるだけだが、実際の業務では「図形がはみ出す」ことが許されないケースもある。その場合は、`pg.PageSheet.Cells(“PageScale”)` と `pg.PageSheet.Cells(“DrawingScale”)` の比率を計算し、ページ内に収まるよう動的に縮尺を再計算するロジックを組み込むのがシニアの仕事だ。

—

4. 結び:技術の「魂」は細部に宿る

単に「PDFを出す」だけなら、標準機能で事足りるかもしれない。しかし、複雑な業務フローや巨大な設備設計図面を扱う現場では、こうした「強制的な統制」がドキュメントの信頼性を担保する。

レガシーなVBAという道具を使いながらも、その設計思想は最新のマイクロサービスやクラウドネイティブな開発と変わらない。「不変なもの(オリジナル)」を守り、「一時的な変異(出力用コピー)」を制御し、「リソース(メモリ)」を適切に解放する。

このコードが、貴殿のシステムの堅牢性を一段階上へと引き上げる一助となれば幸いである。

タイトルとURLをコピーしました