Visio VBAの深淵:多重図面管理における「ページ数監査」の極意
多くのエンジニアがVisio VBAを単なる「図形配置の自動化ツール」だと誤解している。しかし、真にシステムを支配するアーキテクトにとって、Visioは巨大なコンポーネント・オブジェクトモデル(COM)の集合体に他ならない。
特に、複数の図面を同時に扱い、それらをPDF化して納品・アーカイブするプロセスは、メモリリークとCOMの暴走が最も発生しやすい「戦場」だ。今回は、開いている全図面のページ数を算出し、ログとして永続化する「堅牢な監査ツール」の構築手法を伝授する。
1. オブジェクトのライフサイクルを制御せよ
VBAにおいて、`Documents` や `Page` オブジェクトを安易に宣言して放置することは、即ちメモリリークへの招待状である。特に `For Each` 文でのループ処理は、参照カウントを意識しなければ、Visioプロセスがバックグラウンドで残り続け、システムリソースを食い潰す元凶となる。
極限のコード設計
以下のコードは、単なるカウント処理ではない。エラーハンドリングとオブジェクトの明示的解放を徹底した、プロダクションレベルのコードだ。
Option Explicit
‘ メイン処理:開いている全図面の統計情報を抽出する
Public Sub ExportDocumentAuditLog()
Dim docs As Visio.Documents
Dim doc As Visio.Document
Dim logPath As String
Dim fileNum As Integer
‘ 出力先はデスクトップに固定(または環境変数から取得)
logPath = Environ(“USERPROFILE”) & “\Desktop\Visio_Audit_Log.txt”
fileNum = FreeFile
On Error GoTo ErrorHandler
Set docs = Application.Documents
Open logPath For Output As #fileNum
Print #fileNum, “
Visio Audit Log – ” & Now()
Print #fileNum, “File Path, Page Count”
‘ COMオブジェクトの参照を汚さないよう明示的なループ制御
For Each doc In docs
‘ テンプレートファイルや未保存ファイルへのガード
If Not doc.Saved Or doc.Path <> “” Then
Print #fileNum, doc.FullName & “, ” & doc.Pages.Count
End If
Next doc
Close #fileNum
MsgBox “ログ出力が完了しました:” & vbCrLf & logPath, vbInformation
Cleanup:
‘ オブジェクトの明示的解放
Set doc = Nothing
Set docs = Nothing
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
Resume Cleanup
End Sub
2. アーキテクトの視点:なぜ「直接」アクセスしてはいけないのか
初心者は `Application.ActiveDocument` を多用するが、これは禁じ手だ。複数の図面が開かれている環境では、フォーカスが移るたびに `ActiveDocument` は別物を指す。
- 完全な列挙: `Application.Documents` コレクションを直接イテレートし、各図面オブジェクトの `Pages.Count` プロパティにアクセスするのが唯一の正解だ。
- ファイルロックの回避: PDF出力を行う際、対象ファイルが「読み取り専用」で開かれている場合や、別プロセスでロックされている場合がある。このツールで事前にページ数をリスト化し、整合性を担保することで、バッチ処理中の予期せぬクラッシュを未然に防げる。
3. 次なるステージ:システム間連携への布石
このツールは、単なるカウント以上の価値を持つ。例えば、これを応用して以下の処理を組み込むことが可能だ。
1. PDF変換の制御: `doc.ExportAsFixedFormat` メソッドを呼び出し、リスト化されたファイルごとに個別のPDFを出力する。
2. メタデータの注入: Windows API (`Shell32`) を使用し、PDF出力直後にファイルプロパティを書き換えることで、大規模な図面管理システム(DMS)との連携を容易にする。
3. レガシー環境の保守: `VSD` から `VSDX` への移行期において、このスクリプトを走らせることで「変換漏れ」や「破損したファイル」をページ数ゼロとして検知するフィルターとして機能する。
最後に:コードは「対話」である
VBAはレガシーと言われることもあるが、Visioの深層にアクセスできるのは今なおVBAだけだ。あなたが書くコードは、単に作業を自動化するだけではない。システムが長時間稼働しても安定性を保てるよう、メモリを解放し、リソースを管理し、エラーを握りつぶさない。
それが「プロフェッショナル」と「アマチュア」を分かつ境界線だ。
まずはこのスクリプトを自らの環境で実行し、自身のVisio環境がどれだけの「負債」を抱えているか確認することから始めてほしい。それが、真の自動化エンジニアへの第一歩となる。
