【テクニカル・上級編】【上級プロフェッショナル】AutoCAD VBAで図面内の全オブジェクトのID(Entity Name)を取得し、データベースと連携する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する:オブジェクトIDによるDB連携の深淵

AutoCADのオートメーションにおいて、最も頻繁に誤解されているのが「Entity Name」の正体だ。多くの初学者は`Handle`を唯一の識別子と信じ込んでいるが、大規模システムを設計する我々にとって、`Handle`はあくまでデータベース上の「論理キー」に過ぎない。

真にシステムを支配するには、AutoCADの内部メモリ空間を直接指し示す`Entity Name`(DXFグループコードでいうところの`-1`、VBAでは`ObjectID`)を理解し、それをいかに外部システムと同期させるかというアーキテクチャの構築が不可欠である。

本稿では、レガシーなAutoCAD VBA環境において、高負荷な図面データからEntity IDを抽出し、堅牢な外部DB連携を実現する「極限の知見」を共有する。

1. なぜ「ObjectID」なのか:Handleとの決定的な差異

AutoCADの`Handle`は、図面保存後も永続化されるが、`ObjectID`(Entity Name)はセッションごとに変動する可能性がある。しかし、実行中のメモリ空間において、オブジェクトを一意に、かつ高速に特定できるのはObjectIDのみである。

SQL Server等の外部DBと連携する際、以下の設計指針を遵守せよ。

  • HandleをPrimary Keyとする: 図面永続性のため。
  • ObjectIDをRuntime Pointerとして活用する: メモリ上の操作(ハイライト、プロパティ変更)の高速化のため。

2. 実装:オブジェクトIDの抽出とDB連携の最適化

以下のコードは、単なる全探索ではない。`ThisDrawing.ModelSpace`をイテレートする際、オブジェクトの型を厳格に評価し、不要なメモリ消費を抑える設計となっている。

Option Explicit

‘ 外部データベース接続のシミュレーション
‘ 実際にはADODB.Connectionを使用する
Public Sub SyncEntityToDatabase()
Dim obj As AcadEntity
Dim entID As LongPtr
Dim entHandle As String

‘ メモリ最適化: 画面更新を停止させることで処理速度を劇的に向上
ThisDrawing.Application.BeginCommandUndoGroup

For Each obj In ThisDrawing.ModelSpace
‘ Entity Name (ObjectID) の取得
‘ 64bit版AutoCADではLongPtrが必須。ここをLongで宣言するとクラッシュの原因となる
entID = obj.ObjectID
entHandle = obj.Handle

‘ ここで外部DBへの挿入・更新処理を呼び出す
‘ 例: Call UpdateExternalDB(entHandle, entID, obj.ObjectName)

Debug.Print “Handle: ” & entHandle & ” | ObjectID: ” & entID
Next obj

ThisDrawing.Application.EndCommandUndoGroup

‘ 明示的な解放: VBAのGCを待たず、巨大なオブジェクト参照を破棄する
Set obj = Nothing
End Sub

3. レガシー環境におけるメモリ最適化と「罠」

VBAは、一度インスタンス化したオブジェクトの参照を、スコープを抜けるまで保持し続ける悪癖がある。特に`For Each`文で数万の図形を回す場合、メモリリークは致命的だ。

極限の知見:メモリを制御する

1. Set obj = Nothing の徹底: ループ内で頻繁にオブジェクトを操作する場合、ループの最後に必ず`Nothing`を代入し、COM参照カウントをデクリメントせよ。
2. LongPtrの採用: AutoCAD 2015以降、64bit環境が前提である。ObjectIDを`Long`で保持しているなら、即座に`LongPtr`へ修正せよ。これはエンジニアとしての最低限の責務である。
3. イベントの抑制: 大量更新を行う際は、`Application.SysVarChanged`等のイベントを一時的に無効化せよ。不要なイベント発火がシステムを数倍遅くする。

4. システム間連携のアーキテクチャ

外部DB(SQL Server)と連携させる際、ネットワーク遅延がボトルネックになる。「逐次通信」は避けよ。

  • バッチ処理の推奨: 抽出した全データを一度メモリ内の配列(Array)または`Collection`オブジェクトに格納し、トランザクションをまとめてコミットせよ。
  • ハッシュ値の活用: オブジェクトのプロパティ(座標、層、色など)をシリアライズし、ハッシュ値を計算してDBの「変更フラグ」として保持せよ。これにより、変更があったオブジェクトのみを同期する差分更新が可能となる。

最後に:チーフアーキテクトからの助言

AutoCAD VBAはレガシーと言われるが、そのオブジェクトモデルは極めて精緻に設計されている。APIの表面をなぞるだけでは、大規模な図面データの前でシステムは容易に崩壊するだろう。

オブジェクトのライフサイクルを理解し、メモリの断片化を恐れず、常に「何がメモリを占有しているのか」を意識すること。それが、伝説的な自動化システムを構築するための唯一の道である。

次は、`.NET API (ObjectARX)`への移行を見据えた、より深いメモリ管理手法について論じることになるだろう。諸君のコードが、より洗練されたものになることを期待している。

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