【入門編】Shape.ItemFromIDExistsによる安全なID参照:実行時エラーを激減させる設計パターン – Visio VBA解析バイブル

スポンサーリンク

こんにちは!Visioの自動化の世界へようこそ。
マクロの記録ボタンを押してコードを眺めてみたものの、「なんだか難しそうだな…」「動かしたり消したりすると、すぐにエラーで止まってしまうな…」と悩んでいませんか?

大丈夫、安心してください。今日ここで「図形の生存確認」という極意をマスターすれば、あなたの書くマクロは見違えるほど頑丈になり、エラーに怯える必要はなくなります。

今回は、Visio VBAの基礎のキモであるオブジェクトモデルと、現場で絶対に知っておくべき安全な図形参照のテクニックを、優しく丁寧にお伝えしていきますね。ここをクリアすれば、Visio VBAの基本はバッチリですよ!

1. Visio VBAの基本:オブジェクトの「親子関係」を掴もう

VisioのVBAを書くとき、私たちは「Visioの世界がどういう構造になっているか」を頭に思い描く必要があります。これをオブジェクトモデルと呼びます。

Visioの世界は、綺麗なお人形の「マトリョーシカ」や、会社の「組織図」のような階層構造になっています。

  • Application(Visioアプリ全体)
  • Document(今開いているファイル図面)
  • Page(その中の「ページ1」「ページ2」などのキャンバス)
  • Shape(ページの上に描かれた個々の「図形」や「コネクタ」)

VBAで何かを操作するときは、この階段を上から順に降りていくように指定します。
例えば、「アクティブなページの、IDが『1』の図形を取得したい!」と思ったとき、私たちは次のようなコードを書きます。

Dim shp As Visio.Shape
‘ ページの中から ID=1 の図形を掴む
Set shp = ActivePage.Shapes.ItemFromID(1)

……おや?ここでちょっとした疑問が湧きませんか?
「もし、そのID 1番の図形が、さっきうっかり削除されていたらどうなるの?」 と。

2. 恐怖の実行時エラーと、マクロ初心者が陥る罠

プログラムというのは非常に正直(というか融通が利かない)です。
もし存在しない図形のID(例えばユーザーが消してしまったIDなど)を指定して `ItemFromID(1)` を実行すると、Visioは冷酷にこう叫びます。

> 実行時エラー ‘-2032431410’: 指定された名前または ID は存在しません。

このエラーが出ると、マクロはそこで強制終了し、ユーザーの作業データが中途半端に吹き飛ぶことも……。これが、私たちが現場で最も恐れる「クラッシュ」の原因です。

「じゃあ、図形を操作する前に、毎回 `On Error Resume Next`(エラーを無視する魔法の呪文)を書けばいいや!」と思ったそこのあなた。
それは絶対にNGです。エラーを闇雲に握りつぶすコードは、原因不明のバグを生む温床になり、プログラミングの世界では「悪手」とされています。

では、どうすればいいのでしょうか?
ここで登場するのが、今回の主役である `ItemFromIDExists` メソッドです。

3. 救世主登場! `ItemFromIDExists` で安全な生存確認

Visioの Page オブジェクトには、指定したIDの図形が「本当にそこに生きているか?」を事前にこっそり確認してくれる、超優秀なメソッドが用意されています。

それが `Page.ItemFromIDExists(ID, shpVar)` です。

このメソッドのすごいところは、
1. 指定したIDの図形が存在するかどうかを `True` または `False` で教えてくれる。
2. もし存在していれば、ついでにその図形オブジェクトをサッと変数(`shpVar`)に格納してくれる。

という、一石二鳥の安全設計になっている点です。
百聞は一見にしかず。実際のコードを見てみましょう。

実践:エラーを完全に防ぐ安全な図形参照パターン

以下のコードは、特定のID(ここでは例として ID: 5)を持つ図形が存在するか確認し、存在する場合のみ色を赤く変えるサンプルです。

Sub SafeShapeAccessExample()
Dim targetPage As Visio.Page
Dim targetID As Long
Dim foundShape As Visio.Shape

‘ 操作対象のページを取得(ここではアクティブページ)
Set targetPage = ActivePage

‘ 調べたい図形のID(例として ID: 5)
targetID = 5

‘ 【重要】ItemFromIDExistsで生存確認と取得を同時に行う!
‘ 存在していれば True が返り、foundShape に図形がセットされます
If targetPage.ItemFromIDExists(targetID, foundShape) Then

‘ — 生存確認OK(図形は確実に存在します) —
Debug.Print “ID: ” . targetID . ” の図形を発見しました!”

‘ 安全にプロパティを操作する
foundShape.Cells(“FillForegnd”).ResultIU = RGB(255, 0, 0) ‘ 赤色に変更

Else

‘ — 生存確認NG(すでに削除されている等) —
MsgBox “ID: ” . targetID . ” の図形はすでに存在しません。”, vbExclamation, “安全装置作動”

End If

End Sub

このコードの美しいところは、エラーが発生する前に「いる・いない」を判定しているため、VBAの実行時エラーが絶対に起きない点です。これぞ、プロのエンジニアが現場で使う堅牢な設計パターンの基本形です。

4. チーフアーキテクトからの実践アドバイス:IDはいつ変わる?

実務でVisioマクロを組んでいると、「さっき控えた図形のID、後から使おうとしたらエラーになった」という現象によく遭遇します。

  • 図形を新しく作ると、新しいIDが採番される。
  • 図形を削除すると、そのIDは「空き番」になり、基本的に再利用されない(インクリメントされ続ける)。
  • ファイルを保存し直したりすると、内部のID管理が変わることはないが、別ページにコピペするとIDは新しく振り直される。

特に、複数の図形をループで処理しながら削除したり、ユーザーのインタラクティブな操作と連動させるツールを作るとき、図形のIDは「いつの間にか消えているかもしれない儚いもの」だと心得ておく必要があります。

だからこそ、後からIDで図形を再参照するシーン(ボタンクリックのイベント処理や、ログからの復元処理など)では、必ず `ItemFromIDExists` を挟む癖をつけてください。

まとめ

  • Visioのオブジェクトモデルは、Application → Document → Page → Shape の階層構造。
  • 存在しない図形IDを `ItemFromID` で直接指定すると、容赦なく実行時エラーになる。
  • `On Error Resume Next` でごまかさず、`Page.ItemFromIDExists` を使ってスマートに生存確認を行うのがプロの作法。

この設計パターンを取り入れるだけで、あなたの作るVisioマクロの信頼性は劇的に向上します。「動くけれど壊れやすいマクロ」から、「美しく、打たれ強いマクロ」へ。ぜひ明日からの開発に取り入れてみてくださいね。

それでは、素晴らしいVisio自動化ライフを!

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