こんにちは!AutoCAD VBAの自動化の世界へようこそ。
チーフアーキテクトの私だ。
マクロの記録ボタンを押して「なんだか動いたけれど、中身がよくわからない……」というフェーズはもう卒業しよう。実務の現場では、何千個もあるオブジェクトの画层(レイヤー)や色、線種を一瞬で書き換えるような「真の自動化」が求められる。
今回は、図面内のオブジェクトプロパティをまとめて効率よく変更するための極意を伝授しよう。
ここをクリアすれば、君も立派なAutoCAD VBAエンジニアだ。安心してついてきてほしい。
—
1. なぜ「一括変更」でつまづくのか?(AutoCAD VBAの基本思想)
まず、AutoCADのオブジェクトモデルの基本を押さえておこう。
画面に見えている線や円、文字たちは、すべて `AcadDocument.ModelSpace`(またはペーパー空間)という巨大なコンテナ(入れ物)の中にゴロゴロと転がっている。
初学者がやりがちな失敗は、一つひとつのオブジェクトを手動でクリックするようにコードを書こうとすることだ。
「あれ、選択できない」「エラーが出る」と悩む原因のほとんどは、オブジェクトのライフサイクルとコレクションの構造を理解していないことにある。
一括変更の本質はこうだ:
1. ModelSpaceという名の箱の中を覗き込む。
2. 中にあるオブジェクトを上から順にすべてチェックする。
3. 条件に合うものだけをピックアップして、プロパティ(色や画層など)を書き換える。
たったこれだけだ。この「全走査(ループ処理)」のパターンを体に叩き込むだけで、業務効率は100倍に跳ね上がる。
—
2. 実践!図面内の全オブジェクトの色を一括変更するコード
百聞は一見に如かず。まずは、モデル空間にあるすべてのオブジェクトの色を「赤(ColorIndex = 1)」に変更する、最も実用的なコードを見てみよう。
VBAエディタ(Alt + F11)を開き、標準モジュールに以下のコードを貼り付けてみてほしい。
Sub BatchChangeColorToRed()
Dim acadDoc As AcadDocument
Dim acadObj As AcadObject
Dim count As Long
‘ 1. 現在アクティブな図面を取得
Set acadDoc = ThisDrawing
‘ 2. 処理カウンターの初期化
count = 0
‘ 3. モデル空間のオブジェクトをひとつずつ総当たりでチェック(For Each構文)
For Each acadObj In acadDoc.ModelSpace
‘ 4. エラーハンドリング:ロックされた画層や削除不可なオブジェクトをスキップ
On Error Resume Next
‘ 5. 色プロパティを変更 (ACAD_COLORで赤を指定: 1)
acadObj.Color = 1
If Err.Number = 0 Then
count = count + 1
End If
‘ エラー処理を通常に戻す
On Error GoTo 0
Next acadObj
‘ 6. 完了メッセージ
MsgBox count & “個のオブジェクトの色を「赤」に変更しました!”, vbInformation, “一括処理完了”
End Sub
コードの解説(先輩からのワンポイントアドバイス)
- `For Each acadObj In acadDoc.ModelSpace`
これが肝だ。モデル空間というコレクション(集まり)から、中にある要素を一つずつ取り出して `acadObj` という変数に放り込んでいる。配列のインデックスを気にする必要がない最高にエレガントな書き方だ。
- `On Error Resume Next` の重要性
実務の図面には、「ロックされていて変更できない画層」や「読み取り専用の特殊なブロック」が混ざっている。これらにぶ当たった瞬間、コードがエラーで強制終了してしまう。それを防ぐために「エラーが出たら次の処理へ進む」という盾を張っているのだ。プロの現場では必須のテクニックとなる。
—
3. 「特定の条件」に絞り込んで変更する(フィルター処理)
図面内の「すべてのオブジェクト」を無条件に変えることは稀だ。大抵は「特定の画層(Layer)にあるものだけ」「特定の文字(Text)だけ」といった条件がつく。
ここでは、「”OLD_LINE” という画層にあるオブジェクトだけを、”NEW_LINE” 画層に移動する」という、実務で毎日使うレベルのテクニックを伝授しよう。
Sub BatchChangeLayer()
Dim acadDoc As AcadDocument
Dim acadObj As AcadObject
Dim targetLayer As String
Dim newLayer As String
Dim changedCount As Long
Set acadDoc = ThisDrawing
targetLayer = “OLD_LINE” ‘ 変更前の画層名
newLayer = “NEW_LINE” ‘ 変更後の画層名
changedCount = 0
‘ 事前に変更先画層が図面に存在するか確認するなどの配慮があると完璧だが、
‘ 今回はシンプルに走査して条件分岐を行う
For Each acadObj In acadDoc.ModelSpace
‘ オブジェクトが「Layer」プロパティを持っているか確認しつつ比較
On Error Resume Next
If acadObj.Layer = targetLayer Then
acadObj.Layer = newLayer
If Err.Number = 0 Then
changedCount = changedCount + 1
End If
End If
On Error GoTo 0
Next acadObj
MsgBox targetLayer & ” 画層のオブジェクト ” & changedCount & “個を、” & newLayer & ” 画層へ移行しました。”, vbInformation
End Sub
ここで知っておくべき「オブジェクトの型」の罠
初心者からよくある質問が、「なぜ `Dim acadObj As AcadObject` なのか。`AcadLine` や `AcadCircle` ではダメなのか?」というものだ。
モデル空間には、線、円、文字、ブロックなど、様々な形状のオブジェクトが混在している。もし `AcadLine` と宣言してしまうと、そこに「円」が来た瞬間に型が一致せずエラーになってしまう。
そのため、すべての図形オブジェクトの親である `AcadObject` として受け取り、共通して持っているプロパティ(`Layer` や `Color` など)を操作するのが、AutoCAD VBAにおける最も安全でスマートな作法なのだ。
—
4. 現場で陥りやすいエラーと回避の極意
最後に、実務でコードを動かしたときに直面しがちな「ハマりポイント」を先回りして共有しておこう。
1. 「オブジェクトは読み取り専用です」系のエラー
- 原因: 外部参照(XREF)されている図面の中身や、ロックされた画層のエンティティを書き換えようとした場合に発生する。
- 対策: 前述の `On Error Resume Next` を適切に配置し、そもそも変更が許可されているプロパティか(`HasAttributes` やロック状態など)を事前に判定するロジックを挟もう。
2. 処理が重すぎてAutoCADがフリーズしたように感じる
- 原因: 数万個のオブジェクトをループする際、画面の再描画(グラフィックスの更新)がその都度走っているため。
- 対策: プロコードの鉄則として、処理の最初に `AcadApplication.ZoomExtents` などを無駄に呼ばないこと、そして大規模処理の前には画面更新を一時停止する技(※上級向け:`AcadDocument.Utility` やレイアウトの最適化)を使うと劇的に速くなる。まずは今回紹介した基本のループをマスターしよう。
—
まとめ
お疲れ様でした!
今回は、AutoCAD VBAにおけるオブジェクトプロパティの一括変更の基本と、実務で使える実践コードを解説した。
- モデル空間(`ModelSpace`)を `For Each` で総当たりする
- 汎用的な `AcadObject` 型で受け取る
- `On Error Resume Next` で予期せぬエラー(ロック画層など)をいなす
ここさえクリアしていれば、君の図面整理のスピードは手作業の何百倍にも加速するはずだ。
明日からの図面修正作業が、少しでもワクワクする自動化の時間に変わることを願っている。
それでは、また次の極意で会おう。ハッピー・コーディング!
