こんにちは!Visio VBAの世界へようこそ。
マクロの記録ボタンを押して生成されたコードを眺め、「なんだか呪文みたいだな…」と途方に暮れていませんか?大丈夫、その気持ちすごくよく分かります。
今回は、Visio VBAの基礎をマスターしたあなたが、実務の壁を華麗に突破するための「【上級】Shape.UniqueIDによる永続的トラッキング」というテーマについて解説します。
ここをクリアすれば、単なる「お絵描きマクロ」から脱却し、外部データベースやExcelと完全同期する「本格的なエンジニアリング」の領域に到達できます。温かく導いていくので、リラックスしてついてきてくださいね!
—
なぜ、普通の「図形ID」や「名前」ではダメなのか?
Visioで図形を操作するとき、私たちは普段 `ActivePage.Shapes(1)` のようにインデックス番号を使ったり、`Shape.Name`(例: “プロセス.3″)を使ったりします。
しかし、現場でこんな悲劇が起きたことはありませんか?
- 図形を削除して新しく描き直したら、ID番号がズレてプログラムが別の図形をいじってしまった。
- ファイルを保存して別の人に渡し、再び開いたら、図形内部のIDが振り直されていて外部DBとの紐付けが切れた。
そう、Visioの通常の `ID` プロパティや `Name` プロパティは、「その図形がそのページに存在する間だけの、いわば『仮の番号』」に過ぎないのです。ファイル保存やコピー&ペーストを行うと、平気で変わってしまいます。
救世主:`Shape.UniqueID` の登場
ここで登場するのが、今回の主役である `Shape.UniqueID` です。
これは、図形に刻印された「デジタルのDNA(UUID)」のようなもの。一度発行されれば、ファイル保存、別ページへの移動、果ては別ファイルへのコピーを行っても、一貫してその図形を追跡し続けることができます。
外部のSQLデータベースやExcelシートに「この図形のデータはこの行にある」と紐付けるためには、この `UniqueID` を使うのがプロの絶対鉄則です。
—
現場で使える!UniqueIDの取得と復元テクニック
それでは、実際にコードを書いてその挙動を体感してみましょう。
今回は、「図形にUniqueIDを付与してイミディエイトウィンドウに出力する処理」と、「そのUniqueIDを使って後から図形を再検索する処理」の2つを見ていきます。
ステップ1:図形からUniqueIDを確実に取得する
まずは、選択している図形からUniqueIDを取得するコードです。ここで少しVisioの仕様上の注意点があります。VisioのUniqueIDは、何もしない状態だとまだ生成されていないことがあります。そのため、必要に応じて明示的に取得・生成させるアプローチを取ります。
Public Sub GetMyUniqueShapeID()
Dim shp As Visio.Shape
Dim uniqueIDStr As String
‘ 1. ユーザーが図形を選択しているかチェック
If ActiveWindow.Selection.Count = 0 Then
MsgBox “対象の図形を選択してください。”, vbExclamation, “チーフアーキテクトからの注意”
Exit Sub
End If
Set shp = ActiveWindow.Selection(1)
‘ 2. UniqueIDを取得する(visGetUIDCodeDefaultを指定)
‘ ※このメソッドは、まだIDがない図形に対しては自動的に新しいIDを割り当てます
uniqueIDStr = shp.UniqueID(visGetUIDCodeDefault)
‘ 3. イミディエイトウィンドウに結果を出力
Debug.Print “図形名: ” & shp.Name
Debug.Print “永続ID(UniqueID): ” & uniqueIDStr
MsgBox “UniqueIDを取得しました!” & vbCrLf & uniqueIDStr, vbInformation, “成功”
End Sub
コードのポイント
- `shp.UniqueID(visGetUIDCodeDefault)` を呼ぶだけで、Visioが内部的に一意な文字列(例: `{B132A89F-72C3-481E-921A-0E1402E8A3C3}` のような形式)を返してくれます。
- この文字列をExcelやテキストファイル、外部DBに保存しておけば、将来どれだけ図形の位置が変わろうとも絶対に見失うことはありません。
—
ステップ2:UniqueIDから図形を「再検索(トラッキング)」する
次に、保存しておいたUniqueID(文字列)を使って、図形をピンポイントで探し出す魔法のコードです。
ページ全体の図形をループしてIDを比較する必要はありません。Visioには、ページから直接UniqueIDを持つ図形を呼び出す高速なメソッドが用意されています。
Public Sub FindShapeByUniqueID()
Dim targetPage As Visio.Page
Dim targetShp As Visio.Shape
Dim searchID As String
‘ 【実務のシミュレーション】
‘ 先ほど取得したUniqueIDをここに代入すると想定してください(実際はDBやExcelから読み込みます)
searchID = “{B132A89F-72C3-481E-921A-0E1402E8A3C3}” ‘ ← ここをご自身の環境のIDに書き換えてテストしてください
Set targetPage = ActivePage
‘ 1. Page.ShapeFromIDEx を使って一発で図形を特定する
‘ 引数にUniqueIDの文字列を渡します
On Error Resume Next
Set targetShp = targetPage.ShapeFromIDEx(searchID)
On Error GoTo 0
‘ 2. 図形が見つかったかどうかの判定
If Not targetShp Is Nothing Then
‘ 見つかった場合の処理(例:選択状態にして赤色に変える)
ActiveWindow.DeselectAll
ActiveWindow.Select targetShp, visSelect
‘ 試しに図形の色を赤に変更してみる
targetShp.Cells(“FillForegnd”).FormulaU = “RGB(255, 0, 0)”
MsgBox “UniqueIDに一致する図形を発見し、赤色に変更しました!”, vbInformation, “トラッキング成功”
Else
MsgBox “指定されたUniqueIDを持つ図形は、このページには存在しません。”, vbExclamation, “見つかりませんでした”
End If
End Sub
ここがエンジニアの知見!
ループ文(`For Each shp In Page.Shapes`)を使って全図形を総当たりで探すコードを書く初学者が多いですが、これは図形が数千個になった瞬間にパフォーマンスが崩壊(O(N)の処理)します。
`Page.ShapeFromIDEx` を使えば、Visioの内部インデックス機構によって高速に一意の図形へアクセスできます。大規模な図面を扱うシステムでは、この差が命取りになります。
—
陥りやすい罠とエラー回避の作法
最後に、実務で絶対にハマるポイントを先回りして共有しておきます。ここを知っているだけで、デバッグの時間が何時間も浮きますよ。
1. グループ化された図形(シェープ)の扱い
- `UniqueID` はグループ内の個々のサブシェープ(子図形)にも付与されます。しかし、グループ図形ごとコピー&ペーストした場合、グループ全体のIDと中の子図形のIDの関係性がどうなるか、意図した挙動になっているか必ずテストしてください。基本的には、マスターとなる基本図形(マスターシェープ)からドロップされたインスタンスごとにユニークなIDが発行されます。
2. 図形を「削除して再作成」した場合
- 当たり前ですが、図形を一度デリートして新しく描き直した場合は、前の `UniqueID` は二度と戻りません。新しく生成し直す必要があります。「データの紐付け」を維持したいのか、「図形そのものの生存」を追いたいのかを用件定義の段階で明確にしておきましょう。
—
おわりに
お疲れ様でした!
今回は `Shape.UniqueID` を使った、ファイル保存後も図形を追跡する上級テクニックを解説しました。
「図形のIDが変わってしまう」というVisioの仕様の壁にぶBつかったとき、この `UniqueID` と `ShapeFromIDEx` のコンビネーションを知っていれば、どんなに複雑な外部連携システムでも余裕で構築できます。
「ここをクリアすれば、Visio VBAの基本はバッチリですよ!」
自信を持って、次の自動化の扉を開いていきましょう。あなたのVBAライフがよりスマートでエキサイティングなものになることを応援しています!
