AutoCAD VBAの深淵:特定レイアウトを「真にクリーンな新規図面」として切り出す極意
AutoCADの図面管理において、マルチレイアウト図面から「特定の一枚だけ」を抜き出して納品用データを作る作業。手動で行えば、不要なレイアウトの削除、不要なブロック定義のパージ、そしてファイル名の変更……これだけでミスが入り込む余地が生まれる。
中級者レベルになると、「`CopyObjects`メソッドを使えばいい」という知識に辿り着く。しかし、実務で戦う我々が求めるのは、「参照リンクの断絶」や「不要な辞書データのゴミ(ゴミ掃除)」を完全に排除した、堅牢な独立ファイルだ。
今回は、AutoCAD APIのライフサイクルを考慮した、プロフェッショナルなエクスポート・ロジックを伝授する。
—
1. なぜ「単純なコピペ」ではいけないのか
多くの初心者が陥る罠は、`WBLOCK`コマンドをスクリプトで叩くか、`CopyObjects`で全要素を新規ドキュメントへ放り込む手法だ。しかし、これには以下のリスクが伴う。
- 名前付きオブジェクトの衝突: 既存の画層設定や線種定義が引き継がれ、納品先で意図しない表示崩れを起こす。
- 不要なメタデータの肥大化: 親図面の膨大なブロック定義や、使用していない外部参照情報が残骸として残り、ファイルサイズが肥大化する。
- トランザクションの未制御: 巨大な図面を操作する際、メモリ管理が甘いとAutoCADは無慈悲にクラッシュする。
我々が目指すべきは、「必要なレイアウトと、それに付随する最小限の定義のみをクリーンルームにコピーする」というアプローチだ。
—
2. 実装の核心:プロダクションコード
以下のコードは、アクティブなドキュメントから指定したレイアウトを抽出し、クリーンな新規DWGとして保存する設計だ。
Option Explicit
‘ ———————————————————
‘ 機能:指定レイアウトを新規DWGとして書き出す
‘ ———————————————————
Public Sub ExportLayoutToNewDrawing(ByVal layoutName As String, ByVal savePath As String)
Dim srcDoc As AcadDocument
Dim destDoc As AcadDocument
Dim targetLayout As AcadLayout
Set srcDoc = ThisDrawing.Application.ActiveDocument
‘ 1. レイアウトの存在確認
On Error Resume Next
Set targetLayout = srcDoc.Layouts.Item(layoutName)
If Err.Number <> 0 Then
MsgBox “指定レイアウトが見つかりません。”, vbCritical
Exit Sub
End If
On Error GoTo 0
‘ 2. 新規ドキュメントの作成(acad.dwtをベースに)
Set destDoc = srcDoc.Application.Documents.Add(“acad.dwt”)
‘ 3. レイアウトのコピー
‘ CopyObjectsは、オブジェクトの配列と所有先(Owner)を指定する
‘ ここでは既存のモデル空間をクリアし、コピー対象を移動させる
Dim objList(0) As Object
Set objList(0) = targetLayout.Block
‘ 既存の「レイアウト1」を削除し、新しい環境へ注入する
srcDoc.CopyObjects objList, destDoc.ModelSpace
‘ 4. ファイル保存と後処理
‘ 不要なオブジェクトをパージするコマンドを擬似的に実行
destDoc.SendCommand “-PURGE All No ” & vbCr
‘ 名前を付けて保存(バージョン互換のため2018形式などを指定可能)
destDoc.SaveAs savePath, ac2018_DWG
destDoc.Close False
MsgBox “エクスポート完了: ” & savePath
End Sub
—
3. 現場で生き残るための設計思想
① 「SendCommand」への依存を避ける
上記のコードでパージに`SendCommand`を使用しているが、これは非同期処理であり、大規模図面ではタイミング問題で失敗することがある。本気で作り込むなら、`Purge`メソッドや、データベース内を走査して`Delete`するロジックを組むのが「伝説的」なエンジニアの流儀だ。
② ファイルパスの検証を怠るな
VBAのファイル入出力は、書き込み権限がないフォルダを指定した瞬間にエラーで止まる。`Dir`関数での事前チェックはもちろん、ネットワークドライブ上のパスかどうかも考慮すべきだ。
③ 辞書データ(Dictionaries)の扱い
レイアウトには、しばしばプロット設定や独自の拡張データ(XRecord)が付随する。これらが必要ない場合、コピー後に`destDoc.Dictionaries`を走査し、不要なものを削除する処理を挟むことで、納品先で「図面が重い」と文句を言われることを防げる。
—
4. 最後に:エンジニアへの提言
自動化ツールは「書くこと」よりも「運用中に壊れないこと」に価値がある。
今回のコードはあくまでテンプレートだ。実務では、以下の要素を加えて「自分専用の武器」へ昇華させてほしい。
- ログ出力: どの図面からどのレイアウトを抜き出したか、テキストファイルに記録を残すこと。
- テンプレート連携: 会社の標準テンプレート(DWT)を確実に読み込ませるパス指定の徹底。
- エラーハンドリング: `On Error Resume Next`の乱用は禁物だ。必ず`Err.Clear`と組み合わせ、どこで失敗したかを明確に追いかけられるようにする。
AutoCADのAPIは古い。しかし、その分だけ先人たちの苦悩と解決策が積み重なっている。このコードをベースに、君たちの現場に合わせた最強の自動化ツールを組み上げてくれ。健闘を祈る。
