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

スポンサーリンク

Visio VBAを掌握せよ:AddNamedRowで操る「動的シェイプ」の極意

こんにちは。Visioの世界へようこそ。
「マクロの記録」ボタンを押して生成される、あの長大で無機質なコードに絶望したことはありませんか?Visioの自動化における真の門出は、その記録されたコードを捨て、「オブジェクトモデル」という名の設計図を理解した瞬間から始まります。

今日は、Visioのシェイプを単なる「図形」から「自律的なプログラムの入り口」へと進化させる、`AddNamedRow`メソッドの神髄を解説します。

なぜ「AddNamedRow」なのか?

シェイプに情報を付与する際、多くの初心者はShapeSheetを直接操作しようとします。しかし、行のインデックスを決め打ちする手法は、将来的に地獄を見ます。

「もし既にその行が存在したら?」「順序が入れ替わったら?」
これらの衝突をエレガントに回避し、「名前」をキーにして安全にセクションを定義するのが`AddNamedRow`です。これを使えば、右クリックメニュー(Actionセクション)や独自変数(Userセクション)を、プログラムから安全かつ動的に生成できます。

実践:右クリックで「魔法」を呼び出す

まずは、シェイプの右クリックメニューに「ステータスを更新」という項目を追加するコードを見てみましょう。

Sub AddCustomAction()
Dim shp As Visio.Shape
Dim rowIdx As Integer

‘ 選択中のシェイプを取得
Set shp = ActiveWindow.Selection.PrimaryItem

‘ 1. Userセクションが存在しない場合は作成
If Not shp.SectionExists(visSectionUser, False) Then
shp.AddSection visSectionUser
End If

‘ 2. Actionセクション(右クリックメニュー)が存在しない場合は作成
If Not shp.SectionExists(visSectionAction, False) Then
shp.AddSection visSectionAction
End If

‘ 3. AddNamedRowで「MyCustomAction」という名前の行を追加
‘ 既に存在する場合はエラーを回避するため、On Error Resume Nextでガード
On Error Resume Next
rowIdx = shp.AddNamedRow(visSectionAction, “MyCustomAction”, visTagDefault)
On Error GoTo 0

‘ 4. メニューの表示名と実行コマンドを設定
‘ Cellの書き換えは、CellsU(Universal Name)で行うのが鉄則です
With shp.CellsSRC(visSectionAction, rowIdx, visActionMenu)
.FormulaU = “””ステータスを更新””” ‘ メニューに表示される文字列
End With

With shp.CellsSRC(visSectionAction, rowIdx, visActionAction)
.FormulaU = “RUNADDON(“”VBAコードを呼び出すためのマクロ名””)”
End With

MsgBox “右クリックメニューを追加しました!”
End Sub

ここがプロのこだわり:知っておくべき3つの鉄則

1. CellsU を使い倒せ

コード内で`Cells`ではなく`CellsU`を使っています。これは「Universal(国際共通)」の頭文字です。VisioはOSの言語設定によってセクション名が変わるため、`Cells(“メニュー”)`と書くと日本語環境以外で即座にクラッシュします。`CellsU`を使い、常に英語ベースのプロパティ名を指定するのが、世界基準のエンジニアの嗜みです。

2. SectionExists で「生存確認」

`AddNamedRow`を呼ぶ前に、必ず`SectionExists`でセクションが存在するかを確認してください。存在しないセクションに強引に行を追加しようとすれば、Visioは無情なエラーを吐きます。

3. 「名前」は設計の地図

`AddNamedRow`の第二引数に渡す名前(例: `”MyCustomAction”`)は、後からその行を特定するためのIDになります。
後で値を取得したいときも、`shp.CellsU(“User.MyCustomAction.Value”)`のように名前でアクセスできるため、コードの可読性が劇的に向上します。

陥りやすい罠と解決策

よくある失敗は、「とりあえず追加し続ける」コードを書いてしまうことです。マクロを何度も実行するたびに、同じ名前の行が何重にも作成され、ShapeSheetがゴミだらけになります。

解決策:
`AddNamedRow`を呼ぶ前に、その名前の行が既に存在するかどうかをチェックする関数をラップしておくと非常に安全です。

‘ 存在確認付きのスマートな行追加
Function SafeAddRow(shp As Visio.Shape, section As Integer, rowName As String) As Integer
On Error Resume Next
‘ 行が存在すればそのインデックスを返し、なければ追加する
SafeAddRow = shp.Cells(rowName).RowIndex
If Err.Number <> 0 Then
SafeAddRow = shp.AddNamedRow(section, rowName, visTagDefault)
End If
On Error GoTo 0
End Function

最後に:自動化の先にあるもの

`AddNamedRow`を使って右クリックメニューを定義できるようになると、Visioは単なる「お絵かきツール」から「GUIを備えたアプリケーション」へと変貌します。

ユーザーはシェイプを右クリックするだけで、データベースの更新や、別のページへのジャンプ、複雑な計算処理を実行できるようになるのです。

ここをクリアすれば、あなたはもう「記録されたマクロを動かす人」ではありません。「Visioを制御する設計者」です。次の一歩として、`User`セクションにデータを格納し、シェイプの見た目を動的に変化させる「データ駆動型図形」に挑戦してみてください。

あなたの開発ライフが、より効率的で、より知的なものになることを応援しています。質問があれば、いつでもこの場所へ戻ってきてくださいね。

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