【テクニカル・上級編】【初心者】Shape.NameとNameUの使い分け:多言語環境でも壊れない図形識別コードの書き方 – Visio VBA解析バイブル

スポンサーリンク

Visio VBAの深淵:`Name`と`NameU`、その「永続性」という名の残酷な真実

諸君、Visioの自動化において、コードが数ヶ月で使い物にならなくなる「負の連鎖」を経験したことはないだろうか。

「昨日まで動いていたマクロが、なぜか動かなくなった」。その原因の9割は、Shapeの識別子を安易に扱ったことにある。Visioというアプリケーションは、UI上の表示名と、エンジンの論理名を厳格に分離している。この境界線を理解せずして、堅牢なシステムを構築することなど不可能だ。

今日は、Visioアーキテクチャの根幹である「名前の永続性」について、現場の死線を潜り抜けてきた我々の流儀を伝授する。

—

1. なぜ `Shape.Name` を使ってはいけないのか

初心者は必ず `Shape.Name` を使う。だが、これは罠だ。`Name` プロパティは「ローカライズされた名前」を返す。

  • 英語環境: `Process`
  • 日本語環境: `プロセス`

もし君のコードが `If shp.Name = “プロセス” Then` と書かれていたら、そのシステムは言語設定を変えた瞬間に崩壊する。これはマルチ言語環境でのグローバル展開が前提となる現代のエンタープライズ開発において、致命的な技術的負債だ。

真の識別子:`NameU` の絶対性

`NameU` (Universal Name) は、Visioが内部的に保持する「言語に依存しない一意の識別子」だ。たとえOSやOfficeの言語設定が変わろうとも、`NameU` は決して変わらない。APIを叩く際、あるいはシステム連携のキーとして使用すべきは、常に `NameU` である。

—

2. 「ID」と「名前」の賢明な使い分け

Visioの `Shape.ID` は、そのドキュメント(Page内)におけるインデックスに過ぎない。図形の削除や追加、あるいはグループ化の解除によって、IDは容易に変動する。

「IDをキーにした状態管理は、砂上の楼閣である」

動的に生成される図形を追跡したい場合、以下の戦術を推奨する。

1. User-defined Cell (カスタムプロパティ) へのID埋め込み:
`Shape.AddNamedRow` を使い、`User.GUID` のようなセクションを作成せよ。ここに一意のキー(UUID等)を書き込むのが、最も堅牢な手法だ。
2. `NameU` の命名規則:
システム側で制御する図形には、接頭辞を付けよ。例: `SYS_FLOW_NODE_001` のように。

—

3. 実践:マルチ言語対応の堅牢な図形探索コード

以下は、メモリのライフサイクルを考慮し、かつ言語設定に依存せずに特定の図形を確実に特定する、実戦的なコードの一例だ。

Option Explicit

‘ 伝説的なエンジニアは、オブジェクトの解放を決して怠らない
Public Sub FindRobustShape()
Dim vsoDoc As Visio.Document
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim targetNameU As String: targetNameU = “MySystem_Process_01”

Set vsoDoc = ActiveDocument
Set vsoPage = vsoDoc.Pages(1)

‘ 探索開始
‘ NameUを比較対象にすることで、環境依存を排除する
For Each vsoShape In vsoPage.Shapes
If StrComp(vsoShape.NameU, targetNameU, vbTextCompare) = 0 Then
Debug.Print “特定成功: ” & vsoShape.Name
‘ ここで処理を行う
Exit For
End If
Next vsoShape

‘ 明示的なオブジェクトの解放
‘ VBAのガベージコレクションを信用してはいけない
Set vsoShape = Nothing
Set vsoPage = Nothing
Set vsoDoc = Nothing
End Sub

—

4. チーフアーキテクトからの提言:レガシーとの対話

もし君が担当しているのが古いレガシーなVisioファイルで、すでに `Name` が入り乱れている場合、無理に全てを `NameU` に書き換える必要はない。

  • ShapeSheetを覗け: `Shape.NameU` を直接変更することも可能だが、既存のリンクが切れるリスクがある。
  • メタデータの分離: 既存の `Name` は「表示用」として割り切り、システム制御用には `Shape.AddNamedRow` で生成した `User` セクションを「論理名」として運用せよ。これが、後方互換性を維持しつつアーキテクチャを近代化する唯一の道だ。

最後に:コードは「対話」である

Visioは、ただの作図ソフトではない。データと図形が複雑に絡み合う「グラフデータベース」の側面を持っている。`Name` と `NameU` の使い分けという極めて小さな違いが、数年後の保守フェーズにおいて、数千時間の工数削減を意味することになる。

オブジェクトのライフサイクルを慈しみ、メモリを愛せ。そして、システムが「将来の自分」を困らせないよう、今日から `NameU` を使いこなすことだ。

それが、自動化の極致を目指す者の最低限の流儀である。

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