【入門編】【上級プロフェッショナル向け】図面オープン時のリソース管理:メモリリークを防ぐ高度なオブジェクト操作 – AutoCAD VBA解析バイブル

スポンサーリンク

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という大きな存在と、どうやって対話(参照)し、どうやって別れるか」という距離感を掴むことです。

今回紹介した「後始末」の習慣は、どんなに高度なツールを作るときでも一生使える基本技術です。最初は面倒に感じるかもしれませんが、これを体に染み込ませれば、あなたの書くマクロは「止まらない、落ちない、爆速のツール」へと進化します。

ここをクリアしたあなたは、もう初心者ではありません。自信を持って、次の自動化の領域へ進んでください!

何か不明点があれば、いつでも聞いてくださいね。応援しています。

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