【実務・中級編】【上級プロフェッショナル】AcadApplicationオブジェクトで、指定した範囲(Window)内のオブジェクトのみを処理するVBAテクニック – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを支配する:空間フィルタリングによる「特定領域」の高速制御術

AutoCADの自動化において、最も初歩的でありながら、多くの開発者が躓く壁がある。それが「図面全域を探索し、不要なオブジェクトまで舐め回して処理する」という非効率な実装だ。

数万のエンティティがひしめく巨大な図面で `For Each` を回し、条件分岐で間引く……。そんなコードを書いている時点で、エンジニアとしての設計思想が問われている。真のプロフェッショナルは、AutoCADのカーネルが提供する空間検索機能を直接叩き、必要なオブジェクトだけを瞬時に抽出する。

今回は、`AcadApplication` と `AcadDocument` の境界線を理解し、ユーザーが指定した矩形領域(Window)内のオブジェクトだけを射抜く、極限の自動化テクニックを伝授する。

1. なぜ「空間検索」が不可欠なのか

AutoCADには `Select` メソッドが存在するが、これを安易に使うのは素人だ。`Select` を多用すると、図面上の選択表示(ハイライト)が頻発し、画面描画のオーバーヘッドが処理時間を劇的に増大させる。

我々が求めるのは、「描画を介さず、データベースのインデックスを直接参照する」手法だ。`SelectionSets` を活用し、`SelectByPolygon` ではなく、矩形座標を用いた `acSelectionSetWindow` モードを極める必要がある。

2. プロダクション環境に耐えうる堅牢な実装

以下のコードは、単に動くレベルではない。メモリリークを防ぎ、再利用性を担保した「プロダクション・コード」だ。

Option Explicit

‘ ———————————————————
‘ 指定領域内のオブジェクトを効率的に抽出・処理する
‘ @param minPt 矩形の左下座標
‘ @param maxPt 矩形の右上座標
‘ ———————————————————
Public Sub ProcessEntitiesInWindow(minPt As Variant, maxPt As Variant)
Dim doc As AcadDocument
Dim ssets As AcadSelectionSets
Dim sset As AcadSelectionSet
Dim ent As AcadEntity

Set doc = ThisDrawing
Set ssets = doc.SelectionSets

‘ 1. セレクションセットの重複作成によるクラッシュを防ぐ
On Error Resume Next
ssets.Item(“TargetRange”).Delete
On Error GoTo 0

Set sset = ssets.Add(“TargetRange”)

‘ 2. 空間フィルタリング:acSelectionSetWindow を使用
‘ 描画を強制せず、メモリ上で完結させる
sset.Select acSelectionSetWindow, minPt, maxPt

‘ 3. 処理開始(トランザクション的な意識を持つこと)
For Each ent In sset
‘ ここに高度な処理を記述
‘ 例:レイヤーを「PROCESSED」に変更するなど
‘ ent.Layer = “PROCESSED”
Debug.Print “Found: ” & ent.ObjectName
Next ent

‘ 4. 必ず明示的にクリーンアップする
‘ これを怠ると、AutoCADのセッションが重くなり、最悪の場合は落ちる
sset.Delete
End Sub

3. 設計上の重要ポイントと注意点

① セレクションセットの「名前」の取り扱い

`ssets.Add(“TargetRange”)` のように一意の名前を付ける必要があるが、もし前の処理が異常終了していた場合、同名のセットが残存しているとエラーになる。`On Error Resume Next` で削除を試みる、あるいは GUID を利用して動的に名前を生成する設計が必須だ。

② 座標系の罠を回避せよ

`minPt` と `maxPt` は、必ず WCS(ワールド座標系) であることを確認せよ。UCS(ユーザー座標系)上で指定された座標をそのまま渡すと、意図しない領域が選択される。`Utility.TranslateCoordinates` を使用し、常にWCSに変換して渡すのが、業務ツールとして必須の作法である。

③ 大規模データとデータベース連携

もしこの処理の後に外部DB(SQL Serverなど)への書き込みを行う場合、`For Each` ループ内で逐次接続してはならない。処理対象の `ObjectID` を一度配列に格納し、ループ終了後に一括で処理する(バッチ処理)のが、パフォーマンスを最大化する鉄則だ。

結論:ツールは「速さ」と「静寂」で評価される

ユーザーにとって、画面が激しく点滅しながら処理されるツールは「不安」でしかない。今回紹介した `acSelectionSetWindow` を用いた手法は、描画を制御し、必要なデータにのみアクセスする。

これができるかできないかで、君が書く自動化ツールの「品格」が決まる。
コードをコピペするだけでなく、AutoCADのオブジェクトモデルが持つこの「深淵」を理解し、現場の業務効率を劇的に変えるアーキテクトであれ。

さあ、次のコードで図面を支配せよ。

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