【入門編】【実務中級】図面内の全ポリライン(Polyline)の頂点座標をリスト化し、CSVファイルへエクスポートする – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは。現場の最前線でAutoCADの自動化を極め続けてきたチーフアーキテクトです。

「マクロの記録」を卒業し、自分の手でコードを書き始めた皆さんが最初にぶつかる壁。それは「図面という情報の塊から、いかにして必要なデータだけを抜き出し、外部で使える形にするか」という課題です。

今回は、実務で最も要望が多いテーマの一つ、「ポリラインの頂点座標をCSVに書き出す」という処理を深く掘り下げます。単に動くコードを提示するだけでなく、なぜそのオブジェクトを使うのか、プロの現場で通用する「エラーを起こさないための作法」を含めて伝授しましょう。

ここをマスターすれば、AutoCAD VBAのオブジェクトモデルの扱いは一気にレベルアップしますよ。

1. AutoCAD VBAの「心臓部」を理解する

コードを書く前に、私たちが操作する相手の構造(オブジェクトモデル)を頭に入れておきましょう。

1. AcadApplication: AutoCADそのもの。
2. AcadDocument: 現在開いている図面ファイル。
3. ModelSpace: 図面の中の「モデル空間」。ここにあらゆる図形(Entity)が住んでいます。

今回のミッションは、「ModelSpaceの中にいる図形たちの中から、ポリライン(LWPolyline)だけを見つけ出し、その内側に隠されている『座標配列』をこじ開ける」という作業です。

2. 【実践】全ポリラインの座標をCSVへ出力するVBAコード

それでは、実戦的なコードを見ていきましょう。このままコピペして利用可能ですが、各所に仕込んだコメントに「プロの知見」を詰め込んであります。

Option Explicit

‘ =================================================================
‘ 目的: 図面内の全ライトウェイトポリラインの頂点座標を抽出しCSV出力する
‘ 核心: 選択セット(SelectionSet)の適切な管理と座標配列の展開
‘ =================================================================
Sub ExportPolylineVerticesToCSV()
Dim acadApp As AcadApplication
Dim acadDoc As AcadDocument
Set acadApp = ThisDrawing.Application
Set acadDoc = acadApp.ActiveDocument

‘ 1. 出力先CSVファイルの準備
Dim filePath As String
filePath = Environ(“USERPROFILE”) & “\Desktop\PolylineVertices.csv”

Dim fileNo As Integer
fileNo = FreeFile

On Error Resume Next
Open filePath For Output As #fileNo
If Err.Number <> 0 Then
MsgBox “CSVファイルを開けませんでした。Excel等で開いていないか確認してください。”, vbCritical
Exit Sub
End If
On Error GoTo 0

‘ ヘッダーの書き込み
Print #fileNo, “EntityHandle,VertexIndex,X,Y”

‘ 2. ポリラインを効率的に取得するための「選択セット」の構築
‘ モデル空間を全部ループするのは素人のやり方です。フィルタを使いましょう。
Dim sSet As AcadSelectionSet
On Error Resume Next
‘ 既存の同名選択セットがあれば削除(これ重要!)
Set sSet = acadDoc.SelectionSets.Item(“PolyExtractSet”)
If Not sSet Is Nothing Then sSet.Delete
On Error GoTo 0

Set sSet = acadDoc.SelectionSets.Add(“PolyExtractSet”)

‘ フィルタの設定:LWPOLYLINE(ライトウェイトポリライン)のみを抽出
Dim filterType(0) As Integer: filterType(0) = 0
Dim filterData(0) As Variant: filterData(0) = “LWPOLYLINE”

‘ 図面全体から検索
sSet.Select acSelectionSetAll, , , filterType, filterData

‘ 3. データの解析と書き出し
Dim pLine As AcadLWPolyline
Dim ent As AcadEntity
Dim coords As Variant
Dim i As Long, j As Long
Dim polyCount As Long: polyCount = 0

For Each ent In sSet
Set pLine = ent
‘ Coordinatesプロパティは [x1, y1, x2, y2, …] という1次元配列を返す
coords = pLine.Coordinates

‘ 頂点座標をペアで取り出す
j = 0
For i = LBound(coords) To UBound(coords) Step 2
‘ 形式: ハンドル名(図面固有ID), 頂点番号, X座標, Y座標
Print #fileNo, pLine.Handle & “,” & j & “,” & coords(i) & “,” & coords(i + 1)
j = j + 1
Next i
polyCount = polyCount + 1
Next ent

Close #fileNo
sSet.Delete ‘ 使い終わった選択セットは即座に破棄

MsgBox polyCount & ” 個のポリラインからデータを抽出しました。” & vbCrLf & _
“保存先: ” & filePath, vbInformation, “完了”
End Sub

3. ここが「掌握」のポイント:解説と注意点

① なぜ「SelectionSet(選択セット)」を使うのか?

図面内の全オブジェクトを `For Each ent In ModelSpace` で回すと、数万個の図形がある図面では処理が極端に重くなります。
プロのエンジニアは「フィルタ」を使います。今回のコードでは `filterData(0) = “LWPOLYLINE”` と指定することで、AutoCAD側に「ポリラインだけをよこせ」と命令しています。これがパフォーマンス向上の秘訣です。

② LWPolyline と Polyline の違いに注意

AutoCADには2種類のポリラインがあります。

  • LWPolyline (Lightweight Polyline): 現在の標準。座標が $(x, y)$ のペアで格納されます。
  • Polyline (Heavyweight Polyline): 古い形式や3Dポリライン。座標が $(x, y, z)$ のトリオで格納されます。

実務の9割はLWPolylineですが、もし古い図面を扱う場合は `Coordinates` から取り出すステップ数を `Step 3` に変更する必要があることを覚えておいてください。

③ 座標配列 `Coordinates` の正体

`pLine.Coordinates` を実行すると、Variant型の配列が返ってきます。
中身は `(X0, Y0, X1, Y1, X2, Y2…)` というフラットな構造です。そのため、ループ内で `Step 2` を使い、2個飛ばしで値を取得するのが最もスマートな実装です。

④ 選択セットの「名前重複エラー」の回避

AutoCAD VBAで最も多いエラーの一つが、`SelectionSets.Add` 時の「同名セットが既に存在する」というエラーです。
私のコードでは、`On Error Resume Next` を使って、「もし既にあったら一旦消してから作り直す」という処理を入れています。これは「落ちないツール」を作るための必須テクニックです。

4. さあ、次のステップへ

このコードが理解できれば、あなたはもう「図面の中のデータを自由に外部へ持ち出す力」を手に入れました。

  • X, Y座標だけでなく、`pLine.Area` で面積も一緒に出力してみる。
  • `pLine.Layer` を取得して、レイヤーごとにCSVを分けてみる。
  • 逆にCSVを読み込んで、図面にポリラインを自動で作図してみる。

応用範囲は無限大です。
AutoCAD VBAは、使いこなせば「一日の手作業を数秒で終わらせる」魔法の杖になります。一つ一つのプロパティの意味を噛み締めながら、ぜひ自分の手でコードを動かしてみてください。

もしエラーで詰まったら、いつでもこのコードに戻ってきてください。基本はここにすべて詰まっています。

「ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ。応援しています!」

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