AutoCAD VBAを掌握する極限の知見:DWF/DWFxエクスポートの自動化と堅牢なパブリッシュ制御
開発現場のリーダーである私のもとに、よくこんな相談が寄せられる。
「大量の図面を協力会社や他部署に共有するため、軽量なDWFやDWFxへ一括変換したい。しかし、マクロを組むとプリンタ設定が暴走したり、レイアウトごとに予期せぬスケールアウトを起こしたりする」と。
DWGからDWFへの変換は、単なる「名前を付けて保存」ではない。背後にあるプロットエンジン(PlotEngine)とデバイスドライバのライフサイクルを完全に手綱に握る必要がある。
今回は、実務中級者が陥る「画面のちらつき」「メモリリーク」「ページ設定の継承ミス」を完璧に回避し、実戦投入可能なプロダクションレベルのコードともに、DWF/DWFx一括エクスポートの極意を伝授しよう。
—
1. なぜ「素のセーブ」や非効率なコードでは失敗するのか
多くの開発者がやりがちな間違いが、`SendCommand`を使ったLISPコマンドの叩き売りや、ActiveDocumentの不適切な操作だ。
‘ 【アンチパターンの例】絶対にやってはいけない実装
ThisDrawing.SendCommand “-EXPORT” & vbCr & “DWF” & vbCr & “filename.dwf” & vbCr
このアプローチが実務で破綻する理由は明白だ。
1. モーダルダイアログの介入: AutoCADの内部コマンドは、環境変数やダイアログの状態で挙動が変わり、フリーズの原因になる。
2. バックグラウンド処理の欠如: 描画コンテキストが生きたまま処理が行われるため、大量処理時にメモリリークを引き起こす。
3. ページ設定(PlotConfiguration)の無視: 図面側のデフォルトプロッタに依存するため、環境が変わると出力結果が崩壊する。
プロとして、AutoCADのオブジェクトモデルである `Plot` オブジェクトと `Layout` オブジェクトを直接操作し、GUIを介さずにメモリ上で完結させる設計(Headless Execution)を構築しなければならない。
—
2. 実務で耐えうる堅牢なアーキテクチャ設計
DWF/DWFx出力の自動化において、押さえるべき設計ポイントは以下の3点だ。
- 専用DWFパブリッシャドライバの指定: `PublishToWeb DWF.pc3` または `PublishToWeb DWFx.pc3` をコード側から強制アタッチする。
- レイアウトの列挙とフィルタリング: モデル空間および有効なペーパー空間(レイアウト)のみをターゲットにし、無効なシートを除外する。
- エラーハンドリングとトランザクション的思考: 1枚の図面のパブリッシュ失敗が、全バッチ処理を止めない構造にする。
—
3. 【プロダクションコード】DWF/DWFx一括エクスポート・エンジン
以下のコードは、指定したフォルダ内のDWGファイルを走査し、各レイアウトを適切な設定でDWF/DWFxへサイレント出力する実用モジュールだ。エラーハンドリングを徹底し、実務の現場でそのまま組み込めるよう設計している。
Option Explicit
‘ ==============================================================================
‘ モジュール名: modDwfExporter
‘ 概要 : DWGファイルをバックグラウンドで処理し、DWF/DWFxへ一括出力する
‘ 依存関係 : AutoCAD Type Library
‘ ==============================================================================
Public Sub BatchExportToDWF()
Dim targetFolder As String
Dim exportFormat As String
Dim fso As Object
Dim folder As Object
Dim file As Object
‘ 1. 設定値の定義(実務ではUIやINIファイルから取得すること)
targetFolder = “C:\AutoCAD_Work\TargetDWG\”
exportFormat = “DWFx” ‘ “DWF” または “DWFx” を選択
Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FolderExists(targetFolder) Then
MsgBox “指定されたフォルダが存在しません: ” & targetFolder, vbCritical, “パスエラー”
Exit Sub
End If
Set folder = fso.GetFolder(targetFolder)
‘ 2. AutoCADのパフォーマンス最適化(画面描画とアラートの抑制)
On Error GoTo ErrorHandler
Application.ScreenUpdating = False
Dim successCount As Long
Dim errorCount As Long
successCount = 0
errorCount = 0
‘ 3. フォルダ内のDWGファイルをループ処理
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Name)) = “dwg” Then
If ProcessSingleDrawing(file.Path, exportFormat) Then
successCount = successCount + 1
Else
errorCount = errorCount + 1
End If
End If
Next file
‘ 4. 処理結果の通知
Application.ScreenUpdating = True
MsgBox “DWFエクスポートが完了しました。” & vbCrLf & _
“成功: ” & successCount & ” 件” & vbCrLf & _
“失敗: ” & errorCount & ” 件”, vbInformation, “バッチ処理完了”
Exit Sub
ErrorHandler:
Application.ScreenUpdating = True
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “システムエラー”
End Sub
Private Function ProcessSingleDrawing(ByVal dwgPath As String, ByVal formatType As String) As Boolean
Dim doc As AcadDocument
Dim originalLayouts() As String
Dim layout As AcadLayout
Dim plotObj As AcadPlot
Dim plotConfigName As String
Dim mediaName As String
Dim outputFilePath As String
Dim fso As Object
On Error GoTo InnerError
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ ドキュメントを非表示(または最小限)で開く
‘ Documents.Openはバックグラウンドオープンができないため、アクティブ化を最小限にする
Set doc = Documents.Open(dwgPath, True)
Set plotObj = doc.Plot
‘ DWF出力用仮想プリンタの選択
If formatType = “DWFx” Then
plotConfigName = “PublishToWeb DWFx.pc3”
Else
plotConfigName = “PublishToWeb DWF.pc3”
End If
‘ 全レイアウトを走査してプロットを実行
For Each layout In doc.Layouts
‘ 「モデル」および有効な「レイアウト」のみを対象とする(名前空間の除外)
If layout.ModelSpace = True Or layout.Block.Count >= 0 Then
doc.ActiveLayout = layout
‘ ページ設定の適用(デバイスドライバと用紙サイズの強制バインド)
layout.ConfigName = plotConfigName
‘ 出力ファイルパスの生成(例: 図面名_レイアウト名.dwfx)
Dim baseName As String
baseName = fso.GetBaseName(dwgPath)
outputFilePath = fso.GetParentFolderName(dwgPath) & “\” & baseName & “_” & layout.Name & “.” & LCase(formatType)
‘ プロット実行(PlotToDeviceメソッド)
If plotObj.PlotToDevice(outputFilePath) Then
‘ 正常終了のログ記録などが必要であればここに記述
End If
End If
Next layout
‘ 変更を保存せずに閉じる(メモリの解放)
doc.Close False
ProcessSingleDrawing = True
Exit Function
InnerError:
‘ エラー時はドキュメントを強制クローズしてメモリリークを防ぐ
On Error Resume Next
If Not doc Is Nothing Then doc.Close False
ProcessSingleDrawing = False
End Function
—
4. チーフアーキテクトが教える、現場で活きる実装の急所
上記のコードを実務に投入する際、さらに安定性を高めるための「プロの知見」を共有しよう。
① `Application.ScreenUpdating = False` の重要性
AutoCAD VBAにおいて、図面を開閉するたびにグラフィックウィンドウが再描画されると、処理速度が何倍にも低下するだけでなく、OSのウィンドウマネージャーに負荷がかかる。処理の冒頭で画面描画を切り、終了時に確実に戻す(エラー時も含む)ことが、高速化の絶対条件だ。
② 仮想プリンタ名(`.pc3`)の環境依存問題
コード内で指定している `PublishToWeb DWFx.pc3` は標準でインストールされているものだが、PCの環境や管理者設定、あるいは過去のバージョンからの移行環境によっては、名前が異なったりファイルが存在しない場合がある。
厳密なプロダクション環境では、`layout.GetPlotDeviceNames` メソッド等を事前に走査し、システムに存在するドライバ名動的にマッピングする防御的コードを入れるのがベストプラクティスだ。
③ メモリ管理と `Documents.Open` の罠
VBAから `Documents.Open` で開いたドキュメントは、明示的に `doc.Close False` を呼ばない限りメモリ上に常駐し続け、数五十ファイル処理した時点でAutoCADごとクラッシュする。
必ず `On Error Resume Next` を挟んだクローズ処理を担保し、COMオブジェクトの参照(`doc`, `plotObj`, `fso`)をループの都度 `Nothing` にリセットする習慣をつけよ。
—
総括
AutoCAD VBAによるDWF/DWFxエクスポートの自動化は、単なる省力化ツールを超えて、「図面資産の軽量化パイプライン」を構築するための強力な武器となる。
今回提供したアーキテクチャとコードをベースに実装すれば、ヒューマンエラーを完全に排除した高速かつ堅牢なバッチ処理システムが手に入るはずだ。
プロフェッショナルとして、コードの裏にある「メモリとプロットエンジンの挙動」までを完全に掌握し、開発現場の生産性を圧倒的に引き上げてほしい。
