【実務・中級編】Shape.AddNamedRowメソッドを活用した安全なコンテキスト定義:UserセクションやActionセクションに独自の右クリックメニューを動的追加する – Visio VBA解析バイブル

スポンサーリンク

Visio VBAの深淵:AddNamedRowで右クリックメニューを完全制御する

多くの開発者が、Visioのシェイプシート操作で躓くのは「行のインデックス固定」という泥沼です。`AddRow`を安易に使い、インデックス番号でセクションを操作していませんか?それは時限爆弾を埋め込んでいるのと同じです。

シェイプの構成が動的に変わる業務自動化ツールにおいて、行の衝突や「存在しないインデックス」へのアクセスを防ぐ唯一の解は、`AddNamedRow`による名前付き行の活用です。

今日は、プロのアーキテクトが実践する「堅牢な右クリックメニュー(Actionセクション)の動的生成」について、その設計思想と共に伝授します。

なぜ「インデックス」ではなく「名前」で管理すべきか

Visioのシェイプシートは、行が追加・削除されるたびに動的に再インデックスされます。例えば、`User-defined Cells`セクションに3番目の行を追加しようとして、その前に別のソリューションが2行挿入していたら、あなたのコードは壊滅します。

`AddNamedRow`は、行に「論理的な名前」を与えます。
これにより、「何番目の行か」ではなく「その名前の行が存在するか」というコンテキストベースの制御が可能になります。これは、大規模な業務ツールを開発する際、避けては通れない必須のアーキテクチャです。

実装:Actionセクションへの動的コマンド追加

右クリックメニューは`Actions`セクションに定義します。ここでは、特定のシェイプに対して「データベース連携」や「状態リセット」などのコマンドを動的に注入するコードを示します。

堅牢な実装サンプル

Option Explicit

‘ @brief 指定したシェイプのActionセクションに動的にコマンドを追加する
‘ @param shp 対象シェイプ
‘ @param rowName 行の識別名(ユニークであること)
‘ @param menuLabel 右クリックメニューに表示する文字列
‘ @param macroName 実行するマクロ名
Public Sub AddCustomAction(shp As Visio.Shape, rowName As String, menuLabel As String, macroName As String)
Dim sec As Visio.Section
Dim row As Visio.Row

‘ Actionセクションを取得
Set sec = shp.Section(visSectionAction)

‘ 指定した名前の行が存在するか確認し、なければ作成
If Not sec.RowExists(rowName, visExistsAnywhere) Then
Set row = sec.AddNamedRow(visSectionAction, rowName, visTagDefault)
Else
Set row = sec.Row(rowName)
End If

‘ セルに数式を書き込み、右クリックメニューを定義
‘ visActionMenu: メニューの表示名
‘ visActionAction: 実行されるマクロや操作
row.Cell(visActionMenu).Formula = “””” & menuLabel & “”””
row.Cell(visActionAction).Formula = “RUNADDON(“”VISCMDS.VBA_RunMacro(“”” & macroName & “””)””)”

‘ 必要に応じてチェックマークや無効化制御もここで可能
‘ row.Cell(visActionChecked).Formula = “FALSE”
End Sub

現場で絶対に守るべき「3つの鉄則」

1. 名前空間の汚染を防ぐ(プレフィックス戦略)

`AddNamedRow`で設定する名前は、必ずプロジェクト固有のプレフィックスを付けてください。
例:`MyTool_SyncDatabase`, `MyTool_ResetStatus`
他のアドオンやVisio標準機能との衝突を避けるための、プロとしての最低限の防衛策です。

2. 再入可能性(Re-entrancy)の確保

`AddNamedRow`を実行する際、既にその行が存在する場合の処理を適切に記述してください。上記コードのように`RowExists`で確認し、存在する場合は「更新」、なければ「新規作成」という分岐構造を徹底します。これにより、マクロを何度実行してもシェイプシートが肥大化せず、整合性が保たれます。

3. データベース連携時のトランザクション管理

右クリックメニューからDB連携を行う場合、メニュー実行時に「現在どのシェイプが選択されているか(`ActiveWindow.Selection`)」を慎重に特定してください。
また、長時間かかる処理の場合は、必ず `Application.BeginUndoScope` を使用して、操作の取り消しが可能な状態を担保してください。これができないツールは、ユーザーにとって「破壊的」とみなされます。

結びに:保守性を高めるために

オブジェクトモデルを触る際、VBAのコードをただ書くのではなく、「シェイプシートの状態をどう定義し、どう維持するか」というデータモデルの視点を持ってください。

右クリックメニューというUIは、ユーザーとツールの重要な接点です。ここを動的かつ論理的に制御できる能力こそが、単なる「コード書き」と「業務自動化エンジニア」を分かつ境界線となります。

さあ、あなたのVisioツールを、誰にも壊せない堅牢なシステムへと進化させてください。質問があれば、いつでもこのコードを基点にして議論しましょう。

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