【入門編】Shape.SpatialRelationプロパティを活用した図形同士の「包含・重なり・近接」空間判定エンジン – Visio VBA解析バイブル

スポンサーリンク

こんにちは!Visio VBAの世界へようこそ。
マクロの記録ボタンを押して「動いたはいいけれど、中身が全然読めない……」と頭を抱えていませんか?

大丈夫、安心してください。今日ここでお話しする「オブジェクトモデルの本質」「空間判定API」をマスターすれば、あなたのVisio自動化スキルは一気にプロの領域へと駆け上がります。

今回は、自前で面倒な三角関数や座標計算(ピタゴラスの定理など)を一切することなく、Visioの心臓部(エンジン)に図形同士の関係をスパッと判定させる魔法のようなプロパティ、`Shape.SpatialRelation`を使った空間判定エンジンの作り方を徹底解説します。

ここをクリアすれば、Visio VBAの基本はバッチリですよ。さあ、一緒に扉を開けましょう!

1. そもそもVisio VBAの「オブジェクトモデル」ってなに?

VisioのVBAを操る上で、まず絶対に避けて通れないのがオブジェクトモデル(階層構造)です。
Visioの世界は、まるでロシアの民芸品「マトリョーシカ」のように、大きな入れ物の中に小さな入れ物がきれいに並んでいます。

Application (Visioアプリ全体)
└─ Documents (開いている図面ファイル群)
└─ Document (特定の図面)
└─ Pages (ページ群)
└─ Page (特定のページ)
└─ Shapes (図形群)
└─ Shape (個々の図形:これが今回の主役!)

初心者がやりがちな失敗は、今どの階層にいるのかを見失うことです。「あれ、このシェイプはどのページのやつだっけ?」とならないよう、VBAを書くときは「今、どのApplicationの、どのDocumentの、どのPageの、どのShapeを触っているのか」を頭の中で常に意識するのが、一流のエンジニアへの第一歩です。

2. 数学の計算は不要!`SpatialRelation` という最強の武器

例えば、「ある四角形の枠の中に、この丸い図形がすっぽり収まっているか?」を判定したいとします。
素朴なプログラミング初心者は、四角形の $(X, Y)$ 座標を取り出し、幅と高さを足して……と、一生懸命算数の計算コードを書き始めがちです。

ちょっと待って!それ、車輪の再発明です。

Visioには、図形同士の位置関係をミリ単位(正確には内部のマスター単位)で一瞬にして判定してくれる、超高性能な空間認識エンジンが最初から備わっています。それが `Shape.SpatialRelation` プロパティ です。

SpatialRelation の基本構文

lngResult = ShapeA.SpatialRelation(ShapeB, Tolerance, Flags)

  • ShapeA: 基準となる図形
  • ShapeB: 比較対象の図形
  • Tolerance: 許容値(通常は `0` でOK。微小な隙間を無視したい場合にピクセル単位で指定)
  • Flags: 判定のオプション(通常は `visSpatialIncludeHidden` などを指定)

このメソッドを実行すると、`visSpatialContained`(含まれている)や `visSpatialOverlap`(重なっている)といった定数(数値)が返ってきます。これを使えば、複雑な図面のヒットテストや、フローチャートの自動検証システムが驚くほど簡単に作れてしまうのです。

3. 実践!「包含・重なり・近接」を判定するエンジンを作ろう

それでは、開発現場でそのままコピペして使える実践的なコードを公開しましょう。
このコードは、選択した2つの図形のうち「親(A)」に対して「子(B)」がどういう関係にあるのかをイミディエイトウィンドウにビシッと出力するエンジンです。

準備

Visioの適当なページに図形を2つ描き、両方を選択した状態でこのマクロを実行してください。

Sub RunSpatialRelationEngine()
‘ =========================================================================
‘ 伝説のチーフアーキテクトが贈る:Visio空間判定エンジン
‘ =========================================================================
Dim vsoSelection As Visio.Selection
Dim shpTarget As Visio.Shape
Dim shpSource As Visio.Shape
Dim lngRelation As Long

‘ 1. 現在の選択状態を取得
Set vsoSelection = ActiveWindow.Selection

‘ 2. 選択エラーハンドリング(2つ選択されていることが絶対条件)
If vsoSelection.Count <> 2 Then
MsgBox “判定するには、正確に2つの図形を選択してください。”, vbExclamation, “空間判定エンジン”
Exit Sub
End If

‘ 3. 比較する2つのシェイプを変数に格納
‘ ※最初に選択したものをターゲット(A)、後から選択したものをソース(B)とします
Set shpTarget = vsoSelection(1)
Set shpSource = vsoSelection(2)

‘ 4. SpatialRelation メソッドの実行
‘ 第2引数: 許容値 (0)
‘ 第3引数: フラグ (非表示図形も含める場合は visSpatialIncludeHidden を使用)
lngRelation = shpTarget.SpatialRelation(shpSource, 0, visSpatialIncludeHidden)

‘ 5. 返ってきた結果(ビットマスク)をスマートに解析して出力
Debug.Print “=== 空間判定結果 ===”
Debug.Print “ターゲット図形 ID: ” & shpTarget.ID
Debug.Print “ソース図形 ID: ” & shpSource.ID

‘ VisioのSpatialRelationは複数のフラグが同時に立つことがあるため、And演算子で評価します
If (lngRelation And visSpatialContained) Then
Debug.Print ” 【判定】ソース図形は、ターゲット図形に完全に『含まれています(Contained)』。”
End If

If (lngRelation And visSpatialOverlap) Then
Debug.Print ” 【判定】2つの図形は『重なり合っています(Overlap)』。”
End If

If (lngRelation And visSpatialTouching) Then
Debug.Print ” 【判定】2つの図形は『接触しています(Touching)』。”
End If

If lngRelation = 0 Then
Debug.Print ” 【判定】2つの図形は完全に離れています(交差なし)。”
End If

Debug.Print “========================”
MsgBox “判定が完了しました。VBAの[イミディエイト ウィンドウ]を確認してください。”, vbInformation, “完了”
End Sub

4. 現場でありがち!陥りやすいエラーと回避の知見

ここで、現場のエンジニアが思わずハマる「Visio VBAの闇(罠)」をいくつか共有しておきます。知っているだけでデバッグ時間が何時間も浮きますよ。

罠1: 選択順序(Selectionのインデックス)の不安定さ

Visioの `Selection` コレクションは、ユーザーがクリックした順序や図形の重なり順(Zオーダー)によって、`vsoSelection(1)` と `vsoSelection(2)` が入れ替わることがあります。
厳密な判定を行いたい場合は、図形の `ID` の大小を比較してソートするか、ユーザーフォームやダイアログで明示的に「親」「子」を指定させるUI設計にしましょう。

罠2: グループ化された図形(Group Shape)の悲劇

`Shape` オブジェクトが「グループ」である場合、その中にある「子シェイプ(サブシェイプ)」と、通常の図形をそのまま `SpatialRelation` にかけると、座標系の基準(ローカル座標とページ座標)のズレから、おかしな判定結果を返すことがあります。
高度な自動化を行う際は、必ず `.Cells(“PinX”).ResultIU` などを経由してページ全体の絶対座標系に換算されているかを意識してください。

まとめ:Visio VBAの基礎をクリアしたあなたへ

お疲れ様でした!今回はVisio VBAの基礎であるオブジェクトモデルの概念と、数学の計算をスキップして図形関係を丸裸にする `SpatialRelation` プロパティについて解説しました。

「マクロの記録」というオムツを卒業し、こうしたネイティブなAPIやオブジェクトの振る舞いを理解できるようになると、Visioは単なるお絵描きソフトから、「インテリジェントな図面自動生成・検証プラットフォーム」へと姿を変えます。

ここをクリアしたあなたなら、どんな複雑な業務フロー図の自動検証ツールだって作れるはずです。
ぜひ、あなたの業務の自動化にこの「空間判定エンジン」を組み込んでみてください。感動的なスピードアップが待っていますよ!

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