【実務・中級編】【上級プロフェッショナル向け】ネットワーク切断時の緊急退避保存:保存失敗をトラップしてローカルへ自動バックアップ – AutoCAD VBA解析バイブル

スポンサーリンク

その保存ボタン、命懸けで押せますか?:ネットワーク断絶に抗う「緊急退避保存」の極意

設計現場において、最も虚しい音は何だか知っているだろうか。
それは、数時間の集中を経て書き上げた図面を保存しようとした瞬間に響く、VPN切断の警告音と、それに続くAutoCADのフリーズ音だ。

サーバー上のDWGファイルに対して「保存(Save)」をかけた際、ネットワークが瞬断されていると、AutoCADは数分間の沈黙(ハングアップ)の末、最悪の場合はクラッシュする。標準の自動保存(.sv$)に期待するのは素人の仕事だ。プロフェッショナルなら、「保存の失敗」を論理的に予見し、即座にローカル環境へデータを逃がすエスケープハッチをコードに組み込んでおくべきである。

今回は、AutoCAD VBAを掌握するアーキテクトの視点から、堅牢極まる「緊急ローカルバックアップ処理」の実装を伝授する。

—

1. なぜ標準の「Save」だけでは不十分なのか

AutoCADの `ThisDrawing.Save` や `ThisDrawing.SaveAs` メソッドは、ネットワークパスへのアクセス権が失われた際、OSレベルのタイムアウトを待機してしまう。この「待ち」がVBAのシングルスレッド実行をブロッキングし、ユーザーインターフェースを凍結させる。

さらに、以下のリスクを考慮しなければならない。

  • ファイルロックの残存: 保存に失敗した際、サーバー上に中途半端な一時ファイルが残り、再接続後に「読み取り専用」でしか開けなくなる。
  • 共有違反: 誰かが同じファイルを操作している最中にネットワークが不安定になると、ファイル構造そのものが破壊されるリスクがある。

これらを回避するためには、「まず保存先が健全かを確認し、失敗した瞬間に迷わずローカルへ転進する」という二段構えの設計が不可欠だ。

—

2. 堅牢な保存戦略:フェイルセーフ・プロトコル

我々が実装すべきは、単なるエラーハンドリングではない。以下のステップを踏む「インテリジェント・セーブ」である。

1. 疎通確認: 現在のファイルパスが書き込み可能かテストする。
2. トラップ設置: `On Error` を用い、保存エラーを即座に捕捉する。
3. ローカル退避: ユーザーの `TEMP` フォルダ、あるいは特定のローカルディレクトリに「日時+元のファイル名」で緊急保存を実行。
4. 通知とログ: どこに保存したかをユーザーに明確に伝え、設計業務を継続させる。

—

3. プロダクション・コード:`SmartEmergencySave`

以下のコードは、そのまま実務の標準モジュールとして採用できるレベルまで磨き上げたものだ。

Option Explicit

‘ AutoCADバージョンの互換性を保持するための定数(AutoCAD 2018以降を想定)
Private Const AC_SAVE_VERSION As Integer = 64 ‘ ac2018_dwg (acNative)

”’

”’ ネットワークエラーを監視し、失敗時にローカルへ緊急保存する
”’

Public Sub SmartEmergencySave()
Dim doc As AcadDocument
Set doc = ThisDrawing

Dim originalPath As String
Dim fileName As String
Dim localBackupPath As String
Dim timeStamp As String

‘ 1. 現在の状態を把握
On Error Resume Next
originalPath = doc.FullName
fileName = doc.Name
On Error GoTo 0

‘ 新規図面(一度も保存されていない)の場合は通常のSaveAsダイアログへ
If originalPath = “” Or InStr(originalPath, “\”) = 0 Then
On Error Resume Next
doc.SendCommand “_SAVEAS ”
Exit Sub
End If

‘ 2. メインの保存処理を試行
On Error GoTo Err_NetworkFailure

‘ 読み取り専用チェック
If doc.ReadOnly Then
MsgBox “この図面は読み取り専用です。別名で保存を検討してください。”, vbExclamation, “警告”
Exit Sub
End If

