AutoCAD VBAを掌握する極限の知見:図面クローズ時のダイアログ制御と「保存しない」自動化の鉄則
開発プロジェクトの現場において、図面のバッチ処理や自動化スクリプトを組む際、最もフラストレーションが溜まる瞬間を知っているか?
それは、処理の途中でAutoCADが無慈悲に「変更を保存しますか?」のダイアログを表示し、画面の向こうで人間のオペレーターのクリックを永遠に待ち続ける瞬間だ。
数千枚の図面を夜間に一括処理するプログラムを仕掛けたはずが、朝出社したら1枚目の確認ダイアログでフリーズしていた――笑い話のようだが、実務の現場では日常茶飯事に起きる悲劇である。
今回は、AutoCAD VBAにおける図面ファイルのクローズ制御、特に「保存確認ダイアログの完全バイパス」と「保存せずに破棄して閉じる(Discard Changes)」という、実務で絶対に避けて通れない極限の知見を伝授する。
—
1. なぜ「素の `Close` メソッド」では業務が破綻するのか?
初心者が最初に書くコードはこうだ。
‘ 【アンチパターン】絶対に真似してはならないコード
ThisDrawing.Close
このコードの何が問題か?
もし現在の図面にわずかでも変更(フラグの変更含む)が加わっている場合、AutoCADの内部エンジンはユーザーへの確認が必須であると判断し、容赦なくモーダルダイアログを立ち上げる。VBAの実行スレッドはそこで完全にブロックされ、外部からの介入が不可能になる。
業務自動化(RPAやバッチ処理)において、ユーザーインタラクション(画面のクリック)を要求するコードは「バグ」と同義である。私たちは、ダイアログを出させないための厳密なライフサイクル管理をコードに組み込まなければならない。
—
2. 堅牢なクローズ制御のメカニズム
AutoCADの `Document` オブジェクトにおける `Close` メソッドには、実は引数が用意されている。
object.Close([SaveChanges], [FileName])
- `SaveChanges` (Boolean): `True` なら変更を保存して閉じる。`False` なら変更を破棄して閉じる。
- `FileName` (String): 別名で保存する場合のパス(通常は省略可能)。
この `SaveChanges` に `False` を明示的に渡すことこそが、確認ダイアログをバイパスし、無言で図面を葬り去る(変更を破棄して閉じる)ための唯一にして最強の手段である。
さらに、プロフェッショナルなコードでは、「そもそも変更があったかどうか(`Saved` プロパティ)」を判定し、無駄な書き込み処理や不要なイベント発火を防ぐ配慮が求められる。
—
3. 【コピペ即稼働】プロダクションコード例
以下のコードは、実務の現場でそのまま組み込める、堅牢性を極めたドキュメントクローズのテンプレートだ。
現在の図面を変更を破棄して強制閉鎖し、必要であれば次の処理へ安全に制御を渡す設計にしている。
Option Explicit
/
- @brief 現在アクティブな図面を、保存確認ダイアログを出さずに強制クローズする
- @note 変更を加えた場合でも、一切のプロンプトを出さずに変更を破棄して閉じます。
/
Public Sub ForceCloseWithoutSaving()
On Error GoTo ErrorHandler
Dim targetDoc As AcadDocument
Set targetDoc = ThisDrawing
‘ 念のため、図面オブジェクトが有効かチェック
If targetDoc Is Nothing Then
MsgBox “対象となる図面が存在しません。”, vbCritical, “致命的エラー”
Exit Sub
End5:
‘ 【重要】
‘ 変更フラグ(Saved)の状態に関わらず、強制的に変更を破棄(False)して閉じる。
‘ 第1引数に False を渡すことで、あの忌々しい保存確認ダイアログを完全にハメ殺す。
‘ ※注意: この操作を行うと、未保存の変更データはリカバリー不可能です。
targetDoc.Close SaveChanges:=False
Exit Sub
ErrorHandler:
‘ 予期せぬCOMエラーや図面が既に閉じられている場合のケア
MsgBox “図面のクローズ処理中にエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “異常終了”
‘ エラーログ出力や上位システムへの通知をここに記述する
End Sub
コードの解説とアーキテクトの視点
1. `targetDoc.Close SaveChanges:=False` の圧倒的優位性
この1行により、AutoCADのデフォルトのUI介入を完全に断絶する。バッチ処理で「参照のみ行って、ゴミデータを残さずに次々と図面を閉じていく」ようなシーンにおいて、これ以上の解決策はない。
2. エラーハンドリングの義務化
AutoCAD VBAでは、背後でドキュメントが突然破棄されたり、他のプロセスと競合してCOM例外が発生することが稀によくある。`On Error GoTo` をサボるコードは、実務において「いつか必ず爆発する手りゅう弾」を仕掛けているのと同じだ。
—
4. 複数図面(MDI環境)を制御する場合の注意点
AutoCADはMDI(マルチドキュメントインターフェイス)環境である。アプリケーション内に複数の図面(`Documents` コレクション)が常駐している状態で一括処理を行う場合、単に `ThisDrawing` を操作するだけでは不十分だ。
もし複数の図面をループさせながら「保存せずに閉じる」処理を実装する場合は、以下のようにコレクションを逆順(インデックスの大きい方から小さい方へ)で処理するのが、メモリリークやインデックスずれを防ぐための定石である。
Public Sub CloseAllDocumentsWithoutSaving()
Dim i As Long
Dim doc As AcadDocument
‘ コレクションの数から逆向きにループを回す(削除・クローズ時の鉄則)
For i = Application.Documents.Count – 1 To 0 Step -1
Set doc = Application.Documents(i)
‘ 現在のVBAコードを実行しているプロジェクト自体を閉じようとするとエラーになるため除外する判定を入れるとより安全
If doc.Name <> ThisDrawing.Name Then
‘ 変更を破棄して閉じる
doc.Close SaveChanges:=False
End If
Next i
‘ 最後に自身の図面を閉じる(必要に応じて)
‘ ThisDrawing.Close SaveChanges:=False
End Sub
—
5. 総括:プロフェッショナルたるもの「対話」を排除せよ
業務自動化の美学は「完全な無人化」にある。
「図面を閉じる」という極めてプリミティブな操作であっても、背後で何が起きているのか(ダイアログの割り込み、COMのライフサイクル、MDIのメモリ管理)を完全に理解していなければ、堅牢なシステムなど構築できるはずがない。
今回伝授した `Close SaveChanges:=False` のイディオムをあなたのツールキットに加え、ダイアログの呪縛から解放された真の高速自動化環境を手に入れてほしい。
