【AutoCAD VBA 掌握術】大量図面処理の「死の淵」を回避せよ:AcadApplication再起動タイマーの極限設計
設計現場の自動化における「真の壁」は、1枚の図面を美しく処理することではない。数千枚の図面を、一人の人間も介在させずに、数時間、数日間、安定して処理し続けることにある。
並のプログラマーは、`For Each dwgFile In files` というループを書き、数百枚目で「オートメーションエラー」あるいは「メモリ不足」のダイアログと共に沈む。AutoCADという巨大なCADエンジンは、COMインターフェースを介した操作において、どれほど丁寧にオブジェクトを `Set … = Nothing` したとしても、内部的なUndoバッファやリソースの断片化(メモリリーク)からは逃れられない宿命にあるからだ。
本稿では、数千枚規模のバッチ処理を完遂させるために不可欠な、「AutoCADインスタンスのライフサイクル・マネジメント」、すなわち一定枚数ごとにCADそのものを再起動させるプロフェッショナルな設計思想を伝授する。
—
1. なぜ「閉じてもメモリは解放されない」のか
AutoCAD VBA(およびCOM API)を使用している際、`Document.Close` を呼べば図面は閉じられる。しかし、AutoCADが内部で確保したヒープ領域や、外部参照、フォントキャッシュ、そして何より「Undo(元に戻す)」のための履歴スタックは、アプリケーションを終了させるまで完全にリセットされないことが多い。
これを放置すれば、処理速度は指数関数的に低下し、最終的にはWindowsのハンドル数制限やメモリ空間の限界に達してプロセスがハングアップする。
敗者の設計
- 一つの `AcadApplication` インスタンスで全図面を回そうとする。
- エラーが起きてから対処しようとする。
勝者の設計(プロフェッショナル・スタイル)
- 「AutoCADはいつか必ず壊れる」という前提で組む。
- 例えば「50枚処理するごとに、AutoCADを一度完全に終了(Quit)し、新たなプロセスを立ち上げる」という再起動タイマー(カウンター)を実装する。
—
2. 堅牢なアーキテクチャ:コントローラー・パターン
大量処理を行う際、コードを「処理される側(AutoCAD内)」に置いてはいけない。制御主体は Excel VBA または 独立したVB.NET/VBScript であるべきだ。
外部のコントローラーからAutoCADを「操り人形」として制御することで、AutoCADがクラッシュしてもコントローラー側は生き残り、次の図面から処理を再開できる。
設計のポイント
1. 外部DB・リストとの連携: どの図面まで終わったかを、常に外部ファイル(CSVやログ)に書き出す。
2. 強制終了の猶予: `Quit` メソッドが効かない場合に備え、プロセスID(PID)を監視し、必要なら `TaskKill` する。
3. レジューム機能: 途中で止まっても、再実行時に「未処理の図面」から自動スタートする。
—
3. 実践:プロダクション・グレードの再起動コード
以下のコードは、Excel VBAからAutoCADを制御する「コントローラー」のテンプレートだ。実務でそのまま使えるよう、エラーハンドリングと再起動ロジックを組み込んでいる。
‘ — Excel VBA 側の標準モジュールに配置 —
Option Explicit
Private Const RESTART_INTERVAL As Integer = 50 ‘ 50枚ごとにAutoCADを再起動
Private Const ACAD_PROGID As String = “AutoCAD.Application.24” ‘ 2021/2022等のバージョンに合わせる
Sub MassDrawingProcessor()
Dim dwgList As Variant
Dim i As Long
Dim acadApp As Object
Dim processedCount As Integer
Dim targetDwg As String
‘ 1. 処理対象のリストを取得 (A列にパスが入っている想定)
dwgList = Range(“A1:A” & Cells(Rows.Count, 1).End(xlUp).Row).Value
Set acadApp = StartNewAutoCAD()
processedCount = 0
On Error GoTo ErrorHandler
For i = 1 To UBound(dwgList)
targetDwg = dwgList(i, 1)
‘ — 再起動ロジック —
If processedCount >= RESTART_INTERVAL Then
Debug.Print “リソースクリーンアップのためAutoCADを再起動します…”
CloseAutoCAD acadApp
Set acadApp = StartNewAutoCAD()
processedCount = 0
End If
‘ — 個別の図面処理 —
ProcessIndividualDrawing acadApp, targetDwg
‘ 処理成功の記録
processedCount = processedCount + 1
Cells(i, 2).Value = “完了: ” & Now()
Next i
MsgBox “全処理が完了しました。”, vbInformation
GoTo Finalize
ErrorHandler:
Debug.Print “エラー発生 (” & targetDwg & “): ” & Err.Description
‘ エラーが起きたらCADを捨てて再起動し、次へ進む執念が必要
CloseAutoCAD acadApp
Set acadApp = StartNewAutoCAD()
Resume Next
Finalize:
CloseAutoCAD acadApp
End Sub
‘ AutoCADのクリーンな起動
Private Function StartNewAutoCAD() As Object
Dim app As Object
On Error Resume Next
Set app = CreateObject(ACAD_PROGID)
If app Is Nothing Then
MsgBox “AutoCADの起動に失敗しました。”, vbCritical
End
End If
app.Visible = True ‘ デバッグ時はTrue、本番はFalseでも可
Set StartNewAutoCAD = app
End Function
‘ AutoCADの安全な終了
Private Sub CloseAutoCAD(ByRef app As Object)
On Error Resume Next
If Not app Is Nothing Then
app.Quit
Set app = Nothing
End If
‘ COMの解放を確実にするための待機
DoEvents
Sleep 3000 ‘ API等で3秒ほど待つ(後述)
End Sub
‘ — 個別のロジック (ここを業務に合わせて書き換える) —
Private Sub ProcessIndividualDrawing(ByRef acadApp As Object, ByVal dwgPath As String)
Dim doc As Object
Set doc = acadApp.Documents.Open(dwgPath)
‘ ここにズーム、パージ、プロパティ変更、PDF出力などのロジックを記述
‘ 例: doc.SendCommand “_ZE ”
doc.Close SaveChanges:=True
End Sub
—
4. 現場での運用を左右する「プラスアルファ」の知見
ゾンビプロセスの撲滅
`app.Quit` を呼んでも、バックグラウンドで `acad.exe` が居座り続けるケースがある。これを「ゾンビプロセス」と呼ぶ。大量処理においてゾンビが増殖すると、メモリを食いつぶすだけでなく、ファイルロックの原因にもなる。
本気で堅牢性を求めるなら、`CloseAutoCAD` 内で `WMI (Windows Management Instrumentation)` を使い、自身の制御下にある `acad.exe` が消えたかを確認し、残っていれば `Terminate` する処理を加えるべきだ。
データベース連携の黄金律
各図面の処理結果(成功・失敗・エラー内容)は、Excelのセルだけでなく、外部のログファイル(CSV)へ即座に書き出すことを強く推奨する。
万が一、Excel自体が落ちたとしても、「どの図面まで終わったか」というエビデンスが外部に残っていれば、復旧は容易だ。
「Sleep」の重要性
`CreateObject` や `Quit` の直後、VBAは次の行へ猛スピードで進もうとする。しかし、OSレベルではプロセスの生成・破棄には時間がかかる。
`Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)` を宣言し、再起動の合間に数秒の「呼吸」をさせるだけで、オートメーションエラーの発生率は劇的に下がる。
—
5. 結論:制御不能なものを制御する
AutoCAD VBAによる大量処理は、野生の猛獣を操るのに似ている。
「いつか暴走する」ことを前提に、檻(再起動タイマー)を作り、逃げ道(ログ出力)を確保し、常に監視下に置く。
今回紹介した「一定枚数でのインスタンス破棄」は、泥臭い手法に見えるかもしれない。しかし、これこそが数千枚の図面をエラーなしで完遂させる、現場で磨き上げられた「血の通った最適解」なのだ。
あなたのコードが、深夜のオフィスで誰の助けも借りず、静かに、そして確実に図面を捌き続けることを願っている。
