CADを単なる「図面作成ツール」だと思っているうちは、二流だ。
真のプロフェッショナルは、AutoCADを「空間情報を保持したデータベース」として扱う。
設計変更のたびに図面から座標を拾い、Excelに手打ちするような不毛な作業は今日で終わりにしよう。今回は、図面内の全ポリラインから頂点座標をブッコ抜き、外部システムが即座に食えるクリーンなCSVとして出力する「実戦型プロトコル」を伝授する。
単に動くだけのコードではない。数万個のオブジェクトを扱っても破綻せず、保守性に優れた「プロダクションレベル」の設計思想を叩き込む。
—
1. ポリライン抽出における「二つの罠」
コードを書く前に、設計者として回避すべき致命的な落とし穴が2つある。
① 「軽量ポリライン」と「旧形式ポリライン」の混在
AutoCADには、メモリ効率の良い`AcadLWPolyline`(軽量ポリライン)と、3Dや旧形式の`AcadPolyline`が存在する。これらはオブジェクトモデルが異なり、頂点データの保持形式も違う。
- LWPolyline: `Coordinates` プロパティが `Variant(Double)` の1次元配列 `[x1, y1, x2, y2, …]` を返す。
- Polyline (2D/3D): 各頂点が独立した `AcadVertex` オブジェクトとしてぶら下がっている。
実務では、これらを統合的に扱うか、あるいは明確にフィルタリングする設計が必要だ。
② 座標系(UCS vs WCS)の混乱
図面上でユーザーが設定しているUCS(ユーザー座標系)のまま値を出力すると、外部システムで合成した際に位置がズレる。データ連携の鉄則は「常にWCS(世界座標系)で書き出す」ことだ。
—
2. プロダクション・コード:PolylineCoordinateExporter
以下のコードは、エラーハンドリング、選択セットの適切な開放、そして型判定を網羅した実戦用だ。
Option Explicit
‘ =================================================================
‘ 概要: 図面内の全ポリライン頂点を抽出しCSV出力する
‘ 設計思想:
‘ 1. 既存の選択セットとの競合を避けるクリーンアップ処理
‘ 2. LWPolylineとPolylineの双方に対応するポリモーフィズム的アプローチ
‘ 3. I/O負荷を最小限にするためのシーケンシャルアクセス
‘ =================================================================
Public Sub ExportPolylineVerticesToCSV()
On Error GoTo ErrorHandler
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
‘ 1. 出力パスの設定(図面と同じフォルダ)
Dim csvPath As String
csvPath = acadDoc.Path & “\” & Left(acadDoc.Name, InStrRev(acadDoc.Name, “.”) – 1) & “_Vertices.csv”
‘ 2. 選択セットの取得(既存同名セットの削除)
Dim selSet As AcadSelectionSet
On Error Resume Next
Set selSet = acadDoc.SelectionSets.Item(“SS_POLY_EXPORT”)
If Not selSet Is Nothing Then selSet.Delete
On Error GoTo ErrorHandler
Set selSet = acadDoc.SelectionSets.Add(“SS_POLY_EXPORT”)
‘ 3. フィルタリング定義(ポリラインのみを選択)
Dim filterType(0) As Integer: filterType(0) = 0
Dim filterData(0) As Variant: filterData(0) = “POLYLINE” ‘ LWPOLYLINE, POLYLINEの両方にヒット
selSet.Select acSelectionSetAll, , , filterType, filterData
If selSet.Count = 0 Then
MsgBox “対象となるポリラインが見つかりません。”, vbInformation
Exit Sub
End If
‘ 4. ファイルオープン
Dim fileNum As Integer: fileNum = FreeFile
Open csvPath For Output As #fileNum
‘ ヘッダー書き込み
Print #fileNum, “Handle,EntityName,VertexIndex,X,Y,Z”
Dim ent As AcadEntity
Dim i As Long, vIdx As Long
Dim coords As Variant
‘ 5. メインループ
For Each ent In selSet
If TypeOf ent Is AcadLWPolyline Then
‘ — 軽量ポリラインの処理 —
Dim lwPoly As AcadLWPolyline: Set lwPoly = ent
coords = lwPoly.Coordinates
vIdx = 0
For i = LBound(coords) To UBound(coords) Step 2
‘ CSV出力: ハンドル, クラス名, 頂点番号, X, Y, Z(LWは常に一定または0)
Print #fileNum, lwPoly.Handle & “,AcadLWPolyline,” & vIdx & “,” & _
coords(i) & “,” & coords(i + 1) & “,” & lwPoly.Elevation
vIdx = vIdx + 1
Next i
ElseIf TypeOf ent Is AcadPolyline Then
‘ — 2D/3Dポリラインの処理 —
Dim poly As AcadPolyline: Set poly = ent
coords = poly.Coordinates
vIdx = 0
‘ AcadPolylineのCoordinatesは [x, y, z] の3要素1セット
For i = LBound(coords) To UBound(coords) Step 3
Print #fileNum, poly.Handle & “,AcadPolyline,” & vIdx & “,” & _
coords(i) & “,” & coords(i + 1) & “,” & coords(i + 2)
vIdx = vIdx + 1
Next i
End If
Next ent
Close #fileNum
selSet.Delete
MsgBox “抽出完了: ” & csvPath, vbInformation
Exit Sub
ErrorHandler:
If fileNum > 0 Then Close #fileNum
MsgBox “エラー発生: ” & Err.Description, vbCritical
End Sub
—
3. アーキテクトによる深掘り解説
なぜ `Handle`(ハンドル)を出力するのか?
図面内のオブジェクトは、セッションが変われば `ObjectID` が変わる可能性がある。しかし、`Handle` は図面ファイル内で永続的な一意のIDだ。外部のデータベース(SQL ServerやExcel管理表)と図面を紐付ける際、ハンドルこそが最強のプライマリキーになる。これを書き出さない連携ツールは、実務では使い物にならない。
選択セット(SelectionSet)の管理
初心者は `acadDoc.SelectionSets.Add` を連発し、「既に存在します」というエラーでプログラムを止める。
今回のコードでは、`On Error Resume Next` を利用して既存のセットを安全に削除してから再作成している。これはAutoCAD VBAにおける定石であり、堅牢性を担保する必須テクニックだ。
パフォーマンスの最適化
今回は `Print #` ステートメントによるシーケンシャルアクセスを採用した。
もし出力対象が数十万頂点に及ぶ場合、一旦すべてのデータを巨大な文字列バッファ(あるいは配列)に格納してから一気にファイルへ書き出す手法があるが、VBAのメモリ管理の脆弱さを考えると、1エンティティごとにストリームへ流し込むこの手法が、最もクラッシュしにくく安定する。
—
4. さらなる高みへ:外部連携の拡張
このコードをベースに、以下の拡張を検討せよ。これができれば、君の評価は「ただの自動化担当」から「DX推進のキーマン」へと跳ね上がる。
1. 属性(Attribute)の結合: ポリラインが特定のブロック(部屋番号など)に囲まれている場合、その属性情報もCSVに付与する。
2. レイヤーによるフィルタリング: `filterType` を増やし、特定のレイヤー(例: “KABE_LINE”)だけを抽出対象にする。
3. 閉じたポリラインの面積算出: `ent.Area` プロパティを同時に出力し、集計資料を自動生成する。
結論
AutoCAD VBAは古臭い技術だと言われることもある。しかし、オブジェクトモデルの本質を理解し、堅牢なエラー処理とデータ構造を設計できれば、今なお最強の武器になる。
このコードをコピペして満足せず、なぜこの順序で処理しているのか、なぜこの型を使っているのかを反芻してほしい。その思考の積み重ねが、君を「真のアーキテクト」へと変える。