‘ 保存実行
Debug.Print “Saving to: ” & originalPath
doc.Save

Debug.Print “Save successful.”
Exit Sub

Err_NetworkFailure:
‘ 3. ネットワーク切断・書き込み失敗時の緊急処理
‘ エラー番号 0x800401E3 (MK_E_UNAVAILABLE) やオートメーションエラーを捕捉

timeStamp = Format(Now, “yyyyMMdd_HHmmss”)
‘ ローカルのTempフォルダを特定
localBackupPath = Environ(“TEMP”) & “\AutoCAD_Emergency_Save\”

‘ バックアップ用フォルダがなければ作成
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FolderExists(localBackupPath) Then
fso.CreateFolder localBackupPath
End If

Dim emergencyFile As String
emergencyFile = localBackupPath & timeStamp & “_” & fileName

‘ ローカルへの退避保存を実行
On Error Resume Next
‘ SaveAsの第2引数でDWGバージョンを固定(互換性担保)
doc.SaveAs emergencyFile, AC_SAVE_VERSION

If Err.Number = 0 Then
Dim msg As String
msg = “【緊急事態】ネットワークへの保存に失敗しました。” & vbCrLf & _
“データを失わないよう、以下のローカルパスに退避保存しました。” & vbCrLf & vbCrLf & _
“保存先: ” & emergencyFile & vbCrLf & vbCrLf & _
“ネットワーク復旧後、このファイルをサーバーへ戻してください。”
MsgBox msg, vbCritical, “緊急退避完了”
Else
MsgBox “致命的なエラー:ローカルへの退避保存にも失敗しました。” & vbCrLf & _
“ディスク容量や権限を確認してください。”, vbCritical, “最悪の事態”
End If

Set fso = Nothing
End Sub

—

4. アーキテクトによる解説:ここが「プロ」の書き方だ

オブジェクト・ライフサイクルとエラー制御

`On Error Resume Next` を漫然と使うのは三流だ。このコードでは、`originalPath` の取得という「失敗しても致命的ではない箇所」と、`Save` という「失敗をトリガーに動くべき箇所」を明確に分けている。

`Environ(“TEMP”)` の活用

保存先を `C:\Backup` などとハードコーディングしてはいけない。権限設定(ACL)に阻まれる可能性があるからだ。ユーザーごとに必ず書き込み権限が保証されている `%TEMP%` フォルダを起点にするのが、エンタープライズ向けツールの鉄則である。

`ac2018_dwg` (64) の明示

`SaveAs` メソッドを使う際、第2引数を省略すると「現在の設定」に依存する。しかし、プロジェクトによっては旧バージョン(2013形式など)での保存が求められることもある。ここを定数化し、組織の標準に合わせることで、意図しないバージョンアップによる「他部署で開けない」という事故を防ぐ。

ファイルシステムオブジェクト (FSO) の遅延バインディング

`CreateObject(“Scripting.FileSystemObject”)` を使用しているのは、参照設定の欠落によるコンパイルエラーを防ぐためだ。配布性を重視するなら、実行時バインディングが正解である。

—

5. さらに高みを目指すなら:データベース連携の注意点

もし君が、図面プロパティをSQL Serverなどの外部データベースと同期させているなら、この緊急保存時に「同期フラグ」をオフにする処理を追加せよ。

ネットワークが死んでいる状態でDBへの接続を試みれば、そこでもタイムアウトが発生し、せっかくローカルに保存した後にアプリケーションがクラッシュしかねない。
「ネットワークが不安定なら、外部との通信はすべて遮断し、ローカル完結モードに移行する」というステート管理こそが、真のチーフアーキテクトが設計すべき領域だ。

結びに代えて

「保存に失敗しました」というダイアログを出して終わるツールは、ユーザーにとって「何もしない」のと同じだ。プロフェッショナルの仕事とは、予期せぬ事態が起きたときに、ユーザーに代わって最善の次の一手を打つことにある。

このコードを君のライブラリに組み込み、現場の「絶叫」を「安堵」に変えてほしい。それが、システムを構築する我々に課せられた使命なのだから。

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