「いいか、よく聞け。自動化の世界において、ユーザーの手を煩わせる『ダイアログ』ほど無益なものはない。」
私はこれまで数え切れないほどのAutoCAD自動化プロジェクトを統括してきたが、初心者が必ずと言っていいほど踏む地雷がある。それが、「図面を閉じる際の保存確認ダイアログによる処理の中断」だ。
バッチ処理で100枚の図面を回している最中に、「変更を保存しますか?」というダイアログで止まってしまうツール。それはもはや自動化ツールではなく、ただの「手作業の劣化コピー」だ。
今回は、AutoCAD VBAを掌握する上で避けては通れない、`Saved`プロパティを駆使した「変更の強制破棄」について伝授する。このプロパティの真意を理解すれば、君の書くコードの堅牢性は劇的に向上するはずだ。
—
1. なぜ `Document.Close` だけでは不十分なのか
多くの初心者は、図面を閉じる際に `AcadDocument.Close` メソッドの引数に `False` を渡せば済むと考える。
‘ 初心者が書くコードの例
ThisDrawing.Close False
確かにこれは機能する。しかし、大規模なバッチ処理や、複数のドキュメントをまたぐ複雑な制御、あるいは外部データベースと連携するプロフェッショナルな現場では、これだけでは「甘い」と言わざるを得ない。
なぜか? AutoCADの内部状態において、「図面が変更されている」というフラグ自体をコントロールできていないからだ。
我々プロフェッショナルが好むのは、システムに「この図面は、たった今保存されたばかりの綺麗な状態だ」と思い込ませる、より洗練されたアプローチだ。
—
2. `Saved` プロパティ:システムを欺く「魔法のフラグ」
AutoCADの各 `Document` オブジェクトには、`Saved` というBoolean型のプロパティが存在する。
- `Saved = True`: 図面は最後に保存されてから変更されていない(とAutoCADが認識している)。
- `Saved = False`: 図面には未保存の変更がある。
ここで重要なのは、このプロパティは書き込みが可能であるという点だ。
たとえ図面内のオブジェクトを削除し、レイヤーを書き換え、ぐちゃぐちゃにした後でも、`Document.Saved = True` と一行記述するだけで、AutoCADは「おっと、この図面は保存済みだな。閉じる時に確認する必要はない」と判断するようになる。
プロの設計思想:
「変更を保存せずに閉じる」のではなく、「保存済みという状態を偽装して、平然と閉じる」。この思考の切り替えが、予期せぬダイアログを根絶する。
—
3. 実践:堅牢な「変更破棄」の実装パターン
では、実務でそのまま使えるプロダクションコードを示そう。単に閉じるだけでなく、エラーハンドリングとオブジェクト参照の解放を組み込んだ、保守性の高い設計だ。
”’
”’
”’ 対象のAcadDocumentオブジェクト
Public Sub ForceCloseWithoutSaving(ByRef doc As AcadDocument)
On Error GoTo ErrorHandler
If doc Is Nothing Then Exit Sub
‘ 1. システムを欺く:変更フラグを強制的に「保存済み」に書き換える
‘ これにより、Closeメソッド呼び出し時のダイアログ発生を物理的に封じる
doc.Saved = True
‘ 2. 閉じる
‘ 第1引数は「保存するかどうか」。Saved=Trueにしているため、Falseで問題ない。
‘ 第2引数は「ファイル名」。既存ファイルなら省略可能。
doc.Close False
Exit Sub
ErrorHandler:
‘ ログ出力などのエラー処理(実務ではここにエラーロギングを実装する)
Debug.Print “Error in ForceCloseWithoutSaving: ” & Err.Description
End Sub
全図面を一括で「変更破棄」して閉じる(バッチ処理の終端)
Public Sub CloseAllDocumentsDiscardingChanges()
Dim doc As AcadDocument
‘ AutoCADのドキュメントコレクションを逆順でループ
‘ (アクティブな図面との兼ね合いで、逆順ループが最も安全だ)
Dim i As Integer
For i = ThisDrawing.Application.Documents.Count – 1 To 0 Step -1
Set doc = ThisDrawing.Application.Documents.Item(i)
‘ 読み取り専用ファイルや、既に閉じられている場合のガード
If Not doc Is Nothing Then
‘ 自分の図面(マクロ実行中の図面)以外をすべて閉じる場合などの制御をここに入れる
‘ 今回は全破棄とする
doc.Saved = True
doc.Close False
End If
Next i
End Sub
—
4. アーキテクトが教える「運用の罠」と回避策
`Saved` プロパティを操作する際、以下の3点には細心の注意を払え。
① 読み取り専用(Read-Only)属性の罠
ネットワークドライブ上の図面を「読み取り専用」で開いている場合、`Saved = True` にしても、環境によっては `Close` 時に「名前を付けて保存」を促すダイアログが出るケースが稀にある。これを防ぐには、`doc.ReadOnly` プロパティを事前にチェックするロジックを組み込むのが定石だ。
② 外部参照(Xref)の通知
図面自体の変更フラグを `Saved = True` にしても、外部参照が更新されている場合、AutoCADが別の通知を出すことがある。バッチ処理を完璧に無人化するなら、`Expert` システム変数を一時的に書き換えて、あらゆるプロンプトを抑制するテクニックと併用せよ。
‘ あらゆるプロンプトを抑制する(取り扱い注意)
ThisDrawing.SetVariable “EXPERT”, 5
‘ … 処理 …
ThisDrawing.SetVariable “EXPERT”, 0
③ データベース連携時の不整合
もし君のツールが、図面内の情報をSQL ServerやExcelなどの外部DBに書き出しているなら、`Saved = True` で図面を閉じるタイミングに注意せよ。「DBは更新したが、図面は更新しなかった」という不整合が許される仕様か?
トランザクションの整合性を保つなら、「DB更新成功 = 図面も実際に保存」とするのが本来の姿だ。`Saved = True` による破棄は、あくまで「一時的な情報の抽出」や「プレビュー後のクリーンアップ」に限定すべきである。
—
結論:美学のあるコードを書け
`Saved` プロパティを操るということは、AutoCADのドキュメントライフサイクルを君の支配下に置くということだ。
初心者は「どうすれば閉じられるか」を考える。
だが、プロフェッショナルは「どうすればシステムの状態を汚さずに、次の処理へバトンを渡せるか」を考える。
今回紹介した `doc.Saved = True` は、単なるテクニックではない。ユーザーを煩わせず、確実に、そして静かに処理を完遂させるという、エンジニアとしての「美学」の表明である。
君のツールが、ダイアログ一つ出さずに数千枚の図面を鮮やかに処理することを期待している。
