【実務・中級編】Shape.Is1Dプロパティを活用した図形分類の自動化:コネクタと通常シェイプを完全に判別するアルゴリズム – Visio VBA解析バイブル

スポンサーリンク

Visio VBAの深淵へ:Shape.Is1Dで「コネクタと図形」を完全制圧するアーキテクチャ設計

Visioの自動化において、最も頻繁に遭遇し、かつ最も多くのエンジニアが「適当な判定」で逃げている境界線がある。それが「1次元図形(コネクタ)」と「2次元図形(ノード)」の識別だ。

多くの初学者は`Shape.Type`や`Master`の名前を文字列で判定しようとする。だが断言しよう。その設計は、将来的に必ず「名無しのマスター」や「グループ化された複雑な図形」によって破綻する。

今回は、Visioのオブジェクトモデルの根幹である`Shape.Is1D`プロパティを軸に、堅牢かつ拡張性の高いシェイプ分類アルゴリズムを伝授する。

なぜ `Shape.Is1D` なのか?

Visioにおいてシェイプは「1次元(線)」か「2次元(面)」かの二元論で語られる。

  • 1次元図形: 端点(BeginX/Y, EndX/Y)を持ち、他の図形と接続関係を構築する。
  • 2次元図形: 幅(Width)と高さ(Height)を持ち、ピン(PinX/Y)を中心とした座標系で定義される。

`Shape.Is1D`は、シェイプの挙動そのものを規定するフラグだ。これを活用すれば、「グループ化されているか否か」「どんなマスターシェイプか」というメタデータに依存せず、シェイプの「物理的特性」に基づいた純粋な判定が可能になる。

実践:堅牢なシェイプ分類アルゴリズム

プロダクション環境で最も重要なのは「例外処理」と「パフォーマンス」だ。全シェイプを走査する際、単にループを回すのではなく、「処理対象外を即座に弾く」ガード節の設計が重要となる。

以下のコードは、ページ内の全シェイプを走査し、役割ごとに処理を分岐させるためのテンプレートだ。

‘ —————————————————————————
‘ @Description: Visioシェイプのタイプを判定し、適切に分岐処理を行う堅牢なスニペット
‘ @Author: Chief Architect
‘ —————————————————————————
Public Sub ProcessShapesSmartly()
Dim shp As Visio.Shape
Dim pg As Visio.Page

Set pg = ActivePage

‘ ページ内の全シェイプを走査(グループ化されたシェイプも再帰的に扱う場合は再帰関数を推奨)
For Each shp In pg.Shapes
‘ 1. ガード節:処理対象外のメタ情報を除外(必要に応じて)
If shp.LayerMember <> “IgnoreLayer” Then

‘ 2. 核心:Is1Dによる分岐
If shp.Is1D Then
‘ — 1次元図形(コネクタ)の処理 —
Call HandleConnector(shp)
Else
‘ — 2次元図形(アイコン/ノード)の処理 —
Call HandleNode(shp)
End If

End If
Next shp
End Sub

Private Sub HandleConnector(ByRef shp As Visio.Shape)
‘ コネクタ特有の処理:接続点の取得や線のスタイル変更
‘ 例: shp.Cells(“BeginX”).ResultIU…
Debug.Print “Connector detected: ” & shp.Name
End Sub

Private Sub HandleNode(ByRef shp As Visio.Shape)
‘ 2次元図形特有の処理:リサイズ、テキスト書き換え、座標移動
‘ 例: shp.Cells(“Width”).ResultIU…
Debug.Print “Node detected: ” & shp.Name
End Sub

開発現場で陥る「罠」と解決策

1. グループシェイプの扱い

`pg.Shapes`はトップレベルのシェイプしか返さない。グループ化された中のシェイプまで操作したい場合、`shp.Shapes.Count > 0`で再帰処理を実装する必要がある。この際、`Is1D`はグループ全体にも適用されるため、階層構造を意識した設計が不可欠だ。

2. データベース連携時の注意

VisioからSQL ServerやExcelへデータを吐き出す際、`shp.ID`は編集によって変更される可能性がある。「永続的なID(Unique ID)」が必要な場合は、`shp.UniqueID(visGetOrMakeGUID)`を使用すること。これを使えば、図形を移動・コピーしても論理的な整合性を保てる。

3. パフォーマンスの最適化

画面更新(`Application.ScreenUpdating = False`)は必須だ。また、頻繁に`Cells`プロパティにアクセスするとオーバーヘッドが激増する。処理するプロパティが確定している場合は、あらかじめ`Cell`オブジェクトをキャッシュ(変数にセット)してからループを回すのが、プロのエンジニアの流儀だ。

最後に:自動化の先にあるもの

`Is1D`による分類は、単なる「条件分岐」ではない。それは、Visioという複雑な空間を「論理的なデータ構造」として捉え直すための第一歩だ。

コードを書くとき、常に自問自答してほしい。「このロジックは、半年後の自分が仕様変更を加えたときに、一箇所変えるだけで完結するか?」と。堅牢な設計とは、美しいコードではなく、変更に強いコードのことを指す。

この知見が、あなたの業務を劇的に加速させる一助となれば幸いだ。次は、このコネクタの接続情報を抽出する「グラフ理論的アプローチ」について議論しよう。準備はいいか?

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