【実務・中級編】【上級者向け】VisioのPDF出力設定をテンプレート化し、複数の図面で全く同じPDF設定を強制適用するクラス設計 – Visio VBA解析バイブル

スポンサーリンク

【Visio VBA極限講座】PDF出力の「ブレ」を完全根絶する!設定テンプレート強制適用のクラス設計

開発プロジェクトの現場で、Visio図面のPDF一括変換ツールを作ったことがある者なら、一度は絶望したことがあるはずだ。

「なぜか担当者によって出力されるPDFのページサイズがバラバラになる」
「図面範囲ではなく、意図しない広大なキャンバス領域までPDFに含まれてしまう」
「フォントの埋め込み設定が抜けていて、別環境で文字化けを起こした」

VisioのPDF出力(`ExportAsFixedFormat`メソッド)は、非常に気まぐれだ。アプリケーションのデフォルト状態や、前回手動保存された印刷・ページ設定のゴーストを引きずる。複数ファイルをバッチ処理する際、この「環境依存のゆらぎ」を放置することは、エンジニアとして万死に値する。

今回は、「どの図面に対しても、完全に同一の品質と設定でPDFを強制出力する」ための、堅牢なVBAクラス設計を伝授しよう。

—

なぜ場当たり的なコードでは失敗するのか?

多くの初級・中級プログラマブルは、以下のような場当たり的なコードを書く。

‘ 【アンチパターン】絶対にやってはいけない実装
Sub BadPdfExport(vsdPath As String, pdfPath As String)
Dim doc As Visio.Document
Set doc = Visio.Documents.Open(vsdPath)

‘ いきなり出力!前回の設定に依存するため完全な運ゲーになる
doc.ExportAsFixedFormat visFixedFormatPDF, pdfPath, visRasterizeNone, visPrintAll

doc.Close
End Sub

このコードの何が問題か?
Visioの図面(`.vsdとしてのドキュメント`)は、ページサイズ、印刷向き、スケーリング、余白設定などの「印刷プロパティ」をドキュメント内部の各ページおよびページSetupオブジェクトに保持している。 アプリケーション側のエクスポート引数だけでこれらを完全に制御することは不可能に近い。

プロとして、業務で耐えうるシステムを作るのであれば、「出力前に、コード側から図面のページ設定を理想の状態に強制上書き(正規化)してからエクスポートする」というアプローチを取らなければならない。

—

堅牢なクラス設計:`PdfExportManager`

今回は、設定値の保持と適用ロジックをカプセル化したクラスモジュール `PdfExportManager` を設計する。

このクラスは以下の責務を持つ。
1. PDF出力に関するパラメータ(解像度、ページ範囲、カラー等)のデフォルト値管理
2. 対象図面を開いた際、強制的にページ設定を規定値にねじ伏せる(正規化)
3. エラーハンドリングを担保した安全なPDFエクスポート実行

1. クラスモジュール:`PdfExportManager` の実装

VBE(Visual Basic Editor)で新しいクラスモジュールを追加し、名前を `PdfExportManager` に変更して以下のコードを貼り付けてほしい。

VERSION 1.0 CLASS
BEGIN
MultiUse = -1 — True
END
Attribute VB_Name = “PdfExportManager”
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
‘ =================================================================
‘ Class Name: PdfExportManager
‘ Description: Visio図面のPDF出力を一元管理し、設定のゆらぎを完全に排除する
‘ =================================================================
Option Explicit

‘ プライベートフィールド(設定値)
Private m_TargetDPI As Long
PublishQualityEnum
Private m_FitTo1Page As Boolean

‘ 初期化イベント
Private Sub Class_Initialize()
‘ デフォルト値の定義(ここでプロジェクト標準を強制する)
m_TargetDPI = 300 ‘ 高精細印刷品質
m_FitTo1Page = False ‘ 自動縮小はデフォルトオフ(必要に応じて有効化)
End Sub

‘ — プロパティ設定・取得 —
Public Property Let TargetDPI(ByVal value As Long)
m_TargetDPI = value
End Property

Public Property Let FitTo1Page(ByVal value As Boolean)
m_FitTo1Page = value
End Property

‘ =================================================================
‘ メソッド: ターゲット図面に対して設定を強制し、PDFを出力する
‘ =================================================================
Public Function ExportToPdf(ByVal targetDoc As Visio.Document, ByVal outputPdfPath As String) As Boolean
On Error GoTo ErrorHandler

Dim pag As Visio.Page
Dim originalPage As Visio.Page
Set originalPage = Visio.ActivePage

‘ 【重要】図面内の全ページに対して環境の揺らぎを強制上書き(正規化)
For Each pag In targetDoc.Pages
Call ForcePageSettings(pag)
Next pag

