【入門編】【上級プロフェッショナル】AcadDocument.Databaseオブジェクトを直接操作し、Undo/Redoスタックを考慮したトランザクション的な処理を実装する – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは!AutoCADの自動化、日々の業務でガンガン活用していますか?

「マクロの記録」から一歩踏み出し、VBA(Visual Basic for Applications)で図面を自在に操れるようになると、仕事のスピードが何倍にも跳ね上がりますよね。

さて、今回はAutoCAD VBAの基礎からさらに一歩進んで、「プロのエンジニアが現場で必ず使っている、データベースへの直接アプローチとトランザクション制御」をテーマにお届けします。

「VBAで図形を描くなんて余裕だよ」という方でも、数百・数千のオブジェクトを一括処理する時に、こんな悩みにぶつかったことはありませんか?

  • 「処理の途中でエラー落ちしたら、図面が中途半端な状態で保存されてしまった…」
  • 「VBAで変更したあとに『元に戻す(Undo)』を実行したら、何回もCtrl+Zを押さないといけない(あるいは元に戻せない)」

ここをクリアできれば、あなたの書くVBAコードは「おもちゃのマクロ」から「現場の基幹システムを支える堅牢なプログラム」へと劇的に進化します。優しく、そして本質的なところまで丁寧に解説していきますね。ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ!

1. AutoCAD VBAの全体像:なぜ「Database」と「トランザクション」が重要なのか?

私たちが普段画面で見ているAutoCADの図面は、実は「AcadDocument」というオブジェクトの中に包まれています。

しかし、VBAで高度な処理や高速な一括処理を行いたい場合、画面の表示(ModelSpaceなど)をいちいちいじっていると、動作が非常に重くなります。なぜなら、AutoCADが「画面の再描画」や「イベントの監視」を裏で一生懸命やってしまうからです。

そこで登場するのが、`Database`オブジェクトです。
これは、図面の「心臓部(メモリ上のデータ置き場)」に直結しています。画面の描画を無視して、メモリ上でダイレクトに図形データを料理するための最強のパスポートだと思ってください。

そして「Undo/Redo(元に戻す/やり直し)」の壁

Databaseを直接いじると、恐ろしいことがあります。それは「VBAでの一連の変更が、AutoCADのUndoスタックでバラバラに記録されてしまう」という問題です。

例えば、1,個の図形の色を一括変更するプログラムを書いたとします。これを素朴に実行すると、ユーザーが「元に戻す(Ctrl+Z)」を押したときになんと1,回もCtrl+Zを連打しないと元の図面に戻らないという、ユーザー泣かせの悲惨な事態が起きます。

これを解決するのが、今回学ぶ「トランザクション的な処理(グループ化)」です。

2. 実践!データベース直結 & Undoグループ化のコード

百聞は一見に如かず。まずは、現場でそのまま使える実用的なコードを見てみましょう。
このコードは、現在の図面データベースに対して安全にアクセスし、複数の図形変更を「ひとまとまりの操作(1回のUndoで元に戻せる単位)」として安全に処理するテンプレートです。

Sub ProfessionalBatchProcess()
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing.Application.ActiveDocument

Dim acadDb As AcadDatabase
Set acadDb = acadDoc.Database

Dim transManager As AcadTransactionManager
Set transManager = acadDb.TransactionManager

Dim transId As Long

On Error GoTo ErrorHandler

‘ ==========================================
‘ 1. Undoのグループ開始(ここがプロの技!)
‘ ==========================================
‘ この記述により、この後の処理で行う複数の変更が
‘ ユーザーの「Ctrl+Z」1回で元に戻せるようになります。
acadDoc.StartUndoMark

‘ 2. トランザクションの開始(データベースへの安全な接続)
Set transId = transManager.StartTransaction

‘ ==========================================
‘ 3. 実際のデータ処理(例:モデル空間内の全円の色を赤にする)
‘ ==========================================
Dim ent As AcadEntity
Dim count As Long
count = 0

For Each ent In acadDb.ModelSpace
‘ オブジェクトが「円 (AcDbCircle)」かチェック
If TypeOf ent Is AcadCircle Then
‘ プロパティを変更
ent.Color = acRed
‘ 変更をトランザクションに通知
ent.Update
count = count + 1
End If
Next ent

‘ ==========================================
‘ 4. トランザクションのコミット(変更を確定)
‘ ==========================================
transManager.EndTransaction

‘ Undoのグループ終了
acadDoc.EndUndoMark

MsgBox count & “個の円を赤色に変更し、安全にトランザクションを完了しました。”, vbInformation, “プロフェッショナルVBA”
Exit Sub

ErrorHandler:
‘ ==========================================
‘ 5. エラー時のロールバック(安全装置)
‘ ==========================================
MsgBox “エラーが発生しました。処理を中断し、変更を破棄します。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “致命的なエラー”

‘ トランザクションを強制終了(無効化)
On Error Resume Next
transManager.AbortTransaction
acadDoc.EndUndoMark

‘ エラーをクリア
Err.Clear
End Sub

3. コードのキモを徹底解説!

上記のコードには、実務で絶対に外せない「3つの重要ポイント」が詰まっています。

① `acadDb.TransactionManager` による安全管理

従来の初学者向けコードでは、ModelSpace等のオブジェクトを直接ループしてガンガン書き換えていました。しかし、これだと「処理の途中でメモリ例外やCADのフリーズが起きたとき」にデータが破損するリスクがあります。
トランザクション管理(`StartTransaction` / `EndTransaction`)を使うことで、「すべて成功するか、すべて無かったこと(Abort)にするか」の安全な二者択一をプログラムに保証させることができます。

② `acadDoc.StartUndoMark` / `EndUndoMark` の魔力

先ほども触れた「Undoのグループ化」です。
これを挟まないと、VBAが実行した数千回のプロパティ変更がすべてバラバラの履歴としてUndoスタックに積まれ、AutoCADのメモリを圧迫し、ユーザーの操作性を最悪にします。
`StartUndoMark` を宣言しておけば、どれだけ大量のデータを一括処理しても、ユーザー目線では「Ctrl+Zを1回押すだけで、マクロ実行前の完璧な状態に戻る」という神仕様を実現できます。

③ 鉄壁の `On Error GoTo ErrorHandler`

データベースやトランザクションを扱うコードでは、エラーハンドリング(例外処理)をサボることは許されません。
万が一、処理の途中でレイヤーがロックされていたり、不正なデータに当たってエラー落ちしても、`ErrorHandler`内で確実に `AbortTransaction` と `EndUndoMark` を呼ぶことで、AutoCADが「ロック状態」や「中途半端なUndoマークの開きっぱなし」になるのを防ぎます。

4. 陥りやすい罠とエンジニアの心得

最後に、現場でよくある失敗パターンをご紹介しておきます。ここを知っておくだけで、無駄なデバッグ時間を何時間も節約できますよ。

  • 罠1: `EndUndoMark` を呼び忘れてフリーズしたようになる
  • エラーハンドリング内で `EndUndoMark` を呼ばずに途中で `Exit Sub` してしまうと、AutoCADのUndoシステムが「まだ記録中だ…」と思い込み、その後の手動操作でのUndo/Redoが一切効かなくなるバグが発生します。必ずエラー時もペアで閉じるようにしましょう。
  • 罠2: 画面描画のコントロール
  • 大量のデータを一括処理する際は、ループの直前に `acadDoc.Application.ScreenUpdating = False`(※厳密にはAutoCAD VBAには直接このプロパティはありませんが、`AcadDocument.Regen` のタイミングを制御するなど)を意識し、最後に `ThisDrawing.Regen acAllViewports` を1回だけ呼ぶようにすると、爆発的な高速化を実現できます。

まとめ

いかがでしたでしょうか?
今回は、AcadDocumentのさらに奥深くにある `Database` と、実務では絶対に欠かせない `Undo/Redoスタックの制御(トランザクション)` について解説しました。

最初は少し難しく感じるかもしれませんが、この「安全装置」の組み方をマスターすれば、あなたの書くAutoCAD VBAマクロは、社内の誰も真似できない「プロフェッショナル・グレードの堅牢な自動化ツール」へと生まれ変わります。

現場の信頼を勝ち取るエンジニアへの第一歩、ぜひご自身の環境でも試してみてくださいね!

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