Visio VBAの深淵:`BoundingBox`でレイアウトの「崩れ」を物理演算のごとく検知せよ
Visioで複雑な図面を扱う際、最も頭を悩ませるのは「意図しない図形の重なり」と「領域外への飛び出し」だ。手動チェックなどという非生産的な作業は今すぐ捨てろ。今回は、Visioのオブジェクトモデルを掌握し、プログラムでレイアウトの整合性を担保するための「幾何学的検知アルゴリズム」を伝授する。
中途半端なコードは、数千個の図形が並ぶ巨大ドキュメントで必ずメモリリークや計算ミスを引き起こす。本稿では、プロフェッショナルが実務で採用する堅牢な実装パターンを公開する。
—
1. なぜ「単純な座標計算」で失敗するのか
多くの初心者は `Shape.Cells(“PinX”)` や `Width` を直接参照しようとする。だが、これは罠だ。
グループ化された図形、回転した図形、あるいは線幅(`LocPinX`の影響)を考慮していないコードは、現場の複雑な図面では役に立たない。
我々が頼るべきは `Shape.BoundingBox` メソッド だ。これはVisioのレンダリングエンジンが計算する「真の外接矩形」を返す。これを使うことで、回転やグループ化の複雑な階層を意識せず、純粋な座標上の「領域」として図形を判定できる。
—
2. プロダクションコード:レイアウトチェック・エンジン
以下は、指定したページ内の全図形を走査し、特定の矩形範囲から逸脱しているか、あるいは他の図形と衝突しているかを判定するクラス構造の雛形だ。
Option Explicit
‘ @brief 指定範囲から逸脱している図形を検出し、色を変えて警告する
Public Sub CheckLayoutIntegrity(targetPage As Visio.Page, minX As Double, minY As Double, maxX As Double, maxY As Double)
Dim shp As Visio.Shape
Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double
Dim isError As Boolean
‘ 画面描画を停止してパフォーマンスを最大化
Application.ScreenUpdating = False
For Each shp In targetPage.Shapes
‘ BoundingBoxで正確な外接矩形を取得
‘ 1: 線の太さを含む, 0: 含まない(用途に合わせて使い分けろ)
shp.BoundingBox visBBoxExtents, x1, y1, x2, y2
‘ 境界判定ロジック
If x1 < minX Or y1 < minY Or x2 > maxX Or y2 > maxY Then
‘ 崩れている図形を赤枠で強調
shp.Cells(“LineColor”).Formula = “RGB(255,0,0)”
isError = True
Else
‘ 正常な場合は色を黒に戻す
shp.Cells(“LineColor”).Formula = “RGB(0,0,0)”
End If
Next shp
Application.ScreenUpdating = True
If isError Then MsgBox “レイアウトエラーを検出しました。”, vbCritical
End Sub
—
3. 設計の勘所:堅牢性を高めるための「3つの規律」
このコードを「動く」レベルから「使い物になる」レベルへ引き上げるための知見を共有する。
① `visBBoxExtents` の選択肢を理解せよ
`BoundingBox`の引数には `visBBoxExtents`(線の太さを含む)と `visBBoxUpright`(回転を無視して垂直に切り出した矩形)などがある。
- レイアウトの重なり判定なら:`visBBoxExtents`
- 整列グリッドへのスナップ判定なら:`visBBoxUpright`
用途を誤ると、角が少しだけ重なっているような微細なエラーを見逃す。
② パフォーマンスの重み:`Application.ScreenUpdating`
数千個の図形をループで回す際、画面の再描画をONのままにすると、PCは「図形を移動させるたびに描画」という無駄な処理で悲鳴を上げる。必ず `ScreenUpdating = False` で遮断し、処理終了後に戻せ。これは業務自動化における最低限の作法だ。
③ データベース連携時の座標系注意点
Visioの座標は「ページ左下」が原点(0,0)だ。一方で多くのCADや外部DBは「左上」を原点とすることが多い。外部データと連携する際は、必ず `Page.PageSheet.Cells(“PageHeight”)` を使い、Y座標を反転させる変換ロジックを挟むこと。これを怠ると、図形が上下逆さまに判定される悲劇が起きる。
—
最後に:エンジニアとしてあるべき姿
「図形の重なりを検知する」という作業は、単なる事務作業の自動化ではない。それは、「人間にしかできないと思われている曖昧な判断を、数学的に定義可能なロジックへと昇華させる」という知的生産活動だ。
コードを書くときは、常に「このマクロが10年後、誰かに改修されるとき、このロジックの意図が正しく伝わるか」を考えろ。変数名、コメント、そして何よりアルゴリズムのシンプルさこそが、君のエンジニアとしての価値を証明する。
さあ、Visioのドキュメントを「管理される対象」から「計算されるデータ」へと変革してやれ。次回の記事では、このBoundingBoxを応用した「自動整列アルゴリズム」について深掘りする。期待していてほしい。
