AutoCAD VBAの「ゴーストプロセス」を葬り去れ!確実に終了処理を行う堅牢なコード術
こんにちは。AutoCADの自動化の深淵へようこそ。
皆さんはマクロを作成していて、こんな経験はありませんか?
「コードを実行してエラーで止まった後、タスクマネージャーを見ると、裏でAutoCADがひっそりと生き残っている……」
これがいわゆる「ゴーストプロセス」です。これを放置するとメモリが食いつぶされ、PCは重くなり、最悪の場合は図面ファイルがロックされて開けなくなる。まさに「現場の災厄」です。
今日は、VBAの標準機能だけを使って、どんなエラーが起きても確実にAutoCADをクリーンアップする「守護神」のようなコード構造を伝授します。
—
1. なぜ「ゴースト」は生まれるのか?
VBAで外部からAutoCADを操作する場合、`CreateObject`や`GetObject`で`AcadApplication`を呼び出しますよね。
この時、AutoCADは「親(VBA)が生きている限り、自分も生き続けなければならない」と判断します。
問題は、プログラムがエラーで停止したときです。
通常のエラーハンドリングが不十分だと、終了処理のコード(`Quit`メソッドなど)が実行されず、AutoCADは「いつか親が命令をくれるはずだ」と期待して、メモリの中で永遠に待ち続けてしまうのです。これがゴーストの正体です。
—
2. 究極の「クリーンアップ・テンプレート」
VBAにはJavaやC#のような`Try-Catch-Finally`構文はありません。しかし、`On Error GoTo`を駆使すれば、「何があっても最後に必ず実行される終了処理ブロック」を擬似的に作ることができます。
以下のコードをコピーして、あなたのプロジェクトの雛形にしてください。
Sub RobustAutoCADAutomation()
Dim acadApp As Object
Dim acadDoc As Object
Dim isAppStarted As Boolean ‘ 自分が起動したかどうかを判定するフラグ
‘ — エラーハンドラをセット —
On Error GoTo ErrorHandler
‘ 1. AutoCADの起動または接続
On Error Resume Next
Set acadApp = GetObject(, “AutoCAD.Application”)
If acadApp Is Nothing Then
Set acadApp = CreateObject(“AutoCAD.Application”)
isAppStarted = True ‘ ここで起動した場合はフラグを立てる
End If
On Error GoTo ErrorHandler ‘ エラーハンドラを復旧
acadApp.Visible = True
‘ — ここにメイン処理を記述 —
‘ 例: Set acadDoc = acadApp.Documents.Add
‘ Debug.Print “処理実行中…”
‘ Err.Raise 1001 ‘ あえてエラーを起こしてテストしてみよう
‘ — 正常終了処理 —
GoTo Cleanup
ErrorHandler:
MsgBox “エラー発生: ” & Err.Description, vbCritical
Cleanup:
‘ — 【重要】ここが「守護神」のエリア —
‘ もしAutoCADが起動しており、かつ自分が起動させた場合のみ終了させる
If Not acadApp Is Nothing Then
If isAppStarted Then
‘ プロセスを確実に解放するためにQuitを呼び出す
acadApp.Quit
End If
‘ オブジェクトのメモリ解放
Set acadDoc = Nothing
Set acadApp = Nothing
End If
MsgBox “クリーンアップ完了。メモリは解放されました。”
End Sub
—
3. このコードの「極意」を解説します
① `isAppStarted` フラグの重要性
最もやってはいけないミスは、「自分が起動していないAutoCADまで勝手に終了させてしまうこと」です。ユーザーが手動で開いている図面を強制終了させたら怒られてしまいますよね。「自分が生んだ子(プロセス)だけを、責任を持って片付ける」。これがエンジニアの流儀です。
② `GoTo Cleanup` による強制遷移
`On Error`でエラーをキャッチした後、処理を中断するのではなく、必ず`Cleanup`ラベルへ飛ばすことで、途中で何が起きても終了処理が走る仕組みを作っています。これがVBAにおける`Finally`相当の挙動です。
③ 最後に `Nothing` をセットする
VBAのメモリ管理は優秀ですが、明示的に`Set acadApp = Nothing`と書く癖をつけてください。これにより、オブジェクトの参照カウントがゼロになり、ガベージコレクションが確実に実行されます。
—
最後に:先輩からのアドバイス
「マクロが止まったらタスクマネージャーで消せばいいや」と考えているうちは、まだ初心者です。
プロフェッショナルな現場では、「エラーは起こるもの」という前提でコードを書くことが求められます。
今回のテンプレートを使えば、あなたの書くプログラムは驚くほど安定し、他の方に配布しても「勝手にPCが重くなる」といったクレームは激減するはずです。
さあ、この「守護神」をあなたのツールボックスに組み込んで、一段上の自動化エンジニアを目指しましょう!何か分からないことがあれば、いつでも聞いてくださいね。
