【テクニカル・上級編】【初心者向け】図面を閉じる際の「変更の破棄」をVBAで確実に制御する:Savedプロパティの活用 – AutoCAD VBA解析バイブル

スポンサーリンク

序文:自動化の成否を分ける「沈黙」の制御

オートメーションの世界において、最も忌むべきは「予期せぬ対話ボックスの出現」である。
数千枚の図面をバッチ処理する夜、エンジニアがベッドに入った数分後、一つのダイアログが「変更を保存しますか?」と問いかけ、すべてのプロセスを停止させる。これは自動化エンジニアにとっての敗北を意味する。

AutoCAD VBAを扱う者が最初に直面し、そして最後まで付き合うことになるのが、この「図面を閉じる際の挙動制御」だ。特に、一時的な情報を抽出しただけの図面や、不適切な編集を行ってしまった図面を「痕跡を残さず、静かに破棄する」技術は、システムの堅牢性を担保する要(かなめ)となる。

今回は、単なるプロパティの説明に留まらず、オブジェクトのライフサイクル管理とメモリ最適化の観点から、`Saved` プロパティの真髄を解説する。

—

1. `Saved` プロパティの本質:AutoCADを欺く技術

AutoCADのドキュメントオブジェクト(`AcadDocument`)には、その図面が最後に保存されてから変更があったかどうかを保持する `Saved` というBoolean型のフラグが存在する。

通常、図面内のエンティティ(LineやCircleなど)を一つでも追加・修正すれば、このフラグは自動的に `False` に切り替わる。そして `Close` メソッドが呼ばれた際、AutoCADはこのフラグが `False` であることを見て、「保存しますか?」というUIを呼び出す仕組みだ。

我々エンジニアがすべきことは、Closeを呼ぶ直前に、このフラグを強制的に `True` に書き換えることである。これにより、AutoCADは「この図面は最新の状態である」と誤認し、一切のダイアログを出さずにメモリを解放する。

—

2. 実践的コード:変更を破棄して閉じる極限のテンプレート

以下に、実戦でそのまま使用できる堅牢なコードを示す。単に閉じるだけでなく、オブジェクト参照の解除までをセットで行うのがプロフェッショナルの作法だ。

‘——————————————————————————-
‘ 概要: 変更を一切保存せず、強制的に図面を閉じる
‘ 引数: targetDoc – 閉じる対象の AcadDocument オブジェクト
‘ 備考: 呼び出し元でエラーハンドリングを行うこと
‘——————————————————————————-
Public Sub ForceCloseWithoutSaving(ByRef targetDoc As AcadDocument)
On Error Resume Next

If targetDoc Is Nothing Then Exit Sub

‘ 1. AutoCADの「変更フラグ」を強制的にリセットする
‘ これにより、Closeメソッド実行時のダイアログ出現を完全に抑制する
targetDoc.Saved = True

‘ 2. 図面を閉じる
‘ 第1引数は保存の有無だが、Saved=Trueにしているためどちらでも挙動は変わらない
‘ しかし、念のためFalse(保存しない)を明示するのがセオリーである
targetDoc.Close SaveChanges:=False

‘ 3. オブジェクトの明示的解放
‘ VBAのガベージコレクションは時として不完全だ。
‘ 特にループ処理内では、明示的にNothingを代入し、COM参照カウンタを下げる必要がある。
Set targetDoc = Nothing

On Error GoTo 0
End Sub

—

3. シニアエンジニアが考慮すべき「メモリとプロセスの闇」

単に `Saved = True` を行うだけでは、真のプロフェッショナルとは言えない。大規模システムやレガシーな環境においては、以下の3点に留意せよ。

① ゾンビプロセスの回避(Object Leak)

AutoCAD VBAから外部アプリケーション(Excel等)を操作する場合、またはその逆の場合、`AcadApplication` や `AcadDocument` の参照が残っていると、AutoCADを終了させたつもりでも `acad.exe` がバックグラウンドで生き残る「ゾンビプロセス」現象が発生する。
`Saved = True` で図面を閉じた後は、必ず呼び出し元の変数に `Nothing` を代入し、COMの参照チェーンを断ち切ること。

② Windows APIによる強制介入の是非

極稀に、サードパーティ製のARXアプリケーションなどが `Saved` プロパティを上書きし、強制的にダイアログを出そうとするケースがある。その場合は、Windows APIの `SendMessage` を使用して、ダイアログのウィンドウハンドル(HWND)を捕捉し、`WM_CLOSE` を叩き込むような泥臭い処理が必要になることもある。しかし、VBA標準機能の範囲内では `Saved = True` が最もエレガントで副作用の少ない手段である。

③ ReadOnly属性の壁

読み取り専用で開かれた図面に対して編集を行い、誤って `Save` メソッドを呼ぶと、実行時エラーが発生する。この場合も、エラーをトラップして `Saved = True` に逃がす処理を組み込んでおくのが、無人運転を成功させる秘訣だ。

—

4. システム間連携における応用

バッチ処理において「特定のバージョン(例:AutoCAD 2018形式)で保存し直して閉じる」といった要件がある場合、以下のようなロジックを組む。ここでも、保存完了直後の状態管理が重要になる。

‘ バージョン互換を考慮した保存とクローズの例
Public Sub SaveAsLegacyAndClose(ByVal targetDoc As AcadDocument, ByVal filePath As String)
On Error GoTo Err_Handler

‘ ac2018_dwg 形式などで保存(列挙型を使用)
‘ 保存に成功した時点で、Savedプロパティは自動的にTrueになる
targetDoc.SaveAs filePath, acR24 ‘ AutoCAD 2018 format

‘ 保存直後に不必要な変更を加えない限り、そのまま閉じればダイアログは出ない
targetDoc.Close
Set targetDoc = Nothing

Exit Sub

Err_Handler:
‘ 保存に失敗した場合(ファイルロック等)、変更を破棄して沈黙を守る
If Not targetDoc Is Nothing Then
targetDoc.Saved = True
targetDoc.Close
Set targetDoc = Nothing
End If
End Sub

—

結言:アーキテクトの視点

`Saved` プロパティを操るということは、AutoCADのステートマシンを制御することに他ならない。
初心者は「ダイアログを消すための便利なスイッチ」と捉えるが、我々シニアエンジニアはこれを「プロセスの整合性を保ち、リソースのライフサイクルを完結させるための安全装置」と定義する。

コードの一行一行に、背後で動くメモリの挙動をイメージせよ。
その執念が、止まらないシステム、死なない自動化を作り上げる。

技術の深淵へ、ようこそ。

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