Visio VBAの「禁断の果実」:イベント連鎖によるクラッシュを完全に制圧する
こんにちは。自動化の世界へようこそ。
Visio VBAを触り始めると、誰もが一度は「マクロの記録」から卒業し、`ShapeAdded` や `CellChanged` といった強力なイベントハンドラに手を伸ばしたくなるはずです。
「図形が追加された瞬間に自動で色を変えたい」
「数値を変更したら連動してラベルを書き換えたい」
そう思ってコードを書き、いざ実行した瞬間……Visioがフリーズし、最悪の場合は強制終了。
これはあなたが悪いのではありません。Visioのイベントモデルの「深淵」に触れてしまっただけなのです。
今日は、Visio自動化エンジニアとして避けては通れない「無限ループによるスタックオーバーフロー」という呪いを解く、唯一無二の防御策を伝授します。
—
なぜ「無限ループ」は起きるのか?
想像してみてください。あなたは「図形が追加されたら、その図形に青い枠線をつける」というイベントコードを書きました。
1. あなたが図形をドロップする。
2. `ShapeAdded` イベントが発火する。
3. コードが動き、図形の枠線を青く変更する。
4. 「枠線の変更」という操作が、再び Visio の「図形の変更(CellChanged等)」として検知される。
5. 再びイベントが発火する……。
こうして Visio の中で処理が永遠に巡回し、メモリが食いつぶされて「スタックオーバーフロー」が発生します。これが「イベントの連鎖」の正体です。
—
救世主:`Application.EventsEnabled` の真実
このループを止めるための唯一の魔法が、`Application.EventsEnabled` プロパティです。
これを `False` にすることで、コード実行中のイベント発生を完全に無効化できます。処理が終わったら `True` に戻す。この「スイッチのオン・オフ」こそが、堅牢なVBAコードの生命線です。
安全なイベントハンドラのテンプレート
以下は、現場で私が必ず採用している「安全なイベント処理」の基本構造です。
‘ クラスモジュール等でイベントを定義している前提のサンプル
Private Sub vsoApp_ShapeAdded(ByVal Shape As IVShape)
‘ 1. イベントの発生を一時停止(防御の開始)
Dim oldEventsEnabled As Boolean
oldEventsEnabled = Application.EventsEnabled
Application.EventsEnabled = False
‘ エラーが発生しても必ずイベントを再開させるためのガード
On Error GoTo Cleanup
‘ — ここから本来の業務ロジック —
‘ 例:図形にIDを書き込む処理など
Shape.Text = “ID:” & Shape.ID
Shape.Line.Color = vbBlue
‘ ——————————–
Cleanup:
‘ 2. 万が一エラーが起きても、イベントを確実に復帰させる
Application.EventsEnabled = oldEventsEnabled
‘ エラーがあった場合は通知(デバッグ用)
If Err.Number <> 0 Then
Debug.Print “エラー発生: ” & Err.Description
End If
End Sub
—
コードを読み解く:なぜこれが必要か?
初心者の方は、`Application.EventsEnabled = False` だけを書いて満足しがちですが、これだけでは不十分です。以下の3点を心に刻んでください。
- 状態を記憶する (`oldEventsEnabled`)
元々 `False` だった設定を、勝手に `True` に書き換えてはいけません。現在の状態を保存し、最後に元に戻すのがプロの作法です。
- `On Error GoTo` で囲む
もし処理中にコードがエラーで止まったらどうなるでしょう? `Application.EventsEnabled = True` に戻らないまま終了すると、二度と Visio でイベントが発火しなくなります。 これを防ぐため、必ず `Cleanup` ラベルを用意し、エラー時も復帰処理を通すようにしてください。
- 最小範囲をガードする
イベント停止はあくまで「処理の連鎖を防ぐための処置」です。広範囲で止めすぎると、他の必要な機能まで死んでしまいます。必要なロジックの直前直後で制御するのが鉄則です。
—
まとめ:ここをクリアすれば、あなたはもう脱初心者です
Visio VBAで最も恐ろしいのは「動かないこと」ではなく「不安定に動くこと」です。
今回紹介した `EventsEnabled` の制御は、いわば自動化エンジニアとしての「守りの型」です。
1. イベント内で図形を操作するなら、必ずイベントを止める。
2. エラーハンドリング(`On Error`)を併用し、確実にイベントを再開させる。
この2点さえ守れば、Visioはあなたの忠実な下僕となります。
最初は難しく感じるかもしれませんが、一度この型を身につければ、どんな複雑な自動化ツールも怖くありません。
さあ、恐れずにコードを書きましょう。あなたの自動化の旅が、ここからより深く、より確かなものになることを願っています。
