【実務・中級編】【初心者向け】Closeメソッドの引数「SaveChanges」徹底攻略:保存漏れと意図しない上書きを防ぐ – AutoCAD VBA解析バイブル

スポンサーリンク

【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` メソッドを見直し、堅牢なエラーフリーの設計へアップデートしてほしい。

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