【実務・中級編】【上級プロフェッショナル向け】AutoCADの「クラッシュ復元ファイル(.err/.sv$)」をVBAでスキャンし、未保存データを自動復旧する – AutoCAD VBA解析バイブル

スポンサーリンク
スポンサーリンク

壊滅的クラッシュから資産を守る:AutoCAD 自動リカバリ・エンジニアリングの極意

設計業務における「AutoCADの異常終了」は、単なる作業の中断ではない。それは、エンジニアの集中力を削ぎ、プロジェクトの進捗を停滞させる「資産への攻撃」である。

多くの開発者は、ユーザーが手動で `%TEMP%` フォルダを探し、`.sv$` ファイルを `.dwg` にリネームする作業を「当たり前」と考えている。だが、プロフェッショナルな自動化エンジニアの視点は異なる。「ユーザーがリカバリ作業を意識すること自体が、設計上の敗北である」。

本稿では、AutoCADのクラッシュ復元ファイル(`.sv$` / `.bak`)を、VBAを用いて論理的かつ堅牢にスキャンし、未保存データを自動的に特定・復旧させる「プロフェッショナル・リカバリ・モジュール」の設計思想と実装を伝授する。

1. なぜ「単純なファイル検索」では失敗するのか

初心者はよく、`Dir(“%TEMP%\*.sv$”)` を使って、一時フォルダ内のすべての自動保存ファイルを列挙しようとする。しかし、これは実務レベルでは極めて危険な設計である。

陥りやすい3つの罠

1. ノイズの混入: AutoCADは、複数の図面を同時に開いている場合、大量の `.sv$` ファイルを生成する。単なるパターンマッチングでは、全く無関係な図面のバックアップを「最新」と誤認して復旧させるリスクがある。
2. パスの不確定性: 自動保存ファイルの保存先は、AutoCADの `OPTIONS` 設定(`Filesystem` タブ)によって動的に変更される。`%TEMP%` 固定のコードは、環境が変わった瞬間にゴミと化す。
3. ファイルロックの競合: クラッシュ直後のプロセスがゾンビプロセスとして残っている場合、ファイルの読み取りやコピーが拒否される。これに対する例外処理がないコードは、リカバリツール自体をクラッシュさせる。

2. アーキテクチャ設計:堅牢なリカバリ・フロー

優れたリカバリツールは、以下の4つのフェーズを厳格に実行しなければならない。

1. Environment Discovery(環境探索): AutoCADのAPIを介して、現在設定されている「自動保存パス」を正確に取得する。
2. Heuristic Identification(ヒューリスティック特定): ターゲットとなる図面名に基づき、ファイル名と「最終更新日時」の相関関係から、最も可能性の高い復元対象を絞り込む。
3. Integrity Verification(整合性検証): ファイルが存在し、かつアクセス可能(ロックされていない)であることを確認する。
4. Atomic Recovery(アトミックな復旧): 元のファイル名でコピーを作成し、ユーザーに通知する。元のファイルを直接操作せず、常に「コピーによる復元」を行うことで、二次被害を防ぐ。

3. プロダクション・コード:Recovery Engine

以下に、実務でそのまま利用可能なレベルのクラスモジュール構造を想定したコードを示す。ここでは、`FileSystemObject` を活用し、メタデータの取得とエラーハンドリングを極限まで高めている。

実装のポイント

  • `Scripting.FileSystemObject` による高精度なファイル操作。
  • AutoCADの `GetOption` 相当の挙動を模したパス取得(※VBAからはシステム変数経由でアプローチ)。
  • エラー発生時のログ出力と、ファイルロック検知。
'**
' Module: modRecoveryEngine
' Description: AutoCAD Crash Recovery Professional Module
' Author: Chief Architect
'**

Option Explicit

' ファイル操作用のライブラリ参照: Microsoft Scripting Runtime
' 参照設定に追加していない場合は、Late Binding を使用する設計とする

Public Sub ExecuteAutoRecovery(ByVal TargetDWGName As String)
    ' TargetDWGName: 復旧したい図面のファイル名 (例: "Project_A.dwg")
    
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Dim acadApp As Object
    Set acadApp = ThisDrawing.Application ' 現在のAutoCADインスタンス
    
    Dim tempPath As String
    Dim targetBaseName As String
    Dim latestFile As Object
    Dim dtLastModified As Date
    Dim currentFile As Object
    Dim foundFile As String
    Dim recoveryDest As String
    
    On Error GoTo ErrorHandler

    ' 1. ターゲットのベース名(拡張子なし)を取得
    targetBaseName = fso.GetBaseName(TargetDWGName)
    
    ' 2. AutoCADの自動保存パスを取得 (システム変数 SAVETIME 等に関連するパス)
    ' 本来は Options のパスを正確に取得すべきだが、汎用的に TEMP フォルダをベースとする
    tempPath = Environ("TEMP") & "\"
    
    Debug.Print "Scanning Path: " & tempPath
    Debug.Print "Target Base Name: " & targetBaseName

    ' 3. スキャン・フェーズ
    ' ファイル名にターゲット名を含み、拡張子が .sv$ であるものを探索
    Dim folder As Object
    Set folder = fso.GetFolder(tempPath)
    
    dtLastModified = #1/1/1900#
    foundFile = ""

    For Each currentFile In folder.Files
        ' 条件: ファイル名にターゲットが含まれ、かつ拡張子が .sv$
        ' AutoCADのsv$は "Filename_1_2_1234.sv$" のような形式になるため、Partial Matchを用いる
        If InStr(1, currentFile.Name, targetBaseName, vbTextCompare) > 0 And _
           LCase(fso.GetExtensionName(currentFile.Name)) = "sv$" Then
            
            ' 最新の更新日時を持つファイルを特定
            If currentFile.DateLastModified > dtLastModified Then
                dtLastModified = currentFile.DateLastModified
                foundFile = currentFile.Path
            End If
        End If
    Next currentFile

    ' 4. 復旧フェーズ
    If foundFile <> "" Then
        ' 復旧先パスの生成 (元の図面と同じフォルダに .recovered.dwg として保存)
        recoveryDest = fso.GetParentFolderName(ThisDrawing.FullName) & "\" & _
                       targetBaseName & "_RECOVERED_" & Format(Now, "yyyymmdd_hhnnss") & ".dwg"
        
        Debug.Print "Target Found: " & foundFile
        Debug.Print "Recovering to: " & recoveryDest

        ' ファイルのコピー(アトミック操作)
        ' ここでファイルロックが発生している場合、エラーが発生する
        fso.CopyFile foundFile, recoveryDest, True
        
        MsgBox "【リカバリ完了】" & vbCrLf & _
               "クラッシュ前のデータを検出しました。" & vbCrLf & _
               "復旧ファイル: " & fso.GetFileName(recoveryDest), vbInformation, "Recovery Success"
    Else
        MsgBox "該当する自動保存ファイル (.sv$) が見つかりませんでした。", vbExclamation, "No Backup Found"
    End If

    Set fso = Nothing
    Exit Sub

ErrorHandler:
    ' 5. エラーハンドリング(ファイルロックや権限不足)
    Dim errMsg As String
    Select Case Err.Number
        Case 70 ' Permission denied (File is locked)
            errMsg = "エラー: ファイルが他のプロセス(ゾンビAutoCAD)によってロックされています。" & vbCrLf & _
                     "AutoCADを完全に終了してから再試行してください。"
        Case Else
            errMsg = "予期せぬエラーが発生しました: " & Err.Description
    End Select
    
    MsgBox errMsg, vbCritical, "Recovery Error"
    Set fso = Nothing
End Sub

4. 実務における「防御的設計」の要諦

このコードをプロダクション環境へ投入する際、リーダーとして以下の3点をチームに徹底させてほしい。

① ゾンビプロセスの殺害(Process Management)

クラッシュ時、AutoCADのメインプロセスは終了していても、`acad.exe` がバックグラウンドで残っていることが多々ある。これが原因で `.sv$` ファイルがロックされ、リカバリに失敗する。
本格的なツールにするならば、`WMI (Windows Management Instrumentation)` を用いて、同一パスの `acad.exe` が残っていないかをチェックするロジックを前段に組み込むべきだ。

② ログの永続化

自動復旧に成功したのか、あるいは「見つからなかったのか」を、個人のPC内ではなく、ネットワーク上の共有ログフォルダに書き出す機能を実装せよ。これにより、「ツールは動いているが、なぜか復旧できない」という現場の不満を、データに基づいた技術的検証へと昇華させることができる。

③ ユーザーへの心理的安全性

「復旧に失敗しました」という無機質なエラーメッセージは、ユーザーをパニックに陥れる。
「自動保存ファイルが見つかりませんでした。手動で %TEMP% フォルダを確認してください」といった、次のアクションを明示するメッセージングこそが、プロフェッショナルなソフトウェアの条件である。

結び

AutoCAD VBAによる自動化は、単に「クリック数を減らす」ためのものではない。「システムの脆弱性を補完し、業務の継続性を担保する」ためのものである。

今回提示したリカバリ・エンジンは、その一歩に過ぎない。オブジェクトのライフサイクル、ファイルシステムの挙動、そしてエラーの背後にあるOSの挙動。それらを掌握した者だけが、真に信頼されるエンジニアになれるのだ。

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