Visio VBAの「名前」の罠を突破せよ:多言語環境でも壊れない「NameU」の絶対法則
こんにちは。業務自動化の世界へようこそ。
Visioでマクロを書き始めると、必ず一度は壁にぶつかります。「さっきまで動いていたコードが、別のPCや図面で動かない」「なぜか図形が見つからない」。
もしあなたが今、`ActivePage.Shapes(“プロセス”)` のようなコードを書いているなら、それは時限爆弾を抱えているのと同じです。今日は、なぜそれが危険なのか、そしてプロのエンジニアがどうやって図形を特定しているのか、その「極限の知見」を伝授します。
—
1. なぜ「Name」を使ってはいけないのか?
Visioには、図形を識別するためのプロパティが2つあります。
- `Name`: 画面上の表示名。言語設定に依存する(例:日本語版では「プロセス」、英語版では「Process」)。
- `NameU`: 内部的な識別名。世界共通(Universal)。
初学者が陥る「言語の壁」
例えば、あなたが日本語環境で「プロセス」という名前の図形を特定するコードを書いたとします。しかし、そのファイルを海外拠点のエンジニアが英語版のVisioで開いた瞬間、図形の名前は自動的に「Process」に変わります。
あなたのコードは、その瞬間に死にます。
「マクロの記録」で生成されるコードは、便宜上 `Name` を使いますが、それはあくまで「記録用」。自動化を構築するなら、必ず `NameU` を使うのが鉄則です。
—
2. IDさえあればいい?……いいえ、それも危険です
「じゃあ、`Shapes.Item(1)` のようにIDを使えばいいのでは?」という疑問が湧くでしょう。
確かにIDは一意ですが、Visioの図形IDは、コピー&ペーストや削除、グループ化によっていとも簡単に書き換わります。 「ずっと同じ図形を指し続けてほしい」という願いを、IDという不安定な指標に託してはいけません。
—
3. ベストプラクティス:ShapeSheetでの命名
では、どうすれば「壊れない」識別ができるのか。答えは「ShapeSheetに独自のIDを刻み込む」ことです。
すべてのShapeには「ユーザー定義セル(User-defined Cells)」を持たせる機能があります。ここに独自の識別子を書き込み、それを検索キーにするのです。
実践:図形に不変の「タグ」を付けるコード
以下のコードは、選択した図形に「MyID」という名前のユーザー定義セルを作成し、そこに任意のコードを割り当てる例です。
Sub AssignUniqueId()
Dim shp As Visio.Shape
Dim rowIdx As Integer
‘ 現在選択している図形に対して処理を行う
Set shp = ActiveWindow.Selection(1)
‘ ユーザー定義セクションが存在しない場合は追加
If Not shp.SectionExists(visSectionUser, False) Then
shp.AddSection visSectionUser
End If
‘ “MyID” というセルを作成し、値を書き込む
‘ rowIdx はセルの位置。既存なら取得、なければ追加
rowIdx = shp.AddNamedRow(visSectionUser, “MyID”, visTagDefault)
shp.CellsU(“User.MyID”).Formula = Chr(34) & “STEP_001” & Chr(34)
MsgBox “図形に固有の識別子を刻み込みました。”
End Sub
—
4. プロの特定手法:NameU × ユーザーセル検索
図形を探すときは、`NameU` を使いつつ、必要に応じて先ほどの「ユーザーセル」をチェックします。これで、図面がどれだけ編集されても、あなたのプログラムは対象を完全に見失いません。
Function FindShapeByCustomId(page As Visio.Page, targetId As String) As Visio.Shape
Dim shp As Visio.Shape
‘ ページ内の全図形をループして探す
For Each shp In page.Shapes
‘ ユーザーセルが存在し、かつ値が一致するかチェック
If shp.CellExistsU(“User.MyID”, False) Then
If shp.CellsU(“User.MyID”).ResultStr(visNone) = targetId Then
Set FindShapeByCustomId = shp
Exit Function
End If
End If
Next
End Function
—
先輩からのアドバイス
ここをクリアすれば、あなたのVisio VBAは「動く」レベルから「業務を支えるシステム」へと進化します。
1. UI上の名前(Name)を信用しない。
2. IDはあくまで一時的なものと割り切る。
3. 不変の識別子が必要なら、ShapeSheetの「User定義セル」に刻み込む。
プログラミングとは、変化する環境の中で「変わらないもの」をどう定義するかという哲学です。まずは今書いているコードの `Name` を `NameU` に書き換えるところから始めてみてください。
あなたの自動化ライフが、より堅牢で美しいものになることを応援しています!
