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)`への移行を見据えた、より深いメモリ管理手法について論じることになるだろう。諸君のコードが、より洗練されたものになることを期待している。
