AutoCAD VBAの「呪い」を解く:図面オープン・セーブにおけるメモリ管理の極意
こんにちは。AutoCADの自動化の世界へようこそ。
マクロの記録から脱却し、独自のツールを開発し始めた皆さんが必ずぶつかる壁。それが「なぜか図面を繰り返すとAutoCADが重くなる、あるいはクラッシュする」という現象です。
これは皆さんのコードが悪いのではありません。AutoCADという巨大なエンジンの「メモリ管理の作法」をまだ知らないだけなのです。今日は、プロフェッショナルが図面のオープン・クローズで必ず行っている、「メモリリークを防ぐためのオブジェクト参照のライフサイクル管理」について、魂を込めて解説します。
—
1. なぜAutoCAD VBAでメモリリークが起きるのか?
AutoCAD VBAにおいて、`AcadDocument`や`AcadDatabase`といったオブジェクトは、皆さんが想像している以上に「重い」存在です。
特に図面を閉じる際、単に `Close` メソッドを呼ぶだけでは不十分なケースがあります。VBAの背後にあるCOM(Component Object Model)は、「誰かがこのオブジェクトをまだ参照しているかもしれない」と判断すると、メモリから完全に解放してくれません。
これを放置すると、図面を開閉するたびに使用メモリが肥大化し、最終的に「お約束の強制終了」が待っています。
—
2. 鉄則:オブジェクトは「使い捨て」ではなく「後始末」する
プロフェッショナルは、「開いたら必ず明示的に解放する」という儀式を欠かしません。これができていないコードは、時限爆弾を抱えているのと同じです。
メモリを食い荒らさないための「後始末」コード
まずは、図面を安全に開き、処理し、確実に閉じるためのテンプレートを見てください。
Sub SecureDocumentHandler()
Dim doc As AcadDocument
Dim targetPath As String
targetPath = “C:\Projects\Sample.dwg”
‘ 1. エラーハンドリングを必ず実装(異常終了時にメモリが残るのを防ぐ)
On Error GoTo ErrorHandler
‘ 2. 図面を開く
Set doc = Documents.Open(targetPath)
‘ — ここに図面に対する高度な処理を書く —
Debug.Print “処理中: ” & doc.Name
‘ ————————————-
‘ 3. 保存して閉じる(SaveAsまたはClose)
doc.Close True ‘ Trueは変更を保存する意
‘ 4. 超重要:オブジェクト参照を明示的に解放する
Set doc = Nothing
Exit Sub
ErrorHandler:
‘ 異常終了時もオブジェクトを解放する
If Not doc Is Nothing Then
doc.Close False ‘ 変更を保存せずに閉じる
Set doc = Nothing
End If
MsgBox “エラーが発生しました。メモリを解放して終了します。”
End Sub
なぜ `Set doc = Nothing` が必要なのか?
VBAの変数 `doc` は、図面オブジェクトそのものではなく、図面への「窓口(参照)」です。`Close` で図面を閉じても、変数 `doc` には「まだ図面があった場所」という情報が残っています。`Set doc = Nothing` を書くことで、「もうこの窓口は使いませんよ」とCOMに宣言し、メモリの回収(ガベージコレクション)を促すのです。
—
3. バージョン互換の罠:Openメソッドの隠された引数
図面を開く際、`Documents.Open` は単にパスを渡すだけでは危険です。特に過去のバージョンのDWGを開く際、AutoCADは内部で変換処理を行いますが、これがメモリやCPUに負荷をかけます。
以下のオプションを意識してみてください。
- ReadOnly引数: 閲覧のみなら `ReadOnly := True` に設定しましょう。編集権限をロックしないため、メモリの負荷が劇的に下がります。
- パスの管理: ネットワークドライブ上の図面を開く際は、一度ローカルにコピーしてから開くのが、不安定な動作を回避するエンジニアの常識です。
—
4. 陥りやすいエラー:ループ処理でのメモリリーク
最も恐ろしいのは、フォルダ内の全図面を処理するようなループ処理です。
‘ やってはいけない例
For i = 0 To 100
Set doc = Documents.Open(files(i))
‘ 処理…
‘ 閉じ忘れた!あるいはエラーでここを通らない!
Next
このようにループ内でオブジェクトを生成し、解放し忘れると、100枚の図面を開くたびに100個分の参照がメモリに残り続けます。
解決策:
1. 必ず `Do … Loop` や `For` の中で `On Error GoTo` を活用し、どのタイミングで失敗しても `Set doc = Nothing` が実行されるようにすること。
2. 重い処理を行う場合は、定期的に `DoEvents` を挟み、Windowsへ制御を戻してメモリの整理を促すこと。
—
最後に:先輩からのアドバイス
AutoCAD VBAをマスターするというのは、言語の文法を覚えることではありません。「AutoCADという大きな存在と、どうやって対話(参照)し、どうやって別れるか」という距離感を掴むことです。
今回紹介した「後始末」の習慣は、どんなに高度なツールを作るときでも一生使える基本技術です。最初は面倒に感じるかもしれませんが、これを体に染み込ませれば、あなたの書くマクロは「止まらない、落ちない、爆速のツール」へと進化します。
ここをクリアしたあなたは、もう初心者ではありません。自信を持って、次の自動化の領域へ進んでください!
何か不明点があれば、いつでも聞いてくださいね。応援しています。
