【実務・中級編】【実務中級】図面内の全オブジェクトのID(Entity Name)を取得し、データベースと連携する準備をする – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見

【実務中級】図面内の全オブジェクトのID(Entity Name)を取得し、データベースと連携する準備をする

こんにちは。チーフアーキテクトの私だ。
これまで数多くの大規模プラント、建築、インフラのCAD自動化プロジェクトを統括してきたが、現場から最も頻繁に持ち込まれる相談の一つがこれだ。

「図面内の図形データを抽出し、外部のデータベース(AccessやSQL Serverなど)と連携させたい」

この要件を聞いたとき、素人はすぐに `For Each` で図面を舐め回し、図面のプロパティをごっそり取得するコードを書き始める。だが、少し待ってほしい。その設計では、図面が数万オブジェクト規模に膨れ上がった瞬間にメモリリークを起こし、AutoCADごとフリーズする地獄を見る。

今回は、AutoCADのオブジェクトモデルの深層――「Entity Name(DXF名 / エティティ名)」と「Handle(ハンドル)」のライフサイクルを完全に理解し、外部DBと堅牢に連携するためのプロダクションコードを授けよう。

なぜ「Entity Name」なのか? データベース連携の鉄則

AutoCAD図面と外部DBを連携させる際、最大の課題は「図形の一意性(ユニーク性)」の担保だ。

よくある誤りが、レイヤ名や座標値、文字内容などをキーにしてDBと紐づけようとするアプローチだ。これらは図面の修正によって容易に変わり、データの整合性が一瞬で崩壊する。

AutoCAD内部でオブジェクトを一意に特定するためには、以下の2つの識別子が存在する。

1. Handle(ハンドル): オブジェクト作成時に割り当てられる16進数の文字列(例: `A1B2`)。図面セッションを跨いでも不変であるため、DBのプライマリキーとして極めて優秀
2. Entity Name (オブジェクト名 / アプリケーション内ポインタ): VBAやARXのメモリ上でオブジェクトを指し示す長整数(LongPtr / Long)。セッションが変わると無効化されるが、実行中の高速なアクセスには不可欠。

DB連携のアーキテクチャとしては、「永続的なキーにはHandleを使い、VBAのランタイム処理ではEntity Name(またはオブジェクト参照)に変換して高速に叩く」のがプロの定石だ。

バグを生まないための設計思想

実務で動くツールを作るにあたり、以下の3点をコードに組み込むことを義務付けている。

  • エラーハンドリングの徹底: 削除済みオブジェクトや画層ロックなど、予期せぬ例外でマクロが止まらないこと。
  • イテレーションの最適化: `ActiveDocument.ModelSpace` への無駄なアクセスを避け、ローカル変数にキャッシュすること。
  • トランザクション的思考: DB連携の準備として、取得したデータを構造化して出力(今回はイミディエイトウィンドウおよびCSV出力の土台)できること。

【プロダクションコード】全エンティティのIDとメタデータ抽出マクロ

以下のコードは、現在のモデル空間およびペーパー空間に存在するすべての図形をスキャンし、`Handle` と `Entity Name`、さらにレイヤ名やオブジェクト種別を取得してCSV出力の準備を行う実戦用コードだ。

標準モジュールに貼り付けて実行してほしい。

Option Explicit

‘ —————————————————————–
‘ 業務自動化プロシージャ: 図面内全エンティティのID・メタデータ抽出
‘ —————————————————————–
Public Sub ExportEntityIdentifiersForDB()
Dim startTime As Double
startTime = Timer

On Error GoTo ErrorHandler

‘ 1. アプリケーションとドキュメントの安全な参照取得
Dim acadApp As AcadApplication
Dim acadDoc AcadDocument
Set acadApp = ThisDrawing.Application
Set acadDoc = ThisDrawing.ActiveLayout.Application.ActiveDocument

‘ 2. 出力用ファイルの準備(デスクトップにCSVを出力する例)
Dim fso As Object
Dim ts As Object
Dim csvPath As String

