【Visio VBA】大規模VSDXのPDF出力ボトルネックを叩く:ページ単位プロファイラー実装術
業務自動化の現場において、Visioの「PDF一括出力」は鬼門だ。数百ページの図面をPDF化しようとして、数時間放置した挙句にエラーで落ちる……そんな経験はないだろうか。
なぜVisioのPDF出力は重いのか。それはVisioがレンダリング時に全オブジェクトの座標計算とメタデータ再構築を同期的に行うからだ。特に、不必要なグループ化、複雑なシェイプシートの計算式、そして何より「見えないゴミオブジェクト」が蓄積されたページが、全体のパフォーマンスを劇的に引き下げる。
今日は、どのページが「戦犯」なのかを特定するための、ページ単位プロファイラーを伝授する。これは単なる計測ツールではない。大規模図面を管理・最適化するための「外科手術のメス」だ。
—
1. なぜ「PDF出力」はブラックボックスなのか
Visioの `ExportAsFixedFormat` メソッドは、呼び出せば最後、処理が完了するまで制御を返さない。エラーが発生しても「何ページ目で止まったか」すら教えてくれないのがデフォルトだ。
これを解決するには、「ページ単位の個別出力」というアプローチが必要になる。一括出力ではなく、1ページずつPDFを生成し、その経過時間をログに記録する。この設計により、どのページが「計算負荷が高いのか」をミリ秒単位で可視化できる。
—
2. 堅牢なプロファイラー設計の肝
実務で使えるコードにするには、以下の3点を徹底しなければならない。
1. エラーハンドリングの徹底: 一部のページが破損していても、残りの出力処理を止めないこと。
2. 型指定によるメモリ管理: `Visio.Page` オブジェクトを適切に解放し、リークを防ぐ。
3. ログの永続化: `Debug.Print` だけでは不十分だ。CSV形式でファイル出力し、Excelで「ページ番号 vs 処理時間」のヒストグラムが描ける状態にせよ。
—
3. 実践:ページ単位PDFプロファイラー(プロダクションコード)
以下のコードは、現在の図面をページごとに分離出力し、それぞれの経過時間を `C:\Temp\VisioLog.csv` に書き出す。
Option Explicit
‘ 伝説的なエンジニアは定数をハードコードしない
Private Const LOG_FILE_PATH As String = “C:\Temp\Visio_Export_Log.csv”
Sub ProfileVisioPdfExport()
Dim vsoDoc As Visio.Document
Dim vsoPage As Visio.Page
Dim startTime As Double, endTime As Double
Dim fileNum As Integer
Set vsoDoc = ActiveDocument
fileNum = FreeFile
‘ ログファイルの初期化(追記モード)
Open LOG_FILE_PATH For Output As #fileNum
Print #fileNum, “PageName,ExportTime_Sec”
‘ メインループ:ページ単位での処理
For Each vsoPage In vsoDoc.Pages
‘ ページ名を記録
Debug.Print “Profiling: ” & vsoPage.Name
startTime = Timer
On Error Resume Next ‘ ページ単位のエラーで全体を止めない
vsoPage.ExportAsFixedFormat visFixedFormatPDF, _
“C:\Temp\Export_” & vsoPage.Name & “.pdf”, _
visDocExAllPages, visPrintAll
If Err.Number <> 0 Then
Debug.Print “Error on page: ” & vsoPage.Name
Print #fileNum, vsoPage.Name & “,ERROR”
Err.Clear
Else
endTime = Timer
Print #fileNum, vsoPage.Name & “,” & Format(endTime – startTime, “0.00”)
End If
On Error GoTo 0
‘ オブジェクトの明示的解放(VBAでもこれが重要)
Set vsoPage = Nothing
Next vsoPage
Close #fileNum
MsgBox “計測完了。ボトルネックを確認してください。”, vbInformation
End Sub
—
4. ボトルネック特定後の「外科手術」
このプロファイラーを実行すれば、特定のページが突出して遅いことが数値として現れるはずだ。その際、以下の観点で図面を見直せ。
- グループ化の深さ: 5階層以上の入れ子構造になっていないか?
- シェイプの数: 1ページに数千個のシェイプが存在しないか?(不要な非表示シェイプを削除せよ)
- 画像データの解像度: 巨大なビットマップを縮小表示しているだけではないか?(一旦解像度を落として再挿入せよ)
- イベントハンドラ: ページ内に `User-defined cells` の複雑な数式が計算負荷をかけていないか?
最後に:エンジニアとしての矜持
「動くツール」を作るのはプログラマーだが、「止まらない仕組み」を作るのがアーキテクトだ。
今回紹介したプロファイラーは、単に時間を測るためだけのものではない。「計測できないものは最適化できない」という工学の原則を、Visioというブラックボックスな世界に適用するための武器だ。
ログCSVをExcelで開き、処理時間が長いページ順に並び替えてみろ。そこに、君の図面が抱える「癌」が明確に映し出されるはずだ。さあ、次はコードを書き、そのボトルネックを根絶やしにする作業に取り掛かろう。
