【実務・中級編】【上級プロフェッショナル向け】大量図面処理時の「AcadApplication」インスタンス再起動によるメモリリフレッシュ – AutoCAD VBA解析バイブル

スポンサーリンク

【AutoCAD VBA】数千枚の図面処理でメモリリークを根絶する「プロセス再起動」戦略

AutoCAD VBAで数千枚規模の図面を一括処理しようとした際、多くのエンジニアが直面する壁がある。「最初は快調だったのに、数時間経つと処理速度が落ち、最終的にAutoCADがフリーズ、あるいはメモリ不足でクラッシュする」という現象だ。

残念ながら、AutoCADのCOMインターフェースは、長時間の連続処理において「メモリのクリーンアップ」を完璧には行わない。特に`Open`と`Close`を繰り返すループ構造では、たとえ`Set doc = Nothing`を明示しても、GDIオブジェクトやCOMプロキシの断片が蓄積し、いずれシステムは飽和する。

本記事では、この「メモリリークの宿命」をアーキテクチャレベルで解決する、AutoCADプロセス再起動による安定化手法を伝授する。

—

なぜ「再起動」が必要なのか:VBAの限界とCOMの闇

VBA単体で完結させようとするのは、大規模処理においては「設計ミス」に近い。AutoCADのCOMオブジェクトは、プロセスが継続する限りメモリを確保し続ける傾向がある。

この問題を解決する唯一無二の解法は、「処理をバッチ化し、一定数ごとにAutoCADプロセス自体をキルして再起動する」ことだ。これを実現するには、VBA単体ではなく、「制御用コントローラー(VBScript または PowerShell)」を上位層に配置する必要がある。

—

堅牢な設計:3層構造によるプロセス制御

設計のキモは「処理を中断しても、どこまで終わったかを保持する」ことだ。

1. 管理層(PowerShell): インスタンスを起動し、処理件数を監視。限界に達したら終了させ、再起動をトリガーする。
2. 実行層(AutoCAD VBA): 単一の図面処理に特化。完了後にフラグファイルを生成し、終了する。
3. 状態保存層(CSV/JSON): 未処理リストと処理済みリストを管理し、再起動後も直前の状態から復帰する。

—

実装:安定稼働のためのプロダクションコード

1. 管理用コントローラー(PowerShell: `Runner.ps1`)

このスクリプトが「親」となり、AutoCADを管理します。

50枚ごとに再起動する設定
$batchSize = 50
$targetFiles = Get-ChildItem “C:\TargetDrawings\.dwg”

for ($i = 0; $i -lt $targetFiles.Count; $i += $batchSize) {
# 処理対象のサブセットを取得
$currentBatch = $targetFiles | Select-Object -Skip $i -First $batchSize

# ここでAutoCADを起動し、処理をキックする
$acad = New-Object -ComObject AutoCAD.Application
$acad.Visible = $true
$doc = $acad.Documents.Open($targetFiles[0].FullName) # 最初のファイルでVBAを呼ぶ

# 本来はここでVBAをRunさせる(例: $acad.RunMacro(“ProcessDrawings”))
# 処理終了を待機し、一定時間後にプロセスをキルする
Stop-Process -Name “acad” -Force
}

2. 実行用VBA(AutoCAD内部)

処理の終了後、確実にAutoCADを終了させる設計にします。

‘ 処理終了後にAutoCADを確実に解放するロジック
Public Sub ProcessAndQuit()
On Error GoTo ErrorHandler

‘ 1. 図面処理を実行
‘ Call ExecuteBusinessLogic

‘ 2. 保存して閉じる
ThisDrawing.Save
ThisDrawing.Close SaveChanges:=False

‘ 3. AutoCADプロセスを終了(これが再起動のトリガーになる)
Application.Quit
Exit Sub

ErrorHandler:
‘ 異常終了時もログを残して終了
LogError Err.Description
Application.Quit
End Sub

—

現場で陥る「地雷」への注意点

1. 「Application.Quit」の罠:
`Application.Quit`を呼ぶ際、図面が「保存されていない状態」でダイアログが出ると処理が停止する。必ず`Close`メソッドで状態を確定させてから`Quit`を呼ぶこと。
2. COMオブジェクトの解放:
`ThisDrawing`や`AcadApplication`を変数に代入しすぎないこと。ループ内で`Set doc = …`を繰り返すなら、ループの最後で必ず`Set doc = Nothing`を実行する。これだけで開放されるメモリ量は劇的に変わる。
3. データベース(Excel/SQL)のロック:
プロセスを再起動する場合、データベースへの接続は「都度接続・切断」を徹底する。再起動のタイミングで接続がタイムアウトし、孤児プロセスとしてロックが残る事故を防ぐためだ。

アーキテクトからの助言

「自動化」の本質は、プログラムを書くことではなく、「いかにシステムを止まらせないか」にある。

VBAだけで解決しようとして泥沼にはまるエンジニアを多く見てきた。しかし、プロセス制御を上位層(OSレベル)に委譲するこのアーキテクチャを採用すれば、数千枚の図面処理はただの「待機時間」になる。

コードは「動く」だけでなく、「メンテナンス可能」でなければならない。今回提示した構造は、ファイルパスのリストをCSVから読み込むように改修するだけで、どんなプロジェクトにも適合するはずだ。自信を持って実装を進めてほしい。

タイトルとURLをコピーしました