【入門編】【上級】AcadDocument.Databaseの「IsErased」プロパティを走査し、メモリ上のゴミデータを特定 – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは!AutoCAD VBAの世界へようこそ。
マクロの記録から一歩抜け出し、「本物の自動化と図面制御」をマスターしたいあなたへ、今日はとてもディープで、しかし現場でめちゃくちゃ役立つ「オブジェクトのライフサイクルとメモリ管理」のお話をします。

ここをクリアすれば、あなたのVBAスキルは「ただ動くマクロ」から「プロフェッショナルな図面診断ツール」へと大きく飛躍しますよ。肩の力を抜いて、一緒に知的探求の旅に出かけましょう!

1. なぜ「削除したはずのデータ」がメモリに残るのか?

AutoCADで図面を描いているとき、不要な線や文字を「削除(ERASE)」コマンドで消しますよね。画面上からは綺麗さっぱり消えるので、「これでメモリからも消えたな」と思っていませんか?

実はこれ、大きな誤解です。

AutoCADの内部(Database)では、オブジェクトが削除されると、即座にメモリから完全消去されるわけではありません。オブジェクトの `IsErased` というプロパティが `True` に書き換わり、「削除フラグが立った状態」でメモリの片隅に残り続けます。

なぜこんな仕様になっているかというと、AutoCADには強力な「U(Undo)コマンド」があるからです。「あ、やっぱり今の消したくない!」となった時、すぐに復活させるためには、メモリ上にデータが残っていなければ困りますよね。

しかし、これが図面の肥大化(ゴーストデータ)や、予期せぬエラー・破損の原因になることがあります。特に、何世代にもわたって編集を繰り返された図面には、この「ゴミデータ」が山のように眠っているのです。

2. Databaseオブジェクトと「IsErased」の正体

AutoCAD VBAの頂点に君臨するのが `AcadDocument` です。そして、そのDocumentが抱えるすべての図形や画層、ブロック定義などの「全宇宙」を統括しているのが `Database` オブジェクトです。

通常、私たちは `ActiveDocument.ModelSpace` などを通して図形を触りますが、これだと「画面に見えている(またはアクティブな空間にある)もの」しか見えていません。

しかし、`Database` の中を直接、総なめで走査(スキャン)するとどうなるか?
普段はアクセスできない、ブロック定義の内部や、ペーパー空間の裏側、そして「削除フラグが立ったまま浮遊しているゾンビデータ(IsErased = True)」までもが、すべて網羅的に網にかかるのです。

3. 【実践】メモリ上のゴミデータを特定するVBAコード

百聞は一見にしかず。実際に、現在開いている図面のDatabaseを深部まで潜り込み、`IsErased = True` となっているゾンビオブジェクトを暴き出すコードを書いてみましょう。

以下のコードを、AutoCADのVBAエディタ(Alt + F11)の標準モジュールに貼り付けて実行してみてください。

Sub FindErasedObjects()
Dim acadDoc As AcadDocument
Dim acadDb As AcadDatabase
Dim ent As AcadEntity
Dim erasedCount As Long

‘ 1. 現在アクティブなドキュメントとデータベースを取得
Set acadDoc = ThisDrawing
Set acadDb = acadDoc.Database

erasedCount = 0

‘ 2. データベース内の全エンティティを走査
‘ 注: Databaseオブジェクトを直接ループすることはできないため、
‘ 各ブロックテーブルレコード等を巡回するアプローチの基本形となります。
‘ 今回はシンプルに ModelSpace と PaperSpace、および全ブロックを走査する例を示します。

MsgBox “図面データベースのディープスキャンを開始します…”, vbInformation, “診断開始”

‘ モデル空間の走査
Call ScanBlock(acadDb.ModelSpace, erasedCount)

‘ ペーパー空間の走査
Call ScanBlock(acadDb.PaperSpace, erasedCount)

‘ 3. 結果の報告
If erasedCount > 0 Then
MsgBox “警告: メモリ上に ” & erasedCount & ” 個の削除済みゴミデータ(IsErased = True)が検出されました!”, vbExclamation, “診断結果”
Else
MsgBox “素晴らしい!メモリ上のゴミデータは検出されませんでした。”, vbInformation, “診断結果”
End If

End Sub

‘ 再帰的にブロックや空間内を走査するサブルーチン
Private Sub ScanBlock(ByRef targetBlock As AcadBlock, ByRef erasedCount As Long)
Dim ent As AcadEntity

‘ データベースの奥底では、IsErasedがTrueのものも含めてイテレートする必要があります
‘ 通常のFor Eachではスキップされることがあるため、明示的にチェックします
For Each ent In targetBlock
On Error Resume Next
If ent.IsErased Then
erasedCount = erasedCount + 1
‘ デバッグウィンドウにオブジェクトの種類とハンドルを出力
Debug.Print “発見されたゴミ -> タイプ: ” & ent.ObjectName & ” / ハンドル: ” & ent.Handle
End If
On Error GoTo 0
Next ent

End Sub

コードのここがポイント!

  • `ThisDrawing.Database`: 画面の表側だけでなく、裏側のデータ構造(Database)に直接アクセスしています。
  • `ent.IsErased`: これこそが今回の主役です。このプロパティが `True` を返すオブジェクトこそが、メモリを圧迫し、図面を重くしている原因のゾンビデータです。
  • `ent.Handle`: AutoCAD内でオブジェクトを一意に特定するIDです。どの図形がゴミになっているのかをイミディエイトウインドウ(Ctrl + G)で確認できます。

4. 現場で陥りやすいエラーと先輩からのアドバイス

このコードを試すにあたり、初学者が必ずハマる「罠」がいくつかあります。プロの現場で泥を食ってきた私から、先回りしてアドバイスしておきますね。

罠その1:「あれ? `IsErased = True` のオブジェクトが取得できない?」

通常の `For Each` ループでは、AutoCADが親切心(?)から最初から削除済みオブジェクトを隠してしまうことがあります。真にデータベースの深部を暴くには、オブジェクトID(ObjectId)の配列を直接舐めるような、より低レベルなアプローチが必要になるケースもあります。今回のコードは基礎編としての入門ステップですが、これだけでも十分に「裏側の世界」を垣間見ることができます。

罠その2:パージ(PURGE)との違い

「じゃあ、このゴミを完全に消すにはどうすればいいの?」と思いますよね。
実は、`IsErased = True` になったオブジェクトのメモリを完全に解放し、図面を綺麗さっぱり軽量化する最も確実な方法は、VBAでゴリゴリコードを書くことではなく、AutoCAD標準の `PURGE`(名前削除)コマンド を実行するか、図面を一度 `SAVEAS`(名前を付けて保存) することです。
ファイル保存の瞬間、AutoCADのデータベースはガベージコレクション(お掃除)を行界し、`IsErased = True` のデータを物理的にメモリから消し去ります。

まとめ:AutoCADの「裏側」を支配しよう

今回は、`AcadDocument.Database` と `IsErased` プロパティを切り口に、メモリ上のゴミデータを特定するというディープなテーマを解説しました。

  • 画面から消えた=メモリから消えた、ではない。
  • `IsErased` プロパティを監視することで、図面の健康状態(ゴミの蓄積度)を診断できる。
  • データベースの構造を意識すると、AutoCAD VBAの視界が一気に広がる。

「ただ図形を動かすだけのマクロ」から、「図面の構造を理解し、トラブルを未然に防ぐエンジニア」へ。
ここをクリアしたあなたなら、もう次のステップへ進む実力は十分です。ぜひご自身の図面でも試して、イミディエイトウインドウを覗いてみてくださいね。

それでは、次回の高度な自動化の世界でお会いしましょう。お疲れ様でした!

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