Visio VBAの深淵:`Is1D`プロパティが握るシェイプ判定の境界線と最適化の実践
Visioの自動化において、最も頻発し、かつ最も多くのエンジニアが「なんとなく」実装して破綻させるのが、コネクタと通常シェイプの判別だ。
多くの初学者は`Type`プロパティやレイヤー名に頼るが、それは脆弱なレガシーコードへの入り口に過ぎない。シェイプの幾何学的本質を見抜く唯一のプロパティ、それが`Shape.Is1D`である。今回は、このプロパティを軸にした堅牢な自動化アーキテクチャの構築法を伝授する。
—
1. なぜ `Is1D` なのか:幾何学的な本質の分離
Visioのオブジェクトモデルにおいて、`Is1D`プロパティは単なるフラグではない。それはVisioの描画エンジンが、そのシェイプを「座標ベースのパス(線)」として扱うか、「矩形領域(ボックス)」として扱うかの分岐点だ。
- 1Dシェイプ(コネクタ等): `BeginX/Y` と `EndX/Y` という始点と終点の座標で定義される。
- 2Dシェイプ(四角形、アイコン等): `PinX/Y`(中心点)と `Width/Height` で定義される。
この違いを理解せずに座標計算を行えば、グループ化されたシェイプや回転のかかった図形で計算誤差が積み重なり、最終的に描画が崩壊する。
—
2. 実装のベストプラクティス:効率的なシェイプ走査アルゴリズム
単にループを回すだけでは、数千シェイプを超える大規模図面ではメモリの浪費を招く。以下は、オブジェクトの明示的解放と、処理効率を考慮した走査コードの雛形だ。
Option Explicit
”’
”’
Public Sub AnalyzeShapesOptimized()
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Set vsoPage = ActivePage
‘ 描画の更新を一時停止し、パフォーマンスを最大化
Application.ScreenUpdating = False
On Error GoTo Cleanup
For Each vsoShape In vsoPage.Shapes
‘ 1Dか否かを判定:ここが分岐の黄金律
If vsoShape.OneD Then
‘ — コネクタ処理 —
‘ 例: 接続先IDの取得や、線種の変更など
Debug.Print “1D Shape found: ” & vsoShape.Name
Else
‘ — 2Dシェイプ処理 —
‘ 例: 矩形領域の座標移動やテキスト置換など
Debug.Print “2D Shape found: ” & vsoShape.Name
End If
Next vsoShape
Cleanup:
‘ オブジェクトの明示的解放
Set vsoShape = Nothing
Set vsoPage = Nothing
Application.ScreenUpdating = True
End Sub
—
3. シニアエンジニアが押さえるべき「罠」と「回避策」
A. グループ化されたシェイプの再帰的走査
`Page.Shapes`はトップレベルのシェイプしか拾わない。グループ内のシェイプを制御するには、再帰関数(Recursive Function)による探索が必須だ。その際、スタックオーバーフローを避けるために、`vsoShape.Type = visTypeGroup` の判定を前段に置くこと。
B. Windows APIによる座標変換の精度向上
Visioの座標系は内部的にポイント(1/72インチ)で管理されているが、API連携などでピクセル単位の操作が必要な場合、`ActiveWindow.PageToDevice` を使用せよ。不正確な算術演算は、微小な浮動小数点誤差を蓄積させ、数年後の保守フェーズで致命的なバグとなる。
C. メモリ管理の極意
VBAはCOMラッパーである。`For Each`ループ内で大量のオブジェクトを生成・破棄する場合、`DoEvents`を適切に挟むことで、UIスレッドを殺さずにメモリのGC(ガベージコレクション)を促すのが、安定したシステムを構築するコツだ。
—
4. 結び:アーキテクトとしての矜持
「とりあえず動くコード」は、誰にでも書ける。しかし、「10年後の図面データ構造の変化にも耐えうるコード」を書くには、オブジェクトモデルの挙動を根本から理解する必要がある。
`Is1D`を使いこなし、コネクタの端点管理を厳密に行うことは、単なる自動化を超えた「データとしての図面」を維持する行為だ。貴殿の現場が、もし泥沼のレガシー保守に苦しんでいるのなら、まずはこのシェイプ分類のロジックから刷新してみてほしい。
それこそが、伝説的なエンジニアが辿るべき、唯一の道である。
