こんにちは!AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押して「動いたはいいけれど、中身を書き換えようとすると途端にエラーが出る…」そんなモヤモヤを抱えていませんか?
今回は、AutoCAD VBAの基礎をしっかりと押さえつつ、一歩先を行く「上級テクニック」の世界にご案内します。
テーマは『`AcadDocument.Database.CopyObjects`の戻り値「IdPair」を解析し、コピー前後でのオブジェクトIDの対応関係を厳密に管理する』です。
「なんだか難解な呪文みたい……」と思いましたか? 大丈夫。ここをクリアすれば、あなたはもうただの初学者ではありません。図面間を自由自在に飛び回り、データを完璧に同期させるプログラミングの面白さに目覚めるはずです。
さあ、優しい先輩エンジニアと一緒に、AutoCAD VBAの奥深い扉を開けてみましょう!
—
1. なぜ「オブジェクトのコピー」で苦労するのか?
AutoCADで図面を描いているとき、「あっちの図面にあるブロックや線を、こっちの図面に持ってきたいな」と思うことはよくありますよね。
VBAでは、これをコードで行うために `CopyObjects` という強力なメソッドが用意されています。
しかし、ここでCAD特有の大きな壁にぶつかります。
オブジェクトID(Handle / ObjectID)の運命
AutoCADの中では、すべての線や文字に「背番号(オブジェクトID)」が振られています。
図面Aから図面Bへオブジェクトをコピーしたとき、AutoCADは「新天地での新しい背番号」を自動的に割り振ります。
- コピー前(図面A)のID: `ID_A`
- コピー後(図面B)のID: `ID_B`
もし、あなたが「コピーした図形に対して、特定の外部データベース(Excelなど)の情報を紐づけたい」と考えていた場合、「元の図形のどのデータが、コピー後のどの図形になったのか」が分からなくなると、リンクがプツリと切れてしまいます。
これを解決するのが、今回主役となる`IdPair`(IDペア)というオブジェクトです。
—
2. CopyObjectsメソッドとIdPairの基本概念
`CopyObjects` は、文字通りオブジェクトの集まりを別のデータベース(図面)へコピーするためのメソッドです。
書き方のイメージはこうです:
destDb.CopyObjects objectsArray, ownerObject, idPairs
この最後の引数 `idPairs` に、Variant型のエノキ(配列)を仕込んでおくと、AutoCADが「どのIDがどのIDに変わったか」の対応表をその中にぎっしり詰めて返してくれます。
この対応表の1つひとつの要素が `IdPair` オブジェクト です。
`IdPair` は、主に以下の2つの重要なプロパティを持っています。
1. `Key`: コピー前のオブジェクトID(元の姿)
2. `Value`: コピー後のオブジェクトID(新しい姿)
3. `IsCloned`: 無事にコピーが成功したかどうか(Boolean)
—
3. 【実践】図面間でオブジェクトをコピーし、IDの対応関係を追跡するコード
百聞は一見に如かず。実際に別の図面へオブジェクトをごっそりコピーし、`IdPair` を使って「誰が誰に変身したか」をイミディエイトウィンドウに完全追跡するコードを見てみましょう。
このコードは、現在アクティブな図面から、新しく作成した(あるいは指定した)別図面のモデル空間へオブジェクトをコピーするシナリオを想定しています。
Sub CopyObjectsWithIdPairAnalysis()
Dim srcDoc As AcadDocument
Dim destDoc As AcadDocument
Dim srcDb As AcadDatabase
Dim destDb As AcadDatabase
‘ 1. コピー元とコピー先のデータベースを定義
Set srcDoc = ThisDrawing
Set srcDb = srcDoc.Database
‘ ※今回は簡単のため、新規図面をコピー先とします(実務では既存の別図面を指定可能)
Set destDoc = Documents.Add
Set destDb = destDoc.Database
‘ 2. コピー元からオブジェクトを集める(例としてモデル空間の最初の1つを取得)
Dim colObjects As Collection
Set colObjects = New Collection
If srcDb.ModelSpace.Count > 0 Then
Dim ent As AcadEntity
Set ent = srcDb.ModelSpace.Item(0) ‘ テスト用に最初の図形をターゲットに
colObjects.Add ent
Else
MsgBox “コピー元のモデル空間にオブジェクトがありません。”, vbExclamation
Exit Sub
End
‘ 3. AcadObjectの配列(Variant)に変換する
‘ CopyObjectsメソッドは、配列形式でオブジェクトを受け取る仕様です
Dim objArray() As AcadEntity
ReDim objArray(0 to colObjects.Count – 1)
Set objArray(0) = colObjects(1)
‘ 4. コピー先の所有者(今回はコピー先のモデル空間)を指定
Dim destOwner As AcadBlock
Set destOwner = destDb.ModelSpace
‘ 5. IdPairを受け取るための配列変数を準備(Variantとして宣言)
Dim idPairs() As Variant
‘ — 【ここが核心!】CopyObjectsの実行とIdPairの回収 —
srcDb.CopyObjects objArray, destOwner, idPairs
‘ 6. 返ってきた IdPair 配列を解析する
Dim i As Long
Debug.Print “=== オブジェクトID 追跡レポート ===”
For i = LBound(idPairs) To UBound(idPairs)
‘ idPairsの各要素は AcadIdPair オブジェクト
Dim pair As AcadIdPair
Set pair = idPairs(i)
‘ クローン(コピー)が成功しているかチェック
If pair.IsCloned Then
Debug.Print “【成功】”
Debug.Print ” 元のID (Key) : ” & pair.Key
Debug.Print ” 新しいID (Value): ” & pair.Value
‘ コピー後のオブジェクトを新しいIDから逆引きしてみる
Dim clonedEnt As AcadEntity
Set clonedEnt = destDb.ObjectIdToObject(pair.Value)
Debug.Print ” 変身後の図形 : ” & clonedEnt.ObjectName
Else
Debug.Print “【スキップ/失敗】元のID: ” & pair.Key
End If
Next i
MsgBox “コピーとID解析が完了しました。イミディエイトウィンドウを確認してください。”, vbInformation
End Sub
—
4. コードの解説と「初心者がハマりやすい罠」
このコードの肝と、実務で絶対に知っておくべきポイントを優しく解説します。
罠その1: `CopyObjects` に渡すのは「配列」でなければならない
VBA初心者が最も躓くのが、オブジェクトの渡し方です。`CopyObjects` は単体のオブジェクトを直接受け取ってくれません。必ず `AcadEntity` などのオブジェクトが詰まった「配列(Array)」 の形にして渡す必要があります。
上記のコードでは、一度コレクションや配列変数(`objArray()`)を経由させているのはそのためです。
罠その2: 返ってくる `idPairs` は Variant型の配列
`srcDb.CopyObjects` を実行すると、引数に指定した `idPairs` 変数の中に、自動的に `AcadIdPair` のリストが格納されます。
このとき、`idPairs` は事前に要素数を決めておく必要はありません。AutoCADが勝手にメモリを確保して返してくれます(ただし、Variant型として宣言しておくのが絶対条件です)。
応用へのステップ: `ObjectIdToObject`
コピー後の新しいID(`pair.Value`)が分かれば、`destDb.ObjectIdToObject(pair.Value)` を使って、コピー先の図形オブジェクトを瞬時に召喚できます。
これにより、「コピーした直後の図形に対して、色を変えたり、特定の拡張データ(XData)を書き込んだりする」という高度な同期処理が完全にコントロールできるようになります。
—
おわりに
お疲れ様でした!今回は `AcadDocument.Database.CopyObjects` と `IdPair` を使った、プロ顔負けのオブジェクトID管理術を解説しました。
「図面をまたいでデータを正確につなぎ合わせる」という技術は、図面管理システムや、外部DB連動型のCADアドイン開発において必須のスキルです。ここをマスターしたあなたは、もうマクロの記録から完全に卒業し、自分の手でAutoCADを意のままに操るエンジニアの領域に立っています。
「ここをもっとこうしたい」「こんな応用はできる?」といった疑問があれば、いつでも先輩エンジニアに聞いてくださいね。
あなたのAutoCAD VBAライフが、さらに素晴らしいものになるよう応援しています!
