Visio VBAを掌握する:マスターシェイプ・ドロップイベントを制し、自動設計の「聖域」を築く
Visioで「シェイプを配置するたびにプロパティを入力する」という手作業を繰り返しているなら、それはエンジニアとして敗北だ。
業務自動化の現場において、Visioは単なる作図ソフトではない。「データと図形の同期エンジン」であるべきだ。今回解説するのは、シェイプがドロップされた瞬間にVBAを割り込ませ、自動でメタデータやスタイルを注入する「イベント駆動型アーキテクチャ」の核心である。
中途半端なコードは、ドキュメントの肥大化やクラッシュの温床となる。本気で「使える」システムを構築するための極意を伝授しよう。
1. なぜ「EventSink」が必須なのか?
初心者はよく「タイマーで全シェイプを監視する」といった愚策を講じるが、これはパフォーマンスの自殺行為だ。我々が使うべきは `Visio.EVisioEventCodes.visEvtAdd` をフックするイベントシンク(EventSink)である。
これを使えば、システムは「配置された瞬間」だけをピンポイントで監視し、それ以外の時間はCPUリソースを一切消費しない。
2. 堅牢な設計:クラスモジュールによるイベントハンドリング
標準モジュールにイベント処理を書くのは、保守性の観点から最悪だ。イベントハンドラを制御するための「クラスモジュール」を分離し、ライフサイクルを管理せよ。
手順1:クラスモジュール `clsDropHandler` を作成する
' クラスモジュール: clsDropHandler
Option Explicit
Private WithEvents m_vsoApp As Visio.Application
Private m_sink As Visio.EventList
' イベントの初期化
Public Sub Init(app As Visio.Application)
Set m_vsoApp = app
' Applicationレベルで「シェイプの追加」イベントをフックする
Set m_sink = m_vsoApp.EventList.Add(visEvtAdd + visEvtShape, visActCodeRunVBA, "OnShapeDropped")
End Sub
' イベント発生時の処理は標準モジュールのプロシージャに委譲する
手順2:標準モジュールで処理を実装する
ここで重要なのは、「どのシェイプがドロップされたのか」を確実に特定することだ。`Application.EventInfo` を活用する。
' 標準モジュール: modEventProcessor
Option Explicit
Public Sub OnShapeDropped()
Dim vsoShape As Visio.Shape
Dim eventInfo As String
' イベント発生源のシェイプを取得
eventInfo = Visio.Application.EventInfo(visEvtIdMostRecent)
Set vsoShape = Visio.Application.ActivePage.Shapes.ItemFromID(CLng(eventInfo))
' マスターシェイプ名で判定(フィルタリング)
If vsoShape.Master Is Nothing Then Exit Sub
Select Case vsoShape.Master.Name
Case "サーバー装置"
Call ApplyServerDefaults(vsoShape)
Case "ルーター"
Call ApplyNetworkDefaults(vsoShape)
End Select
End Sub
Private Sub ApplyServerDefaults(shp As Visio.Shape)
' エラーハンドリングは必須
On Error Resume Next
' プロパティの自動注入
shp.Cells("Prop.Status").Formula = Chr(34) & "稼働中" & Chr(34)
shp.Cells("Prop.InstalledDate").Formula = Chr(34) & Format(Date, "yyyy/mm/dd") & Chr(34)
End Sub
3. 現場で「バグ」を生ませないための3つの鉄則
① イベントの二重登録を阻止せよ
`Application.EventList.Add` を不用意に呼び出すと、イベントが多重登録され、同じシェイプを置くたびに処理が10回、20回と走る地獄を見る。`Init` プロシージャを呼ぶ際は、必ず既存のイベントを確認するか、フラグ管理を行うこと。
② データベース・外部連携の落とし穴
ドロップと同時にDBへアクセスするのは、通信ラグによりVisioのUIをフリーズさせる原因になる。「遅延読み込み」あるいは「ローカルキャッシュ(DictionaryやCollection)」を介して処理せよ。API通信が必要な場合は、非同期処理を検討するか、まずはローカルでデータを完結させる設計にすべきだ。
③ ユーザー定義セル(ShapeSheet)を信じろ
シェイプの属性をVBAの変数で管理しようとするな。必ず ShapeSheetの `User` セルや `Prop` セルに書き込むこと。Visioは図形データ構造そのものがデータベースである。この原則を無視すると、保存・再読み込みのたびにデータが消失する羽目になる。
結論:自動化は「設計」で決まる
今回紹介したイベント駆動モデルは、単なるコードのコピペ以上の価値がある。それは、「操作者のミスを未然に防ぐインフラ」を構築することと同義だ。
「なぜこの処理を自動化するのか?」
「この設定が漏れると誰が困るのか?」
その問いに対する答えがコードに宿っているとき、あなたのVBAは単なるスクリプトから、組織を支える強力なツールへと進化する。
さあ、コードを開け。手作業を根絶し、エンジニアとして本来注力すべき「設計」の時間を取り戻すのだ。何か技術的な壁に突き当たったら、またいつでも戻ってくるといい。この戦場には、常に我々のようなアーキテクトが必要なのだから。