Set fsp = CreateObject(“Scripting.FileSystemObject”)
csvPath = CreateObject(“WScript.Shell”).SpecialFolders(“Desktop”) & “\CadEntityMapping_” & Format(Now, “yyyymmdd_HHMMSS”) & “.csv”
Set ts = fso.CreateTextFile(csvPath, True)

‘ CSVヘッダーの書き込み(DB連携のスキーマを意識)
ts.WriteLine “Handle,EntityName,ObjectType,LayerName,Color”

‘ 3. スキャン対象のカウントと変数定義
Dim entityCount As Long
entityCount = 0

Dim ent As AcadEntity
Dim ms As AcadModelSpace
Set ms = acadDoc.ModelSpace

‘ 4. 高速イテレーションの実行
‘ ※モデル空間を対象とする(必要に応じてレイアウト空間もループに追加可能)
Dim i As Long
For i = 0 To ms.Count – 1
Set ent = ms.Item(i)

‘ 削除フラグや特殊オブジェクトの除外(堅牢性の担保)
If Not ent Is Nothing Then
‘ DB連携キーとなる Handle と EntityName(ObjectName等)を取得
Dim entHandle As String
Dim entName As String
Dim entType As String
Dim entLayer As String

entHandle = ent.Handle
‘ VBAにおけるEntity Nameは内部ポインタのため文字列化して保持
entName = CStr(ent.ObjectName) ‘ ※厳密なDXFグループネームを取得する場合は別処理が必要な場合あり
entType = TypeName(ent)
entLayer = ent.Layer

‘ CSV行の組み立て(カンマ区切り)
ts.WriteLine entHandle & “,” & entName & “,” & entType & “,” & entLayer & “,” & ent.Color

entityCount = entityCount + 1
End If
Next i

‘ 5. クリーンアップ
ts.Close
Set ts = Nothing
Set fso = Nothing

MsgBox “処理が完了しました。” & vbCrLf & _
“抽出件数: ” & entityCount & ” 件” & vbCrLf & _
“出力先: ” & csvPath, vbInformation, “DB連携準備完了”

Exit Sub

ErrorHandler:
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
If Not ts Is Nothing Then ts.Close
End Sub

コードの解説とアーキテクトからの助言

1. `ent.Handle` の強力さ
このコードで取得している `ent.Handle` こそが、外部データベース(SQLiteやSQL Server等)とのリレーショナルキーになる。次回以降、DB側から「Handle: A1B2 のオブジェクトの色を赤に変えろ」という命令が飛んできたとき、`acadDoc.HandleToObject(“A1B2”)` というメソッドを使えば、一瞬でそのオブジェクトのオブジェクト参照を復元できる。これは絶対に覚えておいて損はないAPIだ。

2. メモリとオブジェクトの解放
ループ内で `Set ent = Nothing` を明示的に行わなくともVBAのスコープで処理されるが、ファイルシステムオブジェクト(FSO)やテキストストリームは確実に `Close` および `Nothing` 代入を行わなければ、ファイルロックのデッドロックを引き起こす。プロダクションコードでは例外時のクリーンアップまで記述するのがプロの流儀だ。

3. パフォーマンスの意識
数万オブジェクトを超える図面では、画面の再描画(`Application.ScreenUpdating` 相当の制御や `ActiveDocument.Utility.Prompt` の多用)がボトルネックになる。今回のコードでは余計な画面出力を削ぎ落とし、純粋なメモリ上の走査に特化させているため、極めて高速に動作する。

次のステップ:データベースとの結合へ

このスクリプトによって、図面内の全オブジェクトが「永続的なキー(Handle)」を持って外部に出力される準備が整った。次は、このCSVデータを元に外部データベース(Microsoft Access等)へインポートし、図面属性と業務データを紐づけるレイヤーへと進むことになる。

基礎の設計が正しければ、どれほど図面が巨大化しようとも、破綻しないシステムが構築できる。
現場の信頼を勝ち取る強靭なコードを、君の手で組み上げてくれ。

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