CADというクローズドな世界から、外部エコシステムへとデータを解き放つ。これは単なる「書き出し」ではなく、「設計情報のデジタル・トランスフォーメーション」の第一歩である。
私はこれまで、数えきれないほどのレガシーシステムと、肥大化したDWGファイルに向き合ってきた。その中で見えてきたのは、多くのエンジニアが「動けばいい」というコードで妥協し、数万個のオブジェクトを前にメモリリークやパフォーマンス不足で沈んでいく姿だ。
今回は、AutoCAD VBAを用いた「ポリライン頂点座標のCSVエクスポート」を題材に、実務中級者が到達すべき、堅牢かつ高効率なアーキテクチャを解説する。
—
1. ポリラインという「多義的」な存在への理解
まず、設計者とプログラマの認識を合わせる必要がある。AutoCADにおける「ポリライン」は一つではない。
- AcadLWPolyline (Lightweight Polyline): 現代の主流。メモリ効率が良く、頂点データは単一の配列として保持される。
- AcadPolyline (Old-style/2D/3D Polyline): 各頂点がサブエンティティ(Vertexオブジェクト)としてネストされているレガシーな構造。
プロフェッショナルは、これらを混同しない。今回のコードでは、現在の標準である `AcadLWPolyline` を主軸に据えつつ、大量のデータ処理に耐えうる実装を行う。
2. Windows APIによる高精度制御とパフォーマンスの極意
大規模な図面では、数千本のポリライン、数十万の頂点を扱うことになる。ここで `SelectionSets` の管理を誤れば、AutoCADのメモリ空間は瞬時に断片化する。
また、CSV出力においては、VBA標準の `Print #` 文でも十分だが、システム間連携を意識するなら、パスの扱いやファイルシステムのロック状態を考慮し、Windows APIを利用したダイアログ制御や、ファイルシステムオブジェクト(FSO)の適切なハンドリングが必要だ。
アーキテクチャの要諦:
1. SelectionFilterの活用: 全オブジェクトをループで回すのは素人の仕事だ。DXFグループコードを用いて、ポリラインのみをメモリにロードする。
2. Variant配列のダイレクト処理: `Coordinates` プロパティが返すVariant配列を、型安全に高速にパースする。
3. 明示的なメモリ解放: AutoCAD VBAのガベージコレクションは信頼しすぎない。`Set … = Nothing` による明示的な破棄を徹底する。
—
3. 極限の抽出コード:ExportPolylineVerticesToCSV
以下に、実戦投入を前提としたコードを示す。このコードは、単に座標を出すだけでなく、ポリラインのハンドル(一意なID)を付与することで、外部データベースとの紐付けを可能にしている。
Option Explicit
‘ ==============================================================================
‘ AutoCAD Polyline Vertex Exporter (System Integration Edition)
‘
‘ 概要: 図面内の全LWPolylineの頂点座標を抽出し、CSV形式で出力する。
‘ 性能: SelectionFilterにより高速なスキャンを実現。大量オブジェクトにも対応。
‘ ==============================================================================
Public Sub ExportPolylineVerticesToCSV()
On Error GoTo ErrorHandler
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
‘ — 1. 出力ファイルの選定 (Windows標準ダイアログの代替案) —
Dim filePath As String
filePath = Environ(“USERPROFILE”) & “\Desktop\PolylineVertices_” & Format(Now, “YYYYMMDD_HHNNSS”) & “.csv”
‘ — 2. 選択セットの構築 (フィルタリングによる高速化) —
Dim sSet As AcadSelectionSet
On Error Resume Next
Set sSet = acadDoc.SelectionSets.Add(“SS_POLY_EXPORT”)
If Err.Number <> 0 Then
Set sSet = acadDoc.SelectionSets.Item(“SS_POLY_EXPORT”)
sSet.Clear
End If
On Error GoTo ErrorHandler
‘ DXFフィルタ: LWPOLYLINE (0) のみを抽出
Dim filterType(0) As Integer: filterType(0) = 0
Dim filterData(0) As Variant: filterData(0) = “LWPOLYLINE”
sSet.Select acSelectionSetAll, , , filterType, filterData
If sSet.Count = 0 Then
MsgBox “対象となるポリラインが見つかりません。”, vbExclamation
Exit Sub
End If
‘ — 3. ファイル出力処理 —
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim ts As Object
Set ts = fso.CreateTextFile(filePath, True)
‘ ヘッダーの書き込み (BOMなしUTF-8/Shift-JISは環境に依存)
ts.WriteLine “Handle,Layer,VertexIndex,X,Y,Z”
Dim ent As AcadEntity
Dim lwPoly As AcadLWPolyline
Dim coords As Variant
Dim i As Long, j As Long
Dim vertexCount As Long
‘ 進捗表示用 (大規模処理時のフリーズ回避)
Application.StatusBar = “データ抽出中…”
For Each ent In sSet
If TypeOf ent Is AcadLWPolyline Then
Set lwPoly = ent
coords = lwPoly.Coordinates ‘ 頂点座標配列を取得 [x0, y0, x1, y1, …]
vertexCount = (UBound(coords) + 1) / 2
For i = 0 To vertexCount – 1
‘ CSV行の構築
‘ lwPoly.Elevation はLWPolylineのZ座標を代表する
ts.WriteLine lwPoly.Handle & “,” & _
lwPoly.Layer & “,” & _
i & “,” & _
coords(i 2) & “,” & _
coords(i 2 + 1) & “,” & _
lwPoly.Elevation
Next i
End If
Next ent
ts.Close
‘ — 4. 後処理とリソース解放 —
Application.StatusBar = “”
sSet.Delete ‘ 選択セットの明示的削除
MsgBox “抽出完了: ” & filePath, vbInformation, “Success”
Exit Sub
ErrorHandler:
Application.StatusBar = “”
MsgBox “致命的エラーが発生しました: ” & Err.Description, vbCritical
If Not sSet Is Nothing Then sSet.Delete
If Not ts Is Nothing Then ts.Close
End Sub
—
4. 現場のシニアエンジニアが注目すべき点
オブジェクトの「Handle」を出力する理由
AutoCADの `Handle` は、図面内で永続的な一意のIDだ。CSVに出力された座標を外部システム(Excelやデータベース)で加工した後、再びAutoCADに戻って特定の図形を更新したい場合、この `Handle` が唯一の架け橋となる。`ObjectID` はセッションごとに変わる可能性があるため、外部連携には不向きだ。
座標系の罠(WCS vs OCS)
`AcadLWPolyline` の `Coordinates` は、OCS(オブジェクト座標系)で保持されている。ほとんどの2D図面ではWCS(世界座標系)と一致しているが、押し出し方向(Normalプロパティ)が `(0, 0, 1)` 以外の場合は、座標変換が必要になる。この点に気付かずシステムを構築すると、特定の回転された図面で座標がズレるという、原因不明のバグに悩まされることになる。
メモリ管理の鉄則
`SelectionSets.Add` は、既に同じ名前が存在する場合にエラーを吐く。これを `On Error Resume Next` でハンドリングし、既存のセットを再利用・クリアする手法は、長期稼働するアドインにおいて必須のテクニックだ。これを怠ると、繰り返し実行時に「名前が重複しています」という初歩的なエラーでシステムが停止する。
—
5. 終わりに:自動化の先にあるもの
ポリラインの頂点抽出は、単なる「作業の自動化」ではない。それは、図面という「絵」を、解析可能な「構造化データ」へと昇華させるプロセスである。
このスクリプトをベースに、次は頂点間の距離計算による検図の自動化、あるいはGIS(地理情報システム)への座標流し込みなど、さらなる高度な連携へと駒を進めてほしい。我々エンジニアの仕事は、レガシーな環境を嘆くことではなく、そこに最新の知見という名の楔を打ち込み、価値を最大化することにあるのだから。
