【入門編】【実務中級】AcadDocument.StartUndoMarkとEndUndoMarkの適切な配置:複雑な一括処理を「Ctrl+Z」一回で元に戻せるようにする親切設計 – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは!AutoCADの自動化設計、楽しんでいますか?
マクロの記録から一歩踏み出し、自分だけのVBAプログラムを書き始めると、図面を一瞬で書き換える魔法のような快感に魅了されますよね。

さて、開発に夢中になるあまり、こんな経験はありませんか?

「数千個の円を一括生成するマクロを作ったぞ!……おっ、動いた動いた。あれ? ちょっと配置ズレてるな……。よし、『Ctrl + Z』で元に戻そう!……あれ? 一つ戻るのに、Ctrl + Zを何百回連打しなきゃいけないんだ……!?(絶望)」

実務でAutoCAD VBAを使うなら、動くだけのコードではプロとして少し物足りません。そのツールを使う設計者への「優しさ」――すなわち、大量の処理を「Ctrl + Z」一回でキレイに元に戻せる親切設計を実装できてこそ、真のプロフェッショナルです。

今回は、AutoCAD VBAの隠れた名機能、`StartUndoMark` と `EndUndoMark` の極意を、優しく、そして本質的なところまで徹底解説します。ここをクリアすれば、あなたの作るマクロは一気に「実務レベルのプロ仕様」にランクアップしますよ!

1. なぜ「Undo(元に戻す)のグループ化」が必要なのか?

AutoCADは、あなたがVBAから実行した「オブジェクト一個の生成や変更」のすべてを、背後でバラバラにUndoスタック(履歴)に積み上げていきます。

例えば、マクロで5,000本の線分を描画したとしましょう。裏側では、AutoCADに対して「線を描け」という命令が5,000回発行されています。そのため、ユーザーが「やっぱりやめた!」とCtrl + Zを押したとき、マクロが実行した一連の処理が1コマずつ逆再生されてしまうのです。これではユーザーの指が腱鞘炎になってしまいますよね。

ここで登場するのが、Undoマーク(トランザクションの境界)です。

[マクロ実行前] ─── (通常の履歴)

├─★ StartUndoMark (ここからグループ化開始!)
│ ├── 線分1の作成
│ ├── 線分2の作成
│ └── …(中略)…
│ └── 線分5000の作成
├─★ EndUndoMark (ここまでをひとまとめにする!)

[マクロ実行後] ─── (ユーザーのCtrl + Z 1回で、ここまで一網打尽に消える!)

このように、コードの「ここからここまでを1つの作業として扱ってね」とAutoCADに宣言してあげるのが、`AcadDocument` が持つUndo制御の役割です。

2. 基本構文と使い方:呪文のようにこの形を覚えよう!

実装は驚くほどシンプルです。対象となる `AcadDocument` オブジェクトに対して、処理の「前」と「後」でメソッドを挟み込むだけです。

Dim doc As AcadDocument
Set doc = ThisDrawing

‘ 【1. Undoグループの開始】
doc.StartUndoMark

On Error GoTo ErrorHandler ‘ エラー対策も忘れずに!

‘ ==========================================
‘ ここに数千個の生成・変更といった重い処理を書く
‘ ==========================================

‘ 【2. Undoグループの終了】
doc.EndUndoMark
Exit Sub

ErrorHandler:
‘ 万が一エラーで途中で止まった場合の保険
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
‘ エラー時にもEndUndoMarkをペアで閉じる配慮がプロの技
doc.EndUndoMark
End Sub

💡 先輩エンジニアからの重要なアドバイス(ここテストに出ます)

`StartUndoMark` を呼び出したら、必ずペアとなる `EndUndoMark` を実行するようにしてください。もし途中でエラー(ゼロ除算やオブジェクトが見つからない等)が起きて `EndUndoMark` が呼ばれずにマクロが終了してしまうと、AutoCADのUndoスタックの整合性が狂い、最悪の場合その図面ファイルが不安定になります。
上のサンプルコードのように、`On Error GoTo` を使ってエラー時でも必ずEndUndoMarkを通る構造(あるいは確実にペアを閉じる設計)にするのが、現場で生き残るエンジニアの鉄則です。

3. 【実践】数千個の円を一瞬で生成し、1回で戻せるマクロ

それでは、実際に動かせるサンプルコードを見てみましょう。
このマクロは、モデル空間にランダムな座標で500個の円を描画します。もちろん、実行後に `Ctrl + Z` を押せば、500個の円がパッと一瞬で消え去り、マクロ実行前の状態に完全に戻ります。

Sub DrawCrystalsWithSmartUndo()
Dim doc As AcadDocument
Set doc = ThisDrawing

‘ 描画処理を高速化するための鉄板テクニック
‘ (画面更新と自動スナップを一時停止してパフォーマンスを爆上げする)
Dim oldScalarEmf As Variant
oldScalarEmf = doc.GetVariable(“REGENMODE”)
doc.SetVariable “REGENMODE”, 0

‘ ==========================================
‘ 【重要】Undoマークの開始
‘ ==========================================
doc.StartUndoMark

On Error GoTo SafeExit ‘ 安全に抜けるためのエラーハンドラ

Dim i As Long
Dim centerPoint(0 to 2) As Double
Dim radius As Double
Dim circObj As AcadCircle

‘ 500個の円を生成するシミュレーション
For i = 1 to 500
‘ 座標をランダムに計算(例:X, Yともに 0 ~ 1000 の範囲)
centerPoint(0) = Rnd 1000
centerPoint(1) = Rnd 1000
centerPoint(2) = 0#

radius = (Rnd 20) + 5 ‘ 半径 5 ~ 25

‘ 円を作成
Set circObj = doc.ModelSpace.AddCircle(centerPoint, radius)
Next i

SafeExit:
‘ エラーの有無にかかわらず、必ずUndoマークを閉じる!
doc.EndUndoMark

‘ 画面描画設定を元に戻す
doc.SetVariable “REGENMODE”, oldScalarEmf
doc.Regen acAllViewports

If Err.Number <> 0 Then
MsgBox “処理中にエラーが発生しました: ” & Err.Description, vbExclamation
Else
MsgBox “500個の円の生成が完了しました![Ctrl + Z] で一発で元に戻せます。”, vbInformation
End If
End Sub

このコードの優れたポイント

1. `REGENMODE` の制御による爆速化:数千個のオブジェクトを作る際、描画の都度画面を再計算させると激重になります。`REGENMODE = 0` でバックグラウンド処理に徹させ、最後に一括で `Regen` をかけることで実用的なスピードを実現しています。
2. 確実なUndoの閉じ込め:`SafeExit` ラベルを用意し、エラーが起きようが正常終了しようが、必ず `doc.EndUndoMark` が通る堅牢な設計になっています。

4. 陥りがちな罠:UndoMarkの「ネスト(入れ子)」にご注意

中級者以上になると、既存の汎用関数(例えば「指定した画層に線を引く共通関数」など)の中で、親切心から `StartUndoMark` を入れてしまうことがあります。

‘ 共通関数
Sub DrawLineHelper()
ThisDrawing.StartUndoMark
‘ 線の描画処理…
ThisDrawing.EndUndoMark
End Sub

これをメインのマクロから何回も呼び出すと、Undoマークの「入れ子(ネスト)」が発生します。
AutoCAD VBAのUndoシステムは、ネスト構造に対応しており、マークの開始と終了のペアの数がピタッと一致しないと、期待通りにグループ化されなかったり、最悪の場合「Undoマークのバランスが崩れています」という実行時エラーを引き起こします。

【原則】

  • Undoマークの制御は、ユーザーが直接操作する「メインのエントリポイント(Subプロシージャの頭とお尻)」にだけ置く。
  • 内部の細かいヘルパー関数の中では `StartUndoMark` / `EndUndoMark` は呼ばない。

このルールを守るだけで、複雑なモジュール構成にしてもトラブルを完全に回避できます。

まとめ

今回は、実務で差がつく `AcadDocument.StartUndoMark` と `EndUndoMark` について解説しました。

  • マクロの一連の大量処理は `Ctrl + Z` 一回で戻せるようにするのが「プロの気配り」
  • 処理の直前で `StartUndoMark`、直後で `EndUndoMark` を呼ぶだけ
  • エラー時でも必ず `EndUndoMark` を通過するような安全設計(`On Error`の活用)を忘れない

たったこれだけの記述を加えるだけで、あなたが作ったVBAツールは、「ただ動くプログラム」から「現場のエンジニアに愛される極上の便利ツール」へと生まれ変わります。

ここをクリアすれば、もうAutoCAD VBAの基礎で迷うことはありません。自信を持って、次の自動化チャレンジへ進んでくださいね!

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