AutoCAD VBAの「ゴースト」を葬る:AcadApplicationを確実に飼いならすための技術的極意
AutoCADのオートメーションにおいて、最も醜悪なバグは「バックグラウンドに生き残るAcad.exe」だ。エラーが発生するたび、タスクマネージャーに蓄積されるゴーストプロセス。これらはメモリを食いつぶすだけでなく、後続のプロセスをロックし、システム全体の整合性を破壊する。
本稿では、VBAという制約の多い環境下で、いかにして「堅牢な終了処理」を実現するか、そのアーキテクチャの真髄を解説する。
—
1. なぜ「Quitメソッド」だけでは不十分なのか
多くの初学者は `AcadApp.Quit` を呼べば終了すると信じている。しかし、VBAのランタイムはオブジェクトの参照カウントがゼロにならない限り、プロセスを解放しない。
- 循環参照の罠: `ThisDrawing` をグローバル変数に格納し、解放を怠れば参照カウントは落ちない。
- イベントハンドラの残留: `WithEvents` で定義したオブジェクトの接続を解除しない限り、メモリ上に残骸が居座る。
- モーダルダイアログの干渉: プロセスが終了処理中にダイアログを待機し、デッドロックに陥るケース。
これらを防ぐには、「オブジェクトのスコープ管理」と「例外処理の強制力」を両立させる必要がある。
—
2. 究極の「Try-Finally」パターン実装
VBAには本来 `Try-Catch-Finally` は存在しない。しかし、ラベルジャンプを駆使することで、擬似的に「確実な後始末(Finally)」を実装できる。以下は、私が長年現場で採用しているテンプレートだ。
Public Sub MasterProcess()
Dim acadApp As Object
Dim acadDoc As Object
‘ 1. エラーハンドラの設定
On Error GoTo ErrorHandler
‘ 2. オブジェクトのインスタンス化
Set acadApp = CreateObject(“AutoCAD.Application”)
acadApp.Visible = True
Set acadDoc = acadApp.Documents.Add
‘ — メイン処理 —
‘ ここに核心となる業務ロジックを記述
‘ ——————
CleanExit:
‘ 3. 確実なクリーンアップ(Finallyブロックに相当)
On Error Resume Next ‘ 解放中のエラーは無視して進行させる
If Not acadDoc Is Nothing Then acadDoc.Close False: Set acadDoc = Nothing
If Not acadApp Is Nothing Then acadApp.Quit: Set acadApp = Nothing
Exit Sub
ErrorHandler:
‘ 4. エラーログ出力や管理
Debug.Print “Critical Error: ” & Err.Description
Resume CleanExit
End Sub
このコードの「極意」
- `On Error Resume Next` の局所適用: クリーンアップ処理そのものが失敗した場合、無限ループや予期せぬ中断を防ぐために必須である。
- `Set Nothing` の徹底: VBAのガベージコレクションは参照カウント方式だ。明示的に `Nothing` を代入することで、即座にオブジェクトを開放する。
—
3. Windows APIによるプロセスの強制終了(最終手段)
上記で解決しない場合、あるいは「既にゾンビ化したプロセス」を叩き斬る必要がある場合は、Win32 APIを直接叩く。これは「外科手術」に等しい。
If VBA7 Then
Private Declare PtrSafe Function TerminateProcess Lib “kernel32” (ByVal hProcess As LongPtr, ByVal uExitCode As Long) As Long
Else
Private Declare Function TerminateProcess Lib “kernel32” (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
End If
‘ ※注意: この処理はプロセスを即座に殺すため、データの保存は期待できない。
‘ 正常終了が失敗した際の最終手段としてのみ使用すること。
—
4. チーフアーキテクトからの助言:アーキテクチャの視点
ゴーストプロセスを発生させないための設計指針を3つ提示する。
1. 「Document」と「Application」の生存期間を分離せよ:
AutoCADのDocumentオブジェクトを長時間保持し続けると、AutoCAD自体の安定性が著しく低下する。処理単位ごとに `CreateObject` し、終われば即座に `Quit` する「使い捨てアーキテクチャ」が、大規模環境では最も安定する。
2. イベントハンドラを過信しない:
`WithEvents` は強力だが、オブジェクトの開放を著しく困難にする。複雑なイベントが必要な場合を除き、可能な限り「ポーリング(状態監視)」ベースの処理へ切り替えるべきだ。
3. シリアル化を検討せよ:
もし貴方のシステムが「一度に多数のAutoCADを起動して処理している」のであれば、それは設計の敗北に近い。キューイングシステムを導入し、AutoCADのプロセス数を制限するゲートウェイを構築せよ。
結びに代えて
AutoCADのオートメーションは、一見すると枯れた技術のように見える。しかし、その裏側にあるメモリ管理とプロセスライフサイクルの制御は、エンジニアの習熟度がそのまま「システムの可用性」に直結する。
コードを書くとき、常に「エラーが発生した瞬間の自分」を想像せよ。その時、あなたの書いたコードは、後始末をして静かに立ち去る準備ができているか? それこそが、プロフェッショナルのコードだ。
