【実務・中級編】図面の変更検知:DocumentEventとApplicationEventを用いたリアルタイム自動処理の実装 – Visio VBA解析バイブル

スポンサーリンク

Visio VBAを掌握する:イベント駆動による「リアルタイム自動化」の極意

多くのエンジニアがVisio VBAに挫折する理由は一つ。「ボタンを押して処理を開始する」という、あまりに原始的な設計に固執しているからだ。

真に自動化を極めるのであれば、ユーザーが図面をいじったその瞬間にシステムが呼応する「イベント駆動型アーキテクチャ」を構築しなければならない。今回は、Visioのオブジェクトモデルを深く理解し、堅牢な常駐型マクロを実装するための設計思想を伝授する。

—

1. なぜ「イベントハンドラ」が必要なのか

「Shapeが追加されたら自動でIDを振る」「プロパティが変わったら外部DBと同期する」。これらをタイマー監視(`OnTime`)で実装するのは悪手だ。CPUリソースの無駄であり、何よりユーザーの操作と同期が取れず、不整合の温床となる。

我々が狙うべきは、`Application`および`Document`レベルで発行される「イベント」をフックすることだ。これにより、Visioの内部エンジンが変更を検知した「その瞬間」に、貴方のロジックを割り込ませることができる。

—

2. 堅牢な設計のための「クラスモジュール」活用

標準モジュールにイベントコードを書いて満足しているなら、今すぐ捨ててほしい。イベント管理には必ず「クラスモジュール」を介在させる。

設計の鉄則:

1. シングルトン管理: イベントを検知するクラスを`Application`レベルで保持する。
2. イベントの遮断: 自身の処理で「変更」が発生し、それがまたイベントを誘発する「イベントの再帰ループ」を制御する。
3. エラーハンドリング: イベント内で未処理の例外が発生すると、Visio自体がクラッシュする可能性がある。全ての処理を `On Error GoTo` で囲うのがプロの最低ラインだ。

—

3. 実装コード:常駐型イベント監視の実用雛形

以下は、図形が追加された瞬間にその名前を検知し、ログを吐き出す最小構成のテンプレートだ。

クラスモジュール名:`clsVisioMonitor`

Option Explicit

‘ Applicationイベントを監視するためのオブジェクト
Public WithEvents AppEvents As Visio.Application

‘ 図形追加イベントのハンドラ
Private Sub AppEvents_ShapeAdded(ByVal Shape As IVShape)
On Error GoTo ErrorHandler

‘ イベント再帰防止用のフラグ制御などが必要な場合はここに記述

Debug.Print “検知: 図形が追加されました – ” & Shape.Name

‘ ここにデータベース連携や属性更新のロジックを注入する
‘ 例: Shape.Cells(“Prop.Status”).Formula = “””Active”””

Exit Sub

ErrorHandler:
Debug.Print “Error in ShapeAdded: ” & Err.Description
End Sub

標準モジュール:`modMain`

Option Explicit

‘ クラスのインスタンスを保持するグローバル変数(これが常駐する)
Public monitor As clsVisioMonitor

Public Sub InitializeMonitor()
‘ インスタンスを生成し、Visio Applicationを紐付ける
Set monitor = New clsVisioMonitor
Set monitor.AppEvents = Application

MsgBox “監視システムを起動しました。”
End Sub

—

4. プロダクション環境における「3つの注意点」

実務でこのアーキテクチャを運用する場合、以下の落とし穴を回避しなければならない。

① イベントの再帰呼び出し(Stack Overflowの回避)

イベントハンドラ内で図面を変更すると、再びそのイベントが発火する。これを防ぐには、処理の開始直後に `Application.EnableEvents = False` を設定し、処理終了後に `True` に戻すという「防波堤」を必ず設置すること。

② Visioの終了とメモリ解放

`Application`レベルのイベントを掴んでいると、Visioが正常に終了できなくなるケースがある。必ず `Document_BeforeDocumentClose` などのイベントで、変数の解放(`Set monitor = Nothing`)を明示的に行う習慣をつけよ。

③ 外部DB/ファイル連携のレイテンシ

イベントハンドラはVisioのメインスレッドで動作する。ここで重い外部DBへの接続処理などを同期的に書くと、図面の操作感が著しく低下する。通信が必要な場合は、処理を非同期にするか、キューに入れてバッチ処理を行うのがアーキテクトとしての判断だ。

—

結論:自動化は「受動」から「能動」へ

イベント駆動をマスターした瞬間、貴方が作るツールは「単なるマクロ」から「Visioと一体化したシステム」へと昇華する。

まずは上記のテンプレートをコピペして、`ShapeAdded` イベントの挙動を体感してほしい。そこから先は、`CellChanged` や `BeforeSelectionDelete` といったイベントを組み合わせ、貴方の業務プロセスに特化した「生きているツール」を設計してほしい。

コードは嘘をつかない。設計の甘さだけがバグを生む。
次回の開発では、この「イベントの連鎖」を制御する設計思想をぜひ取り入れてみてほしい。それが、プロの業務自動化エンジニアとしての第一歩だ。

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