【AutoCAD VBA超入門】Closeメソッドの「SaveChanges」を完全掌握せよ:保存漏れと意図しない上書きを防ぐ実務設計
こんにちは。開発プロジェクトの現場において、数々のAutoCAD自動化を指揮してきたチーフアーキテクトだ。
業務効率化マクロを作り始めた開発者が、最初期につまずき、そして最も痛い目を見るポイントをご存知だろうか?
それが、今回取り上げる図面を閉じる際の `Close` メソッド、特に引数である `SaveChanges`(変更を保存するかどうか)の制御 だ。
「とりあえず `True` にしておけば保存されるだろ」「ダイアログが出て鬱陶しいから `False` でいいか」——そんな安易な実装をしていないだろうか?
そのコード、一歩間違えば顧客の重要図面を破壊する、あるいは1日の作業成果を闇に葬る「爆弾」になり得る。
今回は、AutoCAD VBAにおける図面ライフサイクルの核心に迫り、バグの起きない堅牢なファイルのクローズ処理をロジカルに伝授しよう。
—
1. なぜ「Closeメソッドの誤用」が現場を破滅させるのか?
AutoCADのVBAで大量の図面を一括処理(バッチ処理)するツールを作ったとしよう。
複数のDWGを開き、文字を置換し、閉じる。このシンプルなループ処理の中で、以下の2つの悲劇が頻発する。
1. 保存漏れ(Save Miss):
プログラム側で加工したにもかかわらず、保存されずに閉じられ、成果物が空っぽになる。
2. 意図しない上書き(Unintended Overwrite):
「ちょっと中身を確認しただけ」のつもりの元図が、検証中の適当な変更を含んだまま上書き保存され、原典データが破壊される。
これらはすべて、`Document.Close` メソッドの仕様を理解していないことが原因だ。
Document.Close メソッドの基本構文
object.Close [SaveChanges, [FileName]]
- `SaveChanges` (Boolean):
- `True`: 変更を保存して閉じる。
- `False`: 変更を破棄して閉じる。
- 省略した場合:
図面に変更がある場合、AutoCADは容赦なくユーザーへ「変更を保存しますか?」の確認ダイアログを表示する。
ここで重要なのは、「バックグラウンド(バッチ処理)でこれをやられると、ダイアログが画面の裏でモダールフリーズを起こし、プログラムが永遠に止まる(ハングアップする)」という点だ。完全自動化を目指す私たちにとって、予期せぬダイアログの出現は「悪」なのだ。
—
2. 実務で求められる「3つのクローズ戦略」
現場の要件によって、図面を閉じるアプローチは明確に使い分ける必要がある。適当にコピペしたコードを使うのではなく、以下の設計思想を頭に叩き込んでほしい。
戦略A:【安全第一】変更がある時だけダイアログを出してユーザーに委ねる
人間が目視確認しながら操作する対話型マクロの基本。
戦略B:【完全自動化・サイレント】変更があろうがなかろうが、強制破棄(参照専用)
ログ集計や図面チェッカーなど、図面を一切書き換えない(読み取り専用または変更を捨てたい)場合の鉄板。
戦略C:【スマート上書き】プログラムが意図した変更のみを確実にセーブする
自動修正スクリプトなど、改変を加えたことが確実な場合に行うクローズ。
—
3. 【コピペOK】プロダクションコード実装例
それでは、実務の現場でそのまま使える、堅牢性とエラーハンドリングを考慮したプロシージャを公開しよう。
このコードでは、「図面に変更(Modified)が加わっているか」を判定し、意図しない上書きを防ぐロジックを組み込んでいる。
Option Explicit
”’
”’
Public Sub SafeCloseActiveDrawing()
Dim targetDoc As Document
Set targetDoc = ThisDrawing.Application.ActiveDocument
On Error GoTo ErrorHandler
‘ — 【分岐の設計】図面の状態に応じたクローズ処理 —
‘ ケース1: 図面に何の変化も加わっていない場合
If targetDoc.Saved = True Then
Debug.Print “変更はありません。速やかに閉じます。”
targetDoc.Close False ‘ 保存不要なのでFalseで閉じる
Exit Sub
End If
‘ ケース2: 図面が変更されている場合(ここが腕の見せ所)
‘ 実務要件に合わせて、以下のコメントアウトを切り替えてください。
‘ — パターンA: ユーザーに確認を促す場合(対話型) —
‘ targetDoc.Close True ‘ 引数を省略、またはTrueでAutoCAD標準のダイアログを喚起
‘ — パターンB: 【推奨】プログラムの意思で強制上書き保存する場合 —
‘ ※注意:必ず事前にバックアップを取る設計にすること
Dim userResponse As VbMsgBoxResult
userResponse = MsgBox(“図面 [” & targetDoc.Name & “] に変更が加えられています。” & vbCrLf & _
“上書き保存して閉じますか?”, vbYesNo + vbQuestion, “AutoCAD自動クローズ制御”)
If userResponse = vbYes then
‘ 変更を保存して閉じる(上書き)
targetDoc.Close True
MsgBox “変更を保存して閉じました。”, vbInformation
Else
‘ 変更を破棄して閉じる(元図を守る)
targetDoc.Close False
MsgBox “変更を破棄して閉じました。”, vbInformation
End If
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
‘ 異常終了時のフォールバック(必要に応じてファイルロック解除等のクリーンアップを記述)
End Sub
—
4. チーフアーキテクトからの実践的アドバイス(注意点と裏技)
現場でこのコードを運用するにあたり、シニアエンジニアとして知っておくべき「深淵」をいくつか共有しよう。
① `ThisDrawing` への依存を断て
初心者が書きがちな `ThisDrawing.Close` は、コードを実行しているマクロが含まれる図面(通常は `acadd.dvb` やアドイン)を閉じようとしてエラーを起こすか、意図しない挙動の元になる。
必ず `Application.ActiveDocument` や、`Documents.Open` で取得したドキュメントオブジェクト変数に対して `Close` を叩くこと。オブジェクト指向の基本だ。
② すでに図面が閉じられている場合への耐性
ループ処理の中で複数の図面を閉じていると、「既に何らかの理由で閉じられたドキュメント」に対して再度 `Close` を実行し、ランタイムエラー(“オブジェクトがありません”)を引き起こすケースがある。
クローズ処理の前には、必ずドキュメントコレクションの存在確認や、エラーハンドリング(`On Error Resume Next` の限定的利用)を挟むのがプロの作法だ。
③ `Database.SaveAs` とのコンボ技
「別の名前で保存して、元の図面は変更せずに閉じたい」という要件は実務で非常に多い。その場合は、`Close` の引数に頼るのではなく、以下のように明示的にコントロールするのが定石だ。
‘ 元の図面を汚さずに別名で保存し、変更フラグをクリアしてから閉じる
Dim savePath As String
savePath = “C:\Projects\Output\Processed_” & targetDoc.Name
‘ 別名保存
targetDoc.SaveAs savePath
‘ 変更フラグを強制的にTrueからSaved(変更なし)の状態に見せかけてFalseで閉じる
‘ ※SaveAsした時点でSaved=Trueになるため、そのままClose(False)でOK
targetDoc.Close False
—
まとめ:あなたのコードから「偶発的な事故」を排除せよ
AutoCAD VBAにおける `Close` メソッドの `SaveChanges` は、単なる真偽値の指定ではない。
「データの保全性」と「プロセスの完全自動化」を担保するための重要なアーキテクチャ要素だ。
- 変更の有無を `targetDoc.Saved` で必ず検知する。
- サイレント処理にするのか、ユーザーに確認するのかを用途ごとに明確に分離する。
- 意図しない上書きでエンジニアの信頼を失墜させないコードベースを築く。
この知見を取り入れれば、あなたの作るAutoCAD自動化ツールは、現場のエンジニアから「絶対にバグらない信頼の置けるシステム」として絶賛されることだろう。
さあ、今すぐ自分のコードの `Close` メソッドを見直し、堅牢なエラーフリーの設計へアップデートしてほしい。
