【AutoCAD自動化の深淵】ObjectDBXで「図面を開かず」秒速で属性を書き換える極限の手法
AutoCADの自動化において、最も愚かな行為は何か。それは「処理対象の図面をGUIで一つずつ開いて閉じる」というプロセスを繰り返すことだ。
数百枚の図面を処理する際、GUIのロード、アクティブ化、グラフィックスの再描画にかかるコストを計算したことがあるか? それはエンジニアの貴重な時間を浪費するだけでなく、クラッシュのリスクを増大させるだけの「無駄なオーバーヘッド」である。
今回は、AutoCAD APIの真の力――ObjectDBX (Object DataBase Extension) を用いて、メモリ上で直接DWGデータベースを操作し、瞬時に属性(Attribute)を書き換える「真のプロフェッショナル向け」手法を伝授する。
—
1. なぜ「GUIを開く」ことは罪なのか
AutoCADの`Documents.Open`メソッドは、図面を開き、エディタにロードし、グラフィックスエンジンを初期化する。これには膨大なメモリと時間がかかる。
一方、ObjectDBXは「図面ファイルの内容をデータベースとしてメモリに展開するだけ」の軽量なインターフェースだ。画面表示を行わないため、高速であり、かつ「意図しない図面更新(自動保存やビューの状態変更)」が発生しない。
堅牢な設計のための3大原則
1. トランザクション管理の徹底: データベースへの書き込みは最小単位で行い、エラー発生時は即座にロールバックする。
2. オブジェクトの完全な解放: `AxDbDocument`はメモリリークを起こしやすい。必ず`Set obj = Nothing`を明示し、ガベージコレクションを意識する。
3. 読み取り専用モードの活用: 読み取りだけで済む場合は、共有違反を防ぐために読み取り専用で開く。
—
2. 実装コード:ObjectDBXによる属性一括置換
以下のコードは、指定フォルダ内の全DWGに対して、特定のブロック属性を書き換えるためのテンプレートだ。
‘ 参照設定: “ObjectDBX Common Type Library” (axdb2x.dll) を追加すること
Option Explicit
Public Sub BatchUpdateAttributes()
Dim fso As Object
Dim folderPath As String
Dim targetFile As Object
Dim dbxDoc As AxDbDocument
Set fso = CreateObject(“Scripting.FileSystemObject”)
folderPath = “C:\Projects\TargetDrawings\”
‘ ObjectDBXドキュメントのインスタンス化
Set dbxDoc = GetInterfaceObject(“ObjectDBX.AxDbDocument.24”) ‘ AutoCAD 2021以降
For Each targetFile In fso.GetFolder(folderPath).Files
If LCase(fso.GetExtensionName(targetFile.Path)) = “dwg” Then
On Error Resume Next
dbxDoc.Open targetFile.Path
If Err.Number = 0 Then
‘ 属性書き換え処理を実行
Call UpdateBlockAttributes(dbxDoc, “TITLE_BLOCK”, “DRAWING_NO”, “NEW-12345”)
dbxDoc.SaveAs targetFile.Path
Else
Debug.Print “Open Error: ” & targetFile.Name
End If
On Error GoTo 0
End If
Next
Set dbxDoc = Nothing
End Sub
Private Sub UpdateBlockAttributes(doc As AxDbDocument, blockName As String, tag As String, newValue As String)
Dim ent As Object
Dim atts As Variant
Dim i As Long
‘ モデル空間内の全オブジェクトをスキャン
For Each ent In doc.ModelSpace
If ent.ObjectName = “AcDbBlockReference” Then
If ent.Name = blockName Then
atts = ent.GetAttributes
For i = LBound(atts) To UBound(atts)
If atts(i).TagString = tag Then
atts(i).TextString = newValue
atts(i).Update
End If
Next
End If
End If
Next
End Sub
—
3. プロダクション環境における注意点
この手法を実務に組み込む際、以下の落とし穴に注意してほしい。
① バージョン互換性(AxDbDocumentの依存関係)
`GetInterfaceObject`で指定するバージョン番号は、インストールされているAutoCADのバージョンに依存する。プロダクションコードでは、`Application.Version`から動的に生成するか、レジストリを確認して柔軟に切り替える設計が望ましい。
② 外部参照(Xref)とイメージの扱い
ObjectDBXは、パスが絶対パスであれば外部参照も読み込むが、相対パスの場合は解決できないことが多い。サーバー環境で運用する場合は、必ず環境パスの設定と整合性を取る必要がある。
③ 属性定義(BlockReference)の複雑さ
上記のコードは単純な属性ブロックを想定している。もし、ダイナミックブロックや「属性定義がネストされたブロック」を操作する場合、`GetAttributes`だけでは不十分なケースがある。その際は`BlockTableRecord`を直接再帰的に走査する設計への拡張が必要だ。
—
最後に:エンジニアとしての矜持
「図面を開く」という思考停止した自動化から脱却し、データベースとして図面を捉える視点を持つこと。それが、AutoCADを自在に操るエンジニアと、単なるオペレーターとの決定的な境界線だ。
このObjectDBXの手法は強力だが、同時に「バックグラウンドで何が起きているか」を理解していないと、壊れたDWGを量産する凶器にもなる。トランザクションの正当性を常に検証し、バックアップを自動生成する堅牢なラッパーを構築せよ。
君の次のプロジェクトが、GUIの待ち時間から解放されることを期待している。
