VisioとSQL Serverを同期させる:VBAにおける「状態の一貫性」を担保する極限の設計論
Visioは単なる作図ツールではない。エンジニアにとって、それは「データ構造を視覚化したフロントエンド」であるべきだ。
多くの現場で、Visio図面とSQL Server上のメタデータが乖離し、誰が最新情報を持っているか不明な「ゾンビ図面」が蔓延している。これを解決するのは、UI上のボタン操作ではない。`Document_BeforeSave`イベントを起点とした、メモリ安全かつ堅牢なデータ同期アーキテクチャだ。
本稿では、シニアエンジニアが現場で直面するであろう、メモリリークの回避、排他制御、そしてVBAとADOの疎結合化に焦点を当て、その実装の深淵を解説する。
—
1. アーキテクチャの核心:イベント駆動型同期
Visioの`Document.BeforeSave`イベントをフックする場合、最大の敵は「同期によるパフォーマンス低下」と「保存操作のデッドロック」だ。保存処理中にDB接続がタイムアウトすれば、図面は破損するリスクを抱える。
設計上の鉄則
1. 非同期的な処理の模倣: VBAはシングルスレッドであるため、通信を別プロセス(あるいはVB.NET等の外部DLL)に委譲するのが理想だが、VBA単体で完結させる場合は、ADOのタイムアウト設定を極限まで絞り、フェイルセーフを実装する。
2. オブジェクトの明示的破棄: VBAのガベージコレクションを信じてはいけない。`Set obj = Nothing`は儀式ではなく、リソース枯渇を防ぐための防衛線だ。
—
2. 実装:`Document_BeforeSave`における同期ロジック
以下のコードは、図面のカスタムプロパティ(ShapeSheet)を読み取り、SQL Serverへ同期する基幹ロジックの断片である。
‘ ThisDocument モジュールに配置
Private Sub Document_BeforeSave(ByVal doc As IVDocument)
On Error GoTo ErrorHandler
‘ 1. SQL Serverへの接続(接続文字列は環境変数から取得推奨)
Dim conn As Object
Set conn = CreateObject(“ADODB.Connection”)
conn.ConnectionString = “Provider=SQLOLEDB;Data Source=SERVER;Initial Catalog=DB;Integrated Security=SSPI;”
conn.ConnectionTimeout = 5 ‘ 5秒以上待たせない
conn.Open
‘ 2. 図面プロパティの抽出と同期
SyncDocumentMetadata doc, conn
‘ 3. 明示的なクリーンアップ
conn.Close
Set conn = Nothing
Exit Sub
ErrorHandler:
‘ 保存を中断するか、ログに残してユーザーに警告を発する
MsgBox “DB同期失敗: ” & Err.Description, vbCritical
‘ 必要に応じてCancel = Trueを検討
End Sub
Private Sub SyncDocumentMetadata(doc As IVDocument, conn As Object)
Dim cmd As Object
Set cmd = CreateObject(“ADODB.Command”)
‘ 図面のDocumentSheetからカスタムプロパティを取得
Dim propValue As String
propValue = doc.DocumentSheet.Cells(“Prop.ProjectID”).ResultStr(“”)
‘ SQL実行: プロシージャによる更新
Set cmd.ActiveConnection = conn
cmd.CommandText = “usp_UpdateDrawingMetadata”
cmd.CommandType = 4 ‘ adCmdStoredProc
cmd.Parameters.Append cmd.CreateParameter(“@ID”, 200, 1, 50, doc.Name)
cmd.Parameters.Append cmd.CreateParameter(“@Value”, 200, 1, 255, propValue)
cmd.Execute
Set cmd = Nothing
End Sub
—
3. シニアエンジニアが意識すべき「深淵」
Windows APIによる制御の不可欠性
大規模な図面の場合、`DoEvents`を多用してUIスレッドを解放したくなるが、これは「保存中の状態」を不安定にする。同期処理が長い場合は、Windows API `Sleep`を用いてCPU負荷を制御し、OS側にコンテキストスイッチの機会を与えるべきだ。
レガシー環境でのプロパティ管理
`ShapeSheet`内のプロパティは、Visioのバージョンアップやファイル形式(VSDからVSDX)の移行でメタデータの保持形式が変わることがある。常に `doc.DocumentSheet.CellExists` を用いて、プロパティの存在確認を行ってからアクセスする防御的プログラミングを徹底すること。
VSDXの構造とパフォーマンス
VSDXは実態がZIP圧縮されたXMLの集合体だ。プロパティの更新頻度が高い場合、Visioは内部でXMLの再構築を行う。大規模な図面で頻繁に保存(同期)が発生すると、ディスクI/Oがボトルネックとなる。この場合、同期のトリガーを保存時だけでなく、「一定時間のアイドル検知」または「明示的な更新ボタン」に分けるハイブリッド構成を推奨する。
—
結びに代えて:自動化の先にあるもの
Visio VBAでシステムを構築することは、単なるコード記述ではない。それは「図面という静的なオブジェクト」に「データベースという動的な生命」を吹き込む作業だ。
コードをコピペして動かすことは誰にでもできる。しかし、ネットワークの切断、DBのロック、メモリの断片化といった「予期せぬ失敗」を前提とした堅牢な設計こそが、チーフアーキテクトの仕事だ。
あなたの書いたコードが、数年後のメンテナンス担当者を絶望させないことを祈る。それが、プロフェッショナルの矜持である。
