AutoCAD VBAの限界を超えろ:数千図面を完遂するための「プロセス再起動」戦略
AutoCAD VBAで数千枚規模の図面を一括処理しようとしたとき、必ず遭遇する壁がある。それが「メモリリーク」と「オブジェクトの断片化」だ。
たとえ `Set doc = Nothing` を呼び出し、`ThisDrawing.Close` を実行したとしても、AutoCADのプロセスは確実に疲弊する。VBAのガベージコレクションは非力であり、COMオブジェクトのラッパーが保持するメモリは、処理が長引くほど肥大化し、やがて「致命的なエラー」という名の悪夢を招く。
本稿では、レガシーなAutoCAD環境を極限まで使い倒すための、「プロセス再起動による完全リフレッシュ手法」を伝授する。
—
1. なぜ「プロセス再起動」が唯一の解なのか
AutoCAD(`AcadApplication`)は、長時間のセッションにおいて内部キャッシュを完全に解放しない。特に`ObjectARX`や外部DLLを多用する環境では、スタックの断片化は避けられない。
多くの技術者が「図面を閉じて開く」だけのループで戦おうとするが、これは無益だ。数時間後、メモリ使用率は右肩上がりとなり、COMスタックは限界を迎える。真のエンジニアは、「処理の完了」ではなく「プロセスの生存時間」を管理する。
一定の閾値(例えば図面50枚ごと)でプロセスをシャットダウンし、Windowsのプロセス管理を通じて再起動させる。これが、安定稼働のための唯一のアーキテクチャだ。
—
2. 実装の極意:タスク管理と外部制御
VBA単体で自分自身を再起動するのはリスクが高い。制御用スクリプト(VBScriptまたはC#の外部ランナー)を介して、AutoCADプロセスのライフサイクルを外側から管理するのが定石である。
アーキテクチャの概要
1. 制御用コントローラー(外部): 現在の処理図面番号をテキストファイルやレジストリに保持。
2. AutoCAD VBA: 処理が終わるたびにAutoCADを終了し、コントローラーに制御を戻す。
3. コントローラー: AutoCADが終了したことを検知し、再度AutoCADを起動して処理を継続する。
—
3. 実践コード:プロセスを完全に解放する終了処理
単なる `Quit` では不十分だ。COMオブジェクトを徹底的にパージする意識を持て。
‘ AutoCAD VBA内の終了処理モジュール
Public Sub ForceShutdownAndRestart()
Dim acadApp As AcadApplication
Set acadApp = ThisDrawing.Application
‘ 1. 現在の図面を明示的に保存し閉じる
If ThisDrawing.Saved = False Then ThisDrawing.Save
ThisDrawing.Close False
‘ 2. オブジェクトの明示的解放(VBAにおいては気休めだが、儀式として必須)
Set acadApp = Nothing
‘ 3. Windows APIを使用してプロセスを強制終了させる(念のため)
‘ 内部からの Quit では解放されないメモリ領域があるため
Shell “taskkill /F /IM acad.exe”, vbHide
End Sub
—
4. プロセス再起動を制御するシェル(VBScript例)
外部からAutoCADのインスタンスを制御するコントローラーの原型だ。これを実行することで、プロセスが死んでも処理が継続される堅牢なパイプラインが完成する。
‘ ControlApp.vbs
‘ メイン処理ループ:図面処理完了フラグを確認し、AutoCADを再起動し続ける
Dim acadApp, doc, i
Dim maxDrawingsPerSession : maxDrawingsPerSession = 50
For i = 1 To 1000 ‘ 全図面数
Set acadApp = CreateObject(“AutoCAD.Application”)
acadApp.Visible = True
‘ ここで処理対象の図面を開き、VBAのメインメソッドを呼び出す
Set doc = acadApp.Documents.Open(“C:\TargetDir\Drawing_” & i & “.dwg”)
‘ VBA側の処理完了を待機するロジック(またはVBA内で終了トリガーを引く)
‘ …処理…
‘ 一定枚数に達したらプロセスをリフレッシュ
If i Mod maxDrawingsPerSession = 0 Then
acadApp.Quit
Set acadApp = Nothing
WScript.Sleep 5000 ‘ プロセス解放待ちのバッファ
End If
Next
—
5. 伝説のエンジニアへのアドバイス:安定化の要諦
- 図面データベース(AcDbDatabase)の扱い:
可能な限り `ObjectARX` や `.NET API` を活用し、`Database` オブジェクトを直接操作せよ。VBAの `AcadDocument` はオーバーヘッドが大きすぎる。
- Windows APIの活用:
`GetWindowThreadProcessId` を使い、現在操作している `AcadApplication` がどのプロセスIDに紐付いているかを常に監視せよ。予期せぬフリーズ時には、このPIDを叩き切るのがプロの作法だ。
- メモリの可視化:
`Performance Monitor` を使い、`Working Set` の推移をログに取れ。`Quit` 後のメモリ減少が確認できない場合、それは貴方のコードがどこかでオブジェクトを参照し続けている証拠だ。
AutoCAD VBAはレガシーだが、その設計の根底にあるCOMの構造を理解すれば、最新のツール以上に強力な自動化武器になる。泥臭い再起動ループこそが、巨大な図面管理システムを止めないための、唯一にして最強の防壁であることを忘れないでほしい。
技術に妥協するな。図面が死ぬか、プロセスが死ぬか。選ぶのは貴方だ。
