Visioを「生き物」に変える。DocumentEventとApplicationEventで実現するリアルタイム自動化の極意
こんにちは。現場の最前線でVisioと格闘し続けてきたアーキテクトです。
「マクロの記録」ボタンを押して図形を動かすだけの世界は、もう卒業しましょう。今日お伝えするのは、あなたが触るVisioを「ユーザーの操作に合わせて自律的に動く知的エージェント」へと昇華させるための技術――「イベントハンドリング」です。
Visio VBAで最も強力であり、同時に最も注意が必要な「イベント駆動型プログラミング」の深淵へ、一緒に足を踏み入れましょう。
—
1. なぜ「イベント」なのか?
通常のVBAは、ボタンを押した瞬間に実行され、終われば消える「単発型」です。しかし、業務自動化の真髄は「ユーザーが何かをした瞬間に、その意図を汲み取って裏で処理を走らせる」ことにあります。
- 図形を配置した瞬間に命名規則をチェックする
- 形状を変更したら、データベースと同期する
- ページが切り替わったら、自動的にレイアウトを整える
これらは、Visioが発する「信号(イベント)」をキャッチすることで初めて実現します。
—
2. 実装の要:クラスモジュールによる「監視の定着」
Visioのイベントを捉えるには、標準モジュールではなく「クラスモジュール」が必要です。なぜなら、イベント監視はVisioを開いている間ずっとメモリ上で「生きている」必要があるからです。
手順:監視用クラス(EventSink)の作成
1. VBE(Alt + F11)で「挿入」→「クラスモジュール」を選択。名前を `EventSink` に変更。
2. 以下のコードを記述します。
‘ クラスモジュール: EventSink
‘ WithEventsキーワードでVisioのApplicationを監視下に置く
Public WithEvents App As Visio.Application
‘ 図形が追加された瞬間をフックするイベント
Private Sub App_ShapeAdded(ByVal Shape As IVShape)
‘ ユーザーが図形をドロップした瞬間にログを出す
Debug.Print “検知!新しい図形が追加されました: ” & Shape.Name
‘ ここで自動命名やプロパティ付与などのロジックを叩く
Shape.Text = “自動生成図形”
End Sub
—
3. 監視のスタートライン:Applicationのセット
クラスを作っただけでは動きません。プログラムに「このクラスで監視を始めろ」と命じる必要があります。
標準モジュールでの起動処理
‘ 標準モジュール
Dim myMonitor As EventSink ‘ 監視用クラスのインスタンス
Public Sub StartMonitoring()
‘ インスタンスを生成
Set myMonitor = New EventSink
‘ Visio本体を監視対象としてセット
Set myMonitor.App = Application
MsgBox “監視を開始しました。図形を追加してみてください。”
End Sub
この `myMonitor` という変数は、プロシージャの外(モジュールの先頭)で宣言してください。プロシージャ内で宣言すると、処理が終わった瞬間に変数が破棄され、監視も停止してしまいます。これが初心者が必ずハマる「イベントが動かない」最大の原因です。
—
4. アーキテクトの戒め:注意すべき3つの鉄則
イベント駆動型プログラムは、時に「諸刃の剣」となります。以下の3点だけは必ず守ってください。
1. 無限ループを避ける:
イベントハンドラの中で「図形を変更する」処理を書くと、その変更自体がイベントを発生させ、再びハンドラが動く…という無限ループに陥ります。処理の先頭で `Application.EnableEvents = False` を行い、処理後に `True` に戻すのが定石です。
2. エラーハンドリングを怠らない:
監視中にエラーが発生すると、Visio全体が不安定になることがあります。`On Error Resume Next` を適切に使い、最低限ログを吐く仕組みを入れましょう。
3. メモリ解放を意識する:
大規模な開発では、監視を終了する `StopMonitoring` プロシージャを作り、`Set myMonitor = Nothing` でメモリを明示的に開放する習慣を身につけてください。
—
5. 次のステージへ
今回解説した `ShapeAdded` はほんの入り口に過ぎません。Visioには他にも以下のような強力なイベントが備わっています。
- `DocumentOpened`: ファイルを開いた瞬間に設定を反映
- `CellChanged`: 特定の座標や値が変わった瞬間に計算を実行
- `BeforeSelectionDelete`: 削除を検知して「本当に消して良いか」を確認
「Visioがユーザーの操作を理解している」という感覚。これこそが、業務自動化エンジニアが手にする真の武器です。
まずはこのコードをコピペして、自分の環境で「図形を置いてみる」ところから始めてください。自分の書いたコードがVisioを動かしているという実感が、あなたを次のレベルのエンジニアへと引き上げてくれるはずです。
何か不明点があれば、またいつでも聞いてください。応援していますよ。