‘ PDFエクスポート実行
‘ visFixedFormatPDF: PDF形式
‘ visPrintAll: 全ページ対象
‘ visRasterizeNone: ベクター品質を維持(文字がぼやけないようにする)
targetDoc.ExportAsFixedFormat _
VisFixedFormat.visFixedFormatPDF, _
outputPdfPath, _
VisOpenSaveArgs.visRasterizeNone, _
VisPrintRange.visPrintAll

ExportToPdf = True
Exit Function

ErrorHandler:
‘ ログ出力やエラーハンドリングをここに記述
Debug.Print “PDF Export Error: ” & Err.Description
ExportToPdf = False
End Function

‘ =================================================================
‘ プライベートメソッド: 個別ページの印刷・レイアウト設定を強制上書き
‘ =================================================================
Private Sub ForcePageSettings(ByVal targetPage As Visio.Page)
Dim ps As Visio.PageSetup
Set ps = targetPage.PageSetup

‘ 1. ページサイズを図面の実際オブジェクト領域に合わせるか、標準A4等に固定する
‘ ここでは図面自体のページ設定プロパティを安全な値に統一

‘ 例:余白をゼロまたは標準値に強制
ps.LeftMargin = 0.25
ps.RightMargin = 0.25
ps.TopMargin = 0.25
ps.BottomMargin = 0.25

‘ 例:プリンター用紙サイズを用紙に合わせて自動調整
If m_FitTo1Page Then
ps.PrintFitOnPages = True
ps.PagesWidth = 1
ps.PagesHeight = 1
Else
ps.PrintFitOnPages = False
End If

‘ その他の堅牢化設定をここに集約可能
End Sub

—

現場で即戦力となる標準モジュールからの呼び出し

上記で作成したクラスを、実際の業務自動化マクロ(標準モジュール)からどのように呼び出すか。ここが実務上のポイントだ。ファイルをオープンし、処理し、メモリリークを防ぐために確実にドキュメントを閉じるライフサイクル管理を行う。

‘ =================================================================
‘ Module: 業務実行用標準モジュール
‘ =================================================================
Option Explicit

Sub RunBatchPdfExport()
Dim pdfMgr As PdfExportManager
Set pdfMgr = New PdfExportManager

‘ クラス側で定義した標準ポリシーを適用
pdfMgr.TargetDPI = 300
pdfMgr.FitTo1Page = False ‘ 1ページに収める強制をする場合はTrue

Dim sourceVsdPath As String
Dim outputPdfPath As String

‘ パスは環境に合わせて変更してください
sourceVsdPath = “C:\VisioWork\MasterLayout.vsdm”
outputPdfPath = “C:\VisioWork\Output\MasterLayout.pdf”

Dim targetDoc As Visio.Document
Dim wasOpen As Boolean
wasOpen = False

‘ 既に開いているドキュメントか判定、または新規オープン
On Error Resume Next
Set targetDoc = Visio.Documents(Dir(sourceVsdPath))
On Error GoTo 0

If targetDoc Is Nothing Then
‘ バックグラウンド(非表示)で開くことで描画負荷と画面チラつきをゼロにする
‘ ※VisioのVisibleプロパティ制御のテクニック
Set targetDoc = Visio.Documents.OpenEx(sourceVsdPath, visOpenRO + visOpenHidden)
wasOpen = True
End If

‘ クラスに処理を委譲
Dim success As Boolean
success = pdfMgr.ExportToPdf(targetDoc, outputPdfPath)

‘ 自身で開いた場合は、メモリリークを防ぐため確実にクローズ
If wasOpen Then
targetDoc.Close
End If

If success Then
MsgBox “PDFの出力が正常に完了しました。”, vbInformation, “完了”
Else
MsgBox “PDFの出力に失敗しました。イミディエイトウィンドウを確認してください。”, vbCritical, “エラー”
End

Set pdfMgr = Nothing
End Sub

—

チーフアーキテクトからの実務アドバイス

1. `visOpenHidden` による高速化と安全性
大量の図面をバッチ処理する際、`.Open` で画面上に図面を表示させると、VisioのUIレンダリングコストが発生し、処理速度が劇的に低下するだけでなく、フォーカスの奪い合いによる予期せぬエラーの温床となる。必ず `visOpenHidden` を使ってバックグラウンドで処理せよ。
2. フォント埋め込みに関する注意点
VisioのPDFエクスポートエンジンは、PCにインストールされているフォント依存である。サーバーサイドや専用の仮想マシン(RDP等)でこのマクロを走らせる場合、図面で使用されているフォント(メイリオや各種ゴシックなど)が実行環境にインストールされていないと、PDF化の瞬間に文字化けやレイアウト崩壊を起こす。「PDF化の前に環境のフォントが担保されているか」はインフラ側の前提条件となることを忘れてはならない。

クラス設計によって「設定の揺らぎ」を完全にコードで封じ込める。このアプローチを取り入れるだけで、あなたの組んだ自動化ツールは「素人が書いた不安定なマクロ」から「プロフェッショナルなエンタープライズツール」へと昇華する。ぜひ現場のコードベースに組み込んでほしい。

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