Visio自動化の深淵:ファイル監視によるVSDX-PDFリアルタイム変換アーキテクチャ
Visioの自動化において、多くのエンジニアが陥る罠がある。「Visioは重い」という現実から目を背け、安易なループ処理やタイマー監視でリソースを食い潰す設計だ。
本稿では、レガシーなVBAの制約をWindows APIの力でねじ伏せ、「特定フォルダにVSDXが置かれた瞬間、最小限のメモリ消費でPDFを生成する」ための、真に堅牢なアーキテクチャを提示する。
—
1. なぜ「タイマー監視」は悪手なのか
VBAの`OnTime`メソッドや、フォームの`Timer`イベントでファイルをポーリングするのは低級なアプローチだ。ディスクI/Oを無駄に発生させ、CPUを無意味に占有する。
真のエンジニアは、OSが提供する`FileSystemWatcher`を利用する。だが、VBA単体ではこのイベントをハンドリングできない。ここで、VB.NET(またはC#)で軽量な「監視エージェント」を書き、VisioをCOMオートメーションで制御する「コントローラー」として機能させるのが、現代的な解である。
—
2. アーキテクチャの概要
1. 監視エージェント (.NET): `FileSystemWatcher`を利用し、`Created`イベントをフック。
2. 通信層: エージェントがVisio(または起動済みVisioインスタンス)のCOMインターフェースを叩く。
3. 処理層: VisioがPDFを書き出す。
4. 終了処理: オブジェクトの明示的解放によるメモリリークの根絶。
—
3. 【実装】FileSystemWatcherによる監視エージェント(VB.NET)
まずは、監視の要となる部分を分離する。これをコンソールアプリとして常駐させれば、VBA単体よりも遥かに堅牢だ。
Imports System.IO
‘ 伝説的な堅牢性を備えた監視クラス
Public Class VisioWatcher
Private WithEvents watcher As FileSystemWatcher
Public Sub New(path As String)
watcher = New FileSystemWatcher(path, “.vsdx”)
watcher.EnableRaisingEvents = True
End Sub
Private Sub watcher_Created(sender As Object, e As FileSystemEventArgs) Handles watcher.Created
‘ ファイルロック解除を待機し、Visioを起動
System.Threading.Thread.Sleep(1000)
ConvertVisioToPdf(e.FullPath)
End Sub
Private Sub ConvertVisioToPdf(filePath As String)
Dim visioApp As Object = CreateObject(“Visio.Application”)
Dim doc As Object = Nothing
Try
doc = visioApp.Documents.Open(filePath)
‘ PDF出力の極致:Exportメソッドを使用
doc.ExportAsFixedFormat(0, filePath.Replace(“.vsdx”, “.pdf”), 0, 0)
Finally
‘ 必須の終了処理:メモリのクリーンアップ
If doc IsNot Nothing Then doc.Close(0)
visioApp.Quit()
‘ オブジェクトの完全解放
System.Runtime.InteropServices.Marshal.ReleaseComObject(visioApp)
End Try
End Sub
End Class
—
4. 【深掘り】VBA側で実装する場合の「生存戦略」
もし、どうしてもVBA完結型にこだわるのであれば、`Win32 API`の`ReadDirectoryChangesW`を駆使する必要がある。これは非同期通知を受け取るAPIだが、VBAで行うのは難易度が高い。
現実的な妥協案として、以下の「オブジェクト管理」を徹底すること。これができていないVBAコードは、即刻破棄すべきゴミである。
メモリを支配する3つの鉄則
1. `New`は使うな: `CreateObject`を使い、必要に応じて`Quit`と`ReleaseComObject`を叩く。Visioはインスタンスがゾンビ化しやすい。
2. `DoEvents`の呪縛: 変換中に`DoEvents`を連打しないこと。処理が終わるまでOSに制御を戻すべきではない。
3. エラーハンドリング: `On Error Resume Next`で隠蔽するのは甘えだ。`Err.Number`を厳密にチェックし、PDF変換失敗時には即座に`Doc.Close`を呼ぶログ出力機構を構築せよ。
—
5. 伝説のエンジニアへの助言
このシステムは「PDF化」という一点において最強のパフォーマンスを発揮するが、Visioのバージョンアップには極めて敏感である。
- COM参照の回避: 早い段階でLate Binding(遅延バインディング)に切り替えよ。`Visio.Application`を決め打ちせず、`GetObject`による既存インスタンスの流用を優先すること。
- ファイルロックの回避: 巨大なVSDXを保存した瞬間にPDF変換を走らせると、ファイルがロック中で落ちる。上記のコード例のように、`Sleep`を入れるか、ファイル属性が解除されるまでリトライを繰り返すロジックを必ず組み込め。
システム管理者が求めるのは「止まらないこと」だ。今回提示したアーキテクチャは、そのための最小かつ最強の構成である。
Visioの深淵を覗く者は、そのメモリリークの海を泳ぎ切る覚悟を持たねばならない。コードに魂を込めよ。そうすれば、自動化は苦行から芸術へと昇華する。
