Visioの「Shape.ID」を信じるな:永続的トラッキングで構築する堅牢なデータ連携基盤
Visioで自動化ツールを開発していると、必ず突き当たる壁がある。「図形を特定できない」という問題だ。
多くの初心者は `Shape.ID` をキーにデータベースと連携しようとする。だが、プロの現場ではそれは「時限爆弾」と同義だ。VisioのIDは、コピー&ペースト、グループ化の解除、あるいはファイル再保存の過程で平気で書き換わる。
今日は、Visioのオブジェクトモデルにおける「真の識別子」である `UniqueID` を活用し、外部データと永続的な紐付けを行うためのアーキテクチャを伝授する。
—
1. なぜ「Shape.ID」では不十分なのか
Visioの `Shape.ID` は、そのページ内でのインデックスに過ぎない。
- 再利用性ゼロ: 図形を別のページへ移動したり、グループ化を解除したりすれば、IDは即座にリサイクルされる。
- 不整合の温床: 外部DBとIDで紐付けている場合、Visio上で「コピー&ペースト」を一度実行しただけで、DB上のレコードと図形との関係性が崩壊する。
これに対し、`Shape.UniqueID` は、Visioが内部的に生成する GUID (Globally Unique Identifier) を利用する。これは図形がどこへ移動しようとも、ファイル間で移動させない限り不変だ。
—
2. 永続的トラッキングの設計思想
堅牢なシステムを構築するためのルールは3つだ。
1. 強制割り当て: すべての重要図形には、生成時(あるいは読み込み時)に必ず `UniqueID` を付与する。
2. 存在確認: `UniqueID` を取得する際、未割り当てなら自動生成するラッパー関数を必ず経由させる。
3. インデックス化: 検索が必要な場合は、全シェイプをループさせるのではなく、`UniqueID` をキーとした `Scripting.Dictionary` にキャッシュを構築する。
—
3. プロダクションコード:UniqueIDマネージャー
以下のコードは、既存の図形にGUIDが存在しなければ付与し、存在すればその値を返すという「防御的プログラミング」の核心部分だ。
Option Explicit
‘ 必要な定数:UniqueIDの生成モード
‘ visGetOrMakeGUID: 存在しなければ生成、あれば取得
Private Const visGetOrMakeGUID As Long = 1
”’
”’
Public Function GetPersistentID(shp As Visio.Shape) As String
Dim guid As String
‘ UniqueIDを取得(すでに存在すればそのまま返る)
‘ 第2引数に visGetOrMakeGUID を指定するのがポイント
shp.UniqueID visGetOrMakeGUID, guid
GetPersistentID = guid
End Function
”’
”’
Public Function FindShapeByUniqueID(pg As Visio.Page, targetGUID As String) As Visio.Shape
Dim shp As Visio.Shape
Dim currentGUID As String
For Each shp In pg.Shapes
‘ GUIDが空の図形をスキップして高速化
If shp.HasUniqueId Then
shp.UniqueID 0, currentGUID ‘ 0は取得のみ
If currentGUID = targetGUID Then
Set FindShapeByUniqueID = shp
Exit Function
End If
End If
Next
End Function
—
4. アーキテクトからの助言:実務上の注意点
パフォーマンスの最適化
`Shape.UniqueID` へのアクセスは、実はそこまで高速ではない。大規模な図面(1,000シェイプ以上)で、すべての図形を走査して検索を行うと、ツールのレスポンスは劇的に低下する。
解決策: ツール起動時に一度だけ全図形を走査し、`Dictionary` オブジェクトに `GUID -> Shapeオブジェクト` のマップを作成しておくこと。これが「秒単位」で動くツールと「数分待たされる」ツールの境界線だ。
データベース連携の注意点
データベースの主キー(Primary Key)としてGUIDを扱う場合、以下の点に注意せよ。
- 文字列としての比較: VisioのGUIDは `{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}` という形式だ。DB側の型は `CHAR(38)` または `UNIQUEIDENTIFIER` を推奨する。
- マッピングの完全性: 万が一GUIDが重複・消失した際の「再同期ロジック(図形の全走査によるID再割り当て)」をツールに組み込んでおくことが、運用保守におけるリスクヘッジとなる。
—
最後に:プロのエンジニアであるために
「動けばいい」というコードは、数ヶ月後に必ず自分自身を苦しめる。
Visio VBAにおいて、オブジェクトのIDを管理するということは、単にプロパティを読み書きする行為ではない。「図形のライフサイクルを設計する」という高度なエンジニアリングだ。
この `UniqueID` を基軸にした設計を取り入れれば、貴方の開発するツールは、数千回繰り返される修正やコピー&ペーストに耐えうる、真に堅牢なシステムへと進化するはずだ。
次は、このGUIDをカスタムプロパティ(Shape Data)として書き出し、外部データと完全にリンクさせる手法について深掘りしよう。健闘を祈る。
