こんにちは!AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押すだけの自動化から一歩抜け出し、「自分の手でCADを自在にコントロールしたい」そう思ってこのページにたどり着いたあなたは、すでにエンジニアとしての素晴らしい一歩を踏み出しています。
今回は、実務で絶対に避けて通れない「図面内のオブジェクトと外部データベースを紐づけるための基礎技術」についてお話しします。
「図面の中にある無数の線や文字を、どうやってプログラムで識別するの?」
「Excelや外部DBとどうやって連携の準備をすればいいの?」
そんな疑問を、一つひとつ丁寧に、そして本質からクリアしていきましょう。ここをマスターすれば、あなたのAutoCAD VBAスキルは一気に「中級エンジニア」の領域へとシフトします。準備はいいですか?さあ、始めましょう!
—
1. AutoCADオブジェクトの「戸籍謄本」:Entity Nameを知る
私たちが図面上に描く線(Line)、円(Circle)、文字(Text)などは、すべてAutoCADの内部では「オブジェクト」として管理されています。
ここで一つ、重要な現実をお伝えしなければなりません。
「図面上の見た目が同じでも、AutoCADは人間のように『あの赤い線』と認識しているわけではない」ということです。
プログラムが図形を特定するためには、それぞれに割り当てられた「一意のID(識別子)」が必要になります。これが、AutoCAD VBAの世界で Entity Name(エンティティ名) と呼ばれるものです。
Handle(ハンドル)と Entity Name の違い
実務でデータベース連携を考えるときによく混同されるのが、Handle(ハンドル)とEntity Nameです。
- Entity Name(エンティティ名):
VBAのコード内でオブジェクトを操作するために一時的に割り当てられるポインタのようなものです。図面を開き直したりすると、この値は変わってしまいます。
- Handle(ハンドル):
オブジェクトが生成されたときに固定で割り当てられる、いわば「人間のマイナンバー」のような永続的な文字列です。
データベースと連携し、「あのとき図面で処理したあの図形」を後から外部DB側で追跡したい場合は、この Handle をキーとして使うのが鉄則です。今回は、まずその手前のステップとして、VBAから図面内の全オブジェクトのID(Entity NameおよびHandle)を確実にキャプチャする方法を解説します。
—
2. 【実務直結】図面内の全オブジェクトを走査するVBAコード
それでは、実際に図面内のすべての図形をスキャンし、それぞれのIDを取得してイミディエイトウィンドウに出力するコードを見てみましょう。
以下のコードを、AutoCADのVBAエディタ(`Alt + F11` で起動)の標準モジュールに貼り付けてみてください。
Sub ExportEntityIDsToDatabaseReady()
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing.ActiveDocument
Dim acadEnt As AcadEntity
Dim totalCount As Long
Dim targetSpace As AcadModelSpace
‘ モデル空間オブジェクトを取得
Set targetSpace = acadDoc.ModelSpace
totalCount = targetSpace.Count
If totalCount = 0 Then
MsgBox “モデル空間にオブジェクトが存在しません。”, vbExclamation, “通知”
Exit Sub
End If
Debug.Print “=== 外部DB連携スキャン開始 (総数: ” & totalCount & “件) ===”
Debug.Print “Index, ObjectType, EntityName(LongPtr), Handle”
Dim i As Long
For i = 0 To totalCount – 1
‘ 順番にオブジェクトを取り出す
Set acadEnt = targetSpace.Item(i)
‘ 1. Entity Name の取得(VBAではLongPtr型としてメモリ上のアドレスを保持)
Dim entName As LongPtr
entName = acadEnt.objectID
‘ 2. Handle の取得(データベース連携のキーとなる永続ID)
Dim entHandle As String
entHandle = acadEnt.Handle
‘ 3. オブジェクトのタイプ(種類)を取得
Dim entType As String
entType = acadEnt.EntityName
‘ イミディエイトウィンドウに出力(ここにDBへのINSERT処理などを組み込みます)
Debug.Print i & “, ” & entType & “, ” & entName & “, ” & entHandle
Next i
Debug.Print “=== スキャン完了 ===”
MsgBox “全 ” & totalCount & ” 件のオブジェクト情報をスキャンしました。\nイミディエイトウィンドウを確認してください。”, vbInformation, “完了”
End Sub
コードのここがポイント!
1. `ThisDrawing.ActiveDocument.ModelSpace`
現在アクティブな図面の「モデル空間」をごっそり取得しています。ここがすべての図形の宝庫です。
2. `targetSpace.Item(i)` によるイテレーション
配列と同じように、0から `Count – 1` まで順番にオブジェクトを串刺し(走査)にしていきます。この総当たり(ループ)が自動化の基本中の基本です。
3. `acadEnt.Handle` の活用
この `entHandle` さえあれば、ExcelのVBAからSQLiteやAccess、あるいはWeb上の外部データベース(SQL Serverなど)へ、「この図形の座標や属性はこれです」とデータを飛ばすときの最強のキーになります。
—
3. 現場でありがちな「落とし穴」とエラー回避の知見
さて、ここからがチーフアーキテクトとしての本当のノウハウの共有です。
上記のコードは非常にシンプルですが、実際の業務図面(数万〜数十万オブジェクトがうごめくモンスター図面)でこれを実行すると、いくつかの「罠」にハマります。
罠その1:画面更新によるパフォーマンスの激しい劣化
もしこのループの中で、うっかり図形を選択状態にしたり、画面を再描画(`Update`メソッドなど)させたりすると、AutoCADは猛烈に重くなります。
【対策】 大量処理を行う際は、必ず画面描画をロックしましょう。
‘ 処理の最初で画面描画を停止
acadDoc.Utility.Prompt “データ処理中…”
‘ ※実際にはAcadDocumentのVisibleやレイアウト再描画制御など、
‘ 余計な画面更新を挟まないのが鉄則です。
罠その2:ブロック参照(INSERT)の中身はどうなるの?
今回のコードは「モデル空間直下」のオブジェクトしか見ていません。
実務の図面では、たくさんの図形が「ブロック(部品)」の中にまとめられていますよね。ブロックの内部にある線一本一本にアクセスしたい場合は、`AcadBlockReference` オブジェクトを検出し、その中に入り込む(Explodeする、または `GetAttributes` を使うなど)再帰的な処理が必要になります。
まずはモデル空間の直下を制覇すること。それができれば、ブロックの階層構造へのアプローチも怖くありません。
—
4. まとめと次のステップ
今回は、図面内の全オブジェクトのID(Entity Name / Handle)を取得し、外部データベースと連携するための基礎固めを行いました。
- Entity Name はプログラム内で一時的に図形を特定するポインタ。
- Handle は外部データベースと紐づけるための永続的なID。
- `ModelSpace` を `For` ループで回すことで、すべての図形を網羅できる。
ここをクリアすれば、次は「取得したHandleを元に、Excelや外部DBのデータを書き換える」、あるいは「特定のHandleを持つ図面要素の色をプログラムから一瞬で変える双方向連携」へと進むことができます。
ここをクリアしたあなたは、もうただの「マクロ記録ユーザー」ではありません。立派なAutoCAD自動化エンジニアです。ぜひご自身の環境でコードを動かし、イミディエイトウィンドウに流れるIDの群れを確認してみてください。
それでは、次のステップでお会いしましょう。あなたの開発ライフが素晴らしいものになりますように!
