こんにちは!Visioの自動化の世界へようこそ。
マクロの記録ボタンを押して生成されたコードを眺めてみたものの、「なんだか難しそうなIDが出てきて、狙った図形を全然コントロールできないぞ…?」と頭を抱えていませんか?
大丈夫、安心してください。ここをクリアすれば、Visio VBAの基本はバッチリですよ。
今日は、Visio VBAにおいて最も頻出かつ、避けて通れない「Shape(図形)の識別方法」について、オブジェクトモデルの本質を交えながら優しく、そして深く解説していきます。
マクロの記録から一歩抜け出して、「意図した図形をプログラムから確実につかまえる」ための極意を一緒にマスターしましょう!
—
1. なぜVisioの図形指定は迷子になりやすいのか?
Excel VBAであれば、セルは `Range(“A1”)` や `Cells(1, 1)` で一意に特定できます。しかし、Visioの世界は少し複雑です。
Visioのページ(Page)の上には、たくさんの図形(Shape)が配置されます。これらをプログラムから操作するとき、私たちは「どの図形を操作したいのか」をVisioに正確に伝えなければなりません。
ここで多くの初心者が混乱するのが、図形を識別するための「3つの顔」の存在です。
1. ShapeID(シェイプID)
2. Name(名前)
3. NameU(ユニバーサル名)
「えっ、図形に名前って一つじゃないの?」と思った方、鋭いですね。実は、Visioの裏側ではこれら3つが全く異なる役割を持っています。それぞれの正体を丸裸にしていきましょう。
—
2. 徹底比較:ShapeID vs Name vs NameU
① ShapeID(シェイプID)とは?
- 正体: ページ内で図形が作られた順番に割り振られる「背番号(整数)」です。
- 特徴: `ActivePage.Shapes.ItemByID(1)` のように使います。処理速度が最も速く、VBAからの一括処理などで好まれます。
- 弱点: 図形を削除したり新しく作ったりすると、背番号が変わりまくるという気まぐれな性質を持っています。そのため、コードに直書きして固定で使うのは非常にリスキーです。
② Name(名前)とは?
- 正体: Visioの画面上(シェイプシートなど)で表示される、人間向けの「表示名」です(例: `プロセス.12` など)。
- 特徴: `ActivePage.Shapes.Item(“プロセス.12”)` のように指定できます。
- 弱点: Excelなどと同様に、PCの表示言語(ロケール)に依存します。 例えば、日本語版Visioで記録した `プロセス.1` という名前は、英語版のVisio環境で実行するとエラーになります。チーム共有や配布するツールには向きません。
③ NameU(ユニバーサル名)とは? —— 【プロのイチオシ】
- 正体: 言語の違いを超越した、Visio内部での「戸籍上の本当の名前」です(例: `Process.12`)。
- 特徴: いつでも英語ベースの不変の名前を返します。
- 強点: 言語環境(日本語版・英語版など)が変わっても絶対にブレません。実務でマクロを組むなら、名前で図形を特定するなら `NameU` を使うのがプロの鉄則です。
—
3. 実践!狙った図形を確実に取得するコード
百聞は一見にしかず。実際にVBAのコードを書いて、ページ上の図形を確実に取得してみましょう。
以下のコードは、アクティブページの中から特定の図形(ここではNameUが “Rectangle” のもの、あるいは特定のShapeIDを持つもの)を探し出し、その色を変える実用的なサンプルです。
Sub GetSpecificShapeSample()
Dim shpTarget As Shape
Dim targetNameU As String
Dim found As Boolean
‘ 探したい図形のNameU(ユニバーサル名)を指定
targetNameU = “Rectangle”
found = False
‘ 1. 【最も確実な方法】NameUでループを回して図形を探す
For Each shpTarget In ActivePage.Shapes
‘ NameUを比較(大文字小文字を区別しない場合は StrComp や UCase を使用)
If shpTarget.NameU Like targetNameU & “” Then
found = True
Exit For ‘ 見つかったらループを抜ける
End If
Next shpTarget
‘ 見つかった場合の処理
If found Then
MsgBox “図形が見つかりました! ID: ” & shpTarget.ID & ” / NameU: ” & shpTarget.NameU, vbInformation
‘ 例:見つかった図形の塗りつぶしを赤色(RGB: 255, 0, 0)に変更する
shpTarget.CellsU(“FillForegnd”).FormulaU = “RGB(255, 0, 0)”
Else
MsgBox “指定された図形はページ内に存在しません。”, vbExclamation
End If
End Sub
コードのポイント解説
- `For Each shpTarget In ActivePage.Shapes`: ページ上のすべての図形を総当たりでチェックする、最も安全で確実な走査方法です。
- `NameU Like targetNameU & “”`: Visioは同じマスターから図形を増殖させると、`Rectangle.1`, `Rectangle.2` のように後ろに番号が振られます。`Like` 演算子を使うことで、親の名前をベースにしつつ確実に捕捉できます。
- `CellsU(“FillForegnd”)`: プロパティ設定にも「U(ユニバーサル)」がついています。シェイプシートのセルを操作するときも、言語非依存の `CellsU` を使うのがモダンなVisio VBAの作法です。
—
4. 陥りやすいエラーと回避のテクニック
現場でよくある失敗パターンと、その回避策を押さえておきましょう。
罠①:ShapeIDを過信してエラーになる
> エラー例: `ItemByID` で指定した番号の図形が消されていて、`Run-time error ‘-20320’: 該当する項目が見つかりません。` が発生する。
- 回避策:
不特定多数が触る図面や、動的に図形が追加・削除されるプロセスでは、ShapeIDをハードコーディング(直書き)してはいけません。 必ず `NameU` で検索するか、後述の「セルのカスタムプロパティ(Prop)」を活用しましょう。
罠②:日本語のNameを指定して他PCで動かない
> エラー例: 自分のPCでは動いたのに、海外拠点のPCや英語版Visioで動かした途端に図形が見つからなくなる。
- 回避策:
前述の通り、`Name` ではなく `NameU` を使用する癖をつけましょう。
—
5. さらにワンランク上のテクニック:独自IDを付与する
大規模なシステム連携や、何百個もの図形を制御する業務ツールを作る場合、Visioが勝手に振る `NameU` や `ShapeID` 頼みでは限界が来ます。
そんなときは、図形の「シェイプデータ(カスタムプロパティ)」に一意のID(例: `MyID = “Step_001″`)をあらかじめ埋め込んでおき、VBA側からそのカスタムプロパティをスキャンして図形を特定します。
‘ (概念イメージ)カスタムプロパティの値で図形を特定する
If shpTarget.CellExistsU(“Prop.MyCustomID”, False) Then
If shpTarget.CellsU(“Prop.MyCustomID”).ResultStr(“”) = “Step_001” Then
‘ この図形がターゲット!
End If
End If
この手法を使えば、図形が移動しようが、名前が自動採番で変わろうが、プログラムから絶対に迷子にならない最強の図形特定システムが完成します。
—
まとめ
- ShapeID は速いが、図形の増減で変わるため固定値での指定には向かない。
- Name は日本語環境に依存するため、多言語・チーム開発ではリスクが高い。
- NameU は言語に依存せず、不変であるため、名前で特定するならベストチョイス。
- 本格的な自動化では、シェイプデータ(プロパティ)を活用した独自ID管理も視野に入れよう。
Visioのオブジェクトモデルは、一度コツを掴んでしまえばこれほどロジカルで美しいものはありません。ぜひ今回の知見をご自身の開発現場に持ち帰り、スマートで頑健なVisioマクロを組み上げてみてくださいね。
あなたのVisio自動化ライフが、より快適でクリエイティブなものになりますように!
