【実務・中級編】Shapeオブジェクトの基礎:IDとNameプロパティの違いを理解して狙った図形を確実につかむ – Visio VBA解析バイブル

スポンサーリンク

Visio VBAを掌握せよ:Shapeの「ID」と「Name」を使い分け、堅牢な自動化を実現する極意

業務自動化の現場で、Visioの自動化ほど「脆弱なコード」が量産されやすい領域はない。
「動けばいい」という甘い考えで書かれたマクロは、図形を一つコピーした瞬間に、あるいは誰かが図形を少し動かしただけで沈黙する。

VisioのShapeオブジェクトを確実に掴むための識別子。この根本的な理解なくして、大規模な業務ツールを構築することは不可能だ。今回は、多くのエンジニアが混同する「ID」と「Name」の本質的な違いと、プロダクション環境で採用すべきセキュアな設計指針を授ける。

1. IDとName:その本質的な「寿命」を知る

Visioにおいて、Shapeを一意に特定するためのプロパティには `ID` と `Name` がある。この二つの特性を理解していない者は、運任せのコードを書いているのと同じだ。

Shape.ID:揮発性の高い「生存証明」

  • 特性: ページ内での出現順や処理順に基づき、Visioが自動採番する整数。
  • リスク: 非常に不安定。図形の削除や追加、あるいはファイルの保存・再読み込みによって容易に変化する。
  • 用途: ループ処理内での一時的な参照など、「その場限り」の識別にのみ使用する。

Shape.Name:人間とシステムが共有する「論理名」

  • 特性: `Sheet.1` のようなシステムが生成するデフォルト名と、ユーザーが任意に設定できる名前がある。
  • リスク: 重複の可能性(Visioは同名の図形を許容する仕様がある)。
  • 用途: 「特定の役割を持つ図形」の識別。ただし、そのまま使うのは危険である。

2. 「なぜ動かないのか」を解決する:セキュアな図形取得の設計

初心者は `ActivePage.Shapes(“プロセス1”)` のような書き方をし、名前の重複でエラーを吐かせて途方に暮れる。
プロは、「IDやNameに依存しすぎない設計」あるいは「User-defined Cell(ユーザー定義セル)を用いた強固な識別」を行う。

推奨される設計:ShapeSheetを活用した「タグ付け」

Shapeの `Name` を信頼するのではなく、ShapeSheetに独自のプロパティ(Userプロパティ)を埋め込み、それをキーにして検索するのが最も堅牢だ。

実践的な検索関数:保守性を極めたコード例

以下は、名前の重複を避け、かつ将来的な仕様変更にも耐えうる「図形取得メソッド」の雛形だ。

‘ @description 特定の名前を持つShapeを安全に取得し、存在確認まで行う
‘ @param targetPage 検索対象のPageオブジェクト
‘ @param shapeName 検索したい図形のName
‘ @return 取得できた場合はShapeオブジェクト、失敗時はNothing
Public Function GetShapeByName(ByVal targetPage As Visio.Page, ByVal shapeName As String) As Visio.Shape
Dim shp As Visio.Shape

‘ 名前による検索は直接アクセスせず、ループで走査して検証する
‘ Visioでは同名の図形が複数存在し得るため、厳密に制御する
For Each shp In targetPage.Shapes
If shp.Name = shapeName Then
Set GetShapeByName = shp
Exit Function
End If
Next shp

‘ 見つからなかった場合は明示的にNothingを返し、呼び出し元で制御する
Debug.Print “Warning: Shape ‘” & shapeName & “‘ not found.”
End Function

3. 現場で生き残るための「鉄則」

現場で運用されるツールには、以下の3つのルールを強制せよ。

1. IDはメモリ内で完結させる: IDをデータベースや設定ファイルに保存してはいけない。再起動後に別人が図形を移動させれば、全く別の図形を操作することになる。
2. グループ化を恐れる: `Shapes` コレクションはグループ内の図形を直列に扱う。深い階層の図形を操作する場合は、再帰的な探索アルゴリズムを実装しなければならない。
3. ユーザー定義セルを「名札」にする:
もし図形を確実に特定したいのであれば、Visioの画面上で「ShapeSheet」を開き、`User-defined Cells` セクションに `Prop.ID` 等の行を追加し、そこにユニークな文字列を書き込め。VBAからは `.Cells(“User.ID”).ResultStr(“”)` で取得できる。これが最強の識別子だ。

結論:コードは「意図」を語るべき

「適当なIDで図形を掴む」コードは、技術的負債以外の何物でもない。
今回紹介したように、名前を走査し、必要であればユーザー定義セルでメタデータを持たせるという設計は、一見手間がかかるように見えるだろう。しかし、「仕様変更でコードが壊れない」という圧倒的な保守性は、自動化ツールを「使い捨てのスクリプト」から「資産」へと昇華させる。

Visioの深淵は深い。だが、オブジェクトのライフサイクルさえ掌握すれば、恐れることは何もない。今日から、君のコードに「確実性」という名の魂を込めてほしい。

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