【実務・中級編】【実務中級】図面内の全円弧(Arc)オブジェクトの始点・終点・中心座標と半径を取得・リスト化する – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは。チーフアーキテクトの私だ。
これまで数多のCAD自動化プロジェクトを統括してきたが、現場からもっとも頻繁に挙がる要望の一つが「図面内にある特定の幾何要素(今回は円弧:Arc)のパラメータを正確に抽出し、外部データとして活用したい」というものだ。

Excelへの集計、外部解析ソフトへのインポート、あるいは設計規則の自動チェック。
一見、単純なループ処理に見えるこのタスクだが、AutoCAD VBAのオブジェクトモデルの挙動、メモリ管理、そして座標系の罠を知らずに実装すると、大規模図面でフリーズしたり、ゴミデータを掴まされたりする「地雷コード」が完成する。

今回は、実務の現場で即座に通用する、バグ知らずで高パフォーマンスな円弧情報抽出・リスト化の極意を授けよう。

1. なぜ初心者のコードは実務で破綻するのか?

ネットのサンプルコードによくある、全ドキュメントを舐めるだけの安易なループ。あれは実務の現場では使い物にならない。
実務で直面する「3つの壁」をあらかじめ理解しておこう。

1. モデル空間(ModelSpace)とペーパー空間(PaperSpace)の混同
初心者は `ActiveDocument.ModelSpace` だけを見て満足する。しかし、実務の図面ではレイアウト(ペーパー空間)のビューポート内や、ブロック定義の内部に円弧が潜んでいることが多々ある。今回は基本の王道である「モデル空間+アクティブレイアウト」を確実に押さえる。
2. バインドと解放(オブジェクトライフサイクル)の軽視
VBAのCOMラッパーはデリケートだ。特に `SelectionSet` やイテレーションを雑に扱うと、メモリリークや「Automation Error」の温床になる。
3. Variant配列へのアクセスオーバーヘッド
AutoCADの座標(`Center`, `StartPoint`, `EndPoint` など)はすべて3次元配列(Variant)として返ってくる。これをループの都度、雑に取り出すと描画スレッドとの間で無駄な往復が発生し、巨大図面で露骨に処理が重くなる。

2. 堅牢な設計:バグを生まないためのアーキテクチャ

今回のツールに求められる要件は以下の通りだ。

  • 安全なオブジェクト走査: 選択セットの競合を避け、確実にモデル空間の `Arc` オブジェクトを捉える。
  • 正確な幾何情報の抽出:
  • 中心座標 $(X, Y, Z)$
  • 始点座標 $(X, Y, Z)$
  • 終点座標 $(X, Y, Z)$
  • 半径 ($Radius$)
  • 包含角度 ($TotalAngle$ またはラジアン/度数)
  • 実用的なアウトプット: イミディエイトウィンドウへの出力にとどまらず、実務で即座にExcel連携できるよう、CSV出力や配列への一括保持を意識した設計にする。

3. 【プロダクションコード】円弧情報抽出・リスト化モジュール

以下のコードを、あなたのAutoCAD VBAプロジェクトの標準モジュールにそのまま貼り付けてほしい。
変数名、エラーハンドリング、コメントに至るまで、プロダクション品質で組み上げている。

Option Explicit

‘ ==============================================================================
‘ 処理名: ExportArcGeometryData
‘ 概要 : アクティブ図面のモデル空間からすべての円弧(Arc)を抽出し、
‘ 中心・始点・終点・半径のジオメトリ情報をイミディエイトに出力する
‘ 著者 : チーフアーキテクト
‘ ==============================================================================
Public Sub ExportArcGeometryData()
‘ 1. 宣言とパフォーマンス最適化の準備
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing.Application.ActiveDocument

‘ 画面描画とイベントを抑制し、処理速度を極限まで引き上げる
acadDoc.Application.Utility.SetVariable “CMDECHO”, 0

On Error GoTo ErrorHandler

Dim modelSpc As AcadModelSpace
Set modelSpc = acadDoc.ModelSpace

Dim ent As AcadEntity
Dim arcObj As AcadArc

Dim arcCount As Long
arcCount = 0

‘ ログ用ヘッダー出力
Debug.Print “——————————————————————————–”
Debug.Print “【Arc Geometry Extraction Log】 実行日時: ” & Now
Debug.Print “対象図面: ” & acadDoc.Name
Debug.Print “——————————————————————————–”
Debug.Print “Index, Center_X, Center_Y, Center_Z, Start_X, Start_Y, Start_Z, End_X, End_Y, End_Z, Radius”

‘ 2. モデル空間の全エンティティを走査
Dim i As Long
For i = 0 To modelSpc.Count – 1
Set ent = modelSpc.Item(i)

‘ オブジェクトタイプが “AcDbArc”(円弧)であるものに絞り込む
If TypeOf ent Is AcadArc Then
Set arcObj = ent

‘ 3. 座標データの取得(Variant配列として返るためローカル変数で受ける)
Dim vCenter As Variant
Dim vStart As Variant
Dim vEnd As Variant

vCenter = arcObj.Center
vStart = arcObj.StartPoint
vEnd = arcObj.EndPoint

Dim dRadius As Double
dRadius = arcObj.Radius

‘ 4. ログ出力(CSV形式を意識したカンマ区切り)
‘ ※実務ではここでExcelのセルに直接代入するか、配列に蓄積して一括出力する
Debug.Print arcCount + 1 & “,” & _
Format(vCenter(0), “0.000”) & “,” & Format(vCenter(1), “0.000”) & “,” & Format(vCenter(2), “0.000”) & “,” & _
Format(vStart(0), “0.000”) & “,” & Format(vStart(1), “0.000”) & “,” & Format(vStart(2), “0.000”) & “,” & _
Format(vEnd(0), “0.000”) & “,” & Format(vEnd(1), “0.000”) & “,” & Format(vEnd(2), “0.000”) & “,” & _
Format(dRadius, “0.000”)

arcCount = arcCount + 1
End If
Next i

Debug.Print “——————————————————————————–”
Debug.Print “完了: 抽出された円弧の総数 = ” & arcCount
Debug.Print “——————————————————————————–”

CleanUp:
‘ 5. 確実な環境復元
acadDoc.Application.Utility.SetVariable “CMDECHO”, 1
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “致命的エラー”
Resume CleanUp
End Sub

4. コードのアーキテクチャ解説(プロの視点)

このコードが「なぜ優れているのか」、その設計思想を解説しよう。

① 画面描画の抑制 (`CMDECHO`)

大規模な図面で `ModelSpace.Count` を回す際、AutoCADが余計な再描画を行おうとすると、それだけで処理が数倍遅くなる。`SetVariable “CMDECHO”, 0` を挟むことで、CADエンジンの無駄なリソース消費を防ぎ、極限のパフォーマンスを発揮させる。

② 厳密な型判定 (`TypeOf … Is AcadArc`)

`For Each` やインデックスループでエンティティを漁るとき、線分(Line)や文字(Text)など、円弧以外のオブジェクトが当然混ざる。
ここで `TypeOf` を使って確実にフィルタリングすることで、不意のメソッド・プロパティ呼び出しエラー(型が一致しません)を完全にシャットアウトしている。

③ 3次元配列の安全なハンドリング

AutoCADの `Center` や `StartPoint` は、内部的に `Double` 型の3要素配列(0番目:X, 1番目:Y, 2番目:Z)として渡される。
これを `Variant` 型の変数で一度受けてからインデックスアクセス (`vCenter(0)`) しているのは、COMオブジェクトへの無駄なプロパティアクセスを最小限にし、メモリ上の効率を最大化するためだ。

5. 発展:実務でさらに応用するためのヒント

このコードをベースに、現場のニーズに合わせて以下のように拡張してほしい。

  • Excelとのシームレスな連携:

`Debug.Print` でイミディエイトに出力している部分を、`CreateObject(“Excel.Application”)` を使ったCOM連携に書き換えれば、マクロの実行ボタン一つでフォーマット済みの集計表Excelが完成する。

  • レイアウト空間(PaperSpace)の網羅:

`ModelSpace` だけでなく、`Layouts` コレクションをループさせて、各ペーパー空間上のビューポートやレイアウト図面に描かれた円弧も対象に含めることで、取りこぼしのない完璧なデータ抽出が可能になる。

プロのエンジニアであれば、コードの「動く・動かない」だけでなく、「保守性」「パフォーマンス」「エラー耐性」の3つを常に意識すべきだ。今回の知見をあなたの開発環境に組み込み、日々の設計業務を自動化の力で圧倒的に効率化してほしい。

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