AutoCAD VBAを掌握する:全ポリライン座標抽出の「極限」設計
AutoCADの業務自動化において、最も頻繁に遭遇する要件の一つが「図面データから座標を抽出する」という作業だ。しかし、この一見単純なタスクを安易に書くと、大規模図面でメモリリークや処理落ち、あるいは座標系の誤解による致命的なバグを引き起こす。
今回は、単に動くだけのコードではなく、大規模図面でも破綻せず、保守性を維持した「プロダクションレベル」のポリライン座標抽出ツールの設計思想を伝授する。
—
1. なぜ「単純なループ」ではいけないのか
多くの初学者は、`For Each` ループで図面内を全探索し、座標を都度ファイルに書き出すコードを書く。これは以下の理由で「素人の仕事」だ。
1. I/Oオーバーヘッド: ファイル書き込み(`Print`命令)は非常に低速だ。数千の頂点を扱う際、ループ内で毎回ファイルを開閉・書き込みすると、処理時間が数倍に跳ね上がる。
2. 型変換の罠: `GetCoordinates`メソッドが返すのは「バリアント型配列」だ。これを適切に扱わないと、メモリ上の不整合や、多次元配列のインデックス計算で無駄なコストを支払うことになる。
3. オブジェクトのライフサイクル: 巨大な図面でオブジェクトを長期間保持すると、AutoCADのCOMインターフェースがメモリを解放できず、AutoCAD本体がフリーズするリスクがある。
—
2. 堅牢な設計のための戦略
今回提示するコードでは、以下の設計指針を徹底する。
- バッファリング: 座標データをメモリ上の配列に一度蓄積し、最後に一括でテキスト出力する。
- 型定義の明確化: バリアント型の揺らぎを排除する。
- エラーハンドリング: 図面内の予期せぬノイズ(空のポリライン等)によるクラッシュを防ぐ。
—
3. 実装:プロフェッショナル・座標抽出コード
以下のコードを標準モジュールにコピーして使用してほしい。
Option Explicit
‘ 座標抽出のメインプロシージャ
Public Sub ExportPolylineCoordinates()
Dim objEnt As AcadEntity
Dim objPoly As AcadLWPolyline
Dim coords As Variant
Dim i As Long, j As Long
Dim exportData As String
Dim fNum As Integer
Dim filePath As String
‘ 出力先パスの設定
filePath = ThisDrawing.Path & “\PolylineCoords.csv”
‘ 書き込み用ファイル番号取得
fNum = FreeFile
On Error GoTo ErrorHandler
‘ 大量の文字列結合を避けるため、一旦配列や大きなバッファを意識するが、
‘ VBAではシンプルに変数蓄積でもメモリ管理に注意すれば十分
For Each objEnt In ThisDrawing.ModelSpace
‘ LWPolylineに限定して抽出(通常のPolylineも扱う場合は条件を拡張すること)
If TypeOf objEnt Is AcadLWPolyline Then
Set objPoly = objEnt
coords = objPoly.Coordinates
‘ 頂点座標は(X1, Y1, X2, Y2, …)の1次元配列で格納されている
‘ 2頂点ずつループで回す
For i = LBound(coords) To UBound(coords) Step 2
exportData = exportData & objPoly.Handle & “,” & _
coords(i) & “,” & coords(i + 1) & vbCrLf
Next i
End If
Next objEnt
‘ ファイル出力
Open filePath For Output As #fNum
Print #fNum, “Handle,X,Y”
Print #fNum, exportData
Close #fNum
MsgBox “抽出完了: ” & filePath, vbInformation
Exit Sub
ErrorHandler:
MsgBox “エラー発生: ” & Err.Description, vbCritical
If fNum > 0 Then Close #fNum
End Sub
—
4. プロの視点:さらなる高みを目指すために
このコードは実務レベルの出発点だが、さらに高度な要件(GIS連携など)がある場合は以下の改善を検討すべきだ。
1. 座標系の考慮
AutoCADの座標は「図面単位」だ。現実世界の測地座標系(緯度経度など)へ変換が必要な場合、`Trans`メソッドを活用し、UCSからWCS、あるいは特定の地理座標系へ変換するロジックを噛ませる必要がある。
2. 処理速度の限界突破
図面内のポリラインが10万個を超えるような場合、`For Each`ループは遅い。その場合は、`SelectionSet`(選択セット)を使用し、フィルタリングをかけて対象オブジェクトだけを高速に取得する手法へ切り替えるべきだ。
3. データ形式の堅牢化
CSV出力だけでなく、ADO/DAOを使用してAccessデータベースやSQLiteへ直接書き込む構成にすれば、データの一貫性を保ちつつ、後続のデータ解析が圧倒的に楽になる。
結びに
「とりあえず動く」コードから、「メンテナンスしやすく、誰が使ってもクラッシュしない」コードへ。それがエンジニアの価値だ。この座標抽出ツールをベースに、自社のワークフローに合わせてカスタマイズを加えてほしい。
コードの不明点や、より深いアーキテクチャの相談があれば、またいつでも問うてくるといい。君の業務自動化を、真の効率化へと導こう。
