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

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

失われた時間を奪還せよ:AutoCAD VBAによる「クラッシュ復元エンジン」の構築

「……あ。」

その瞬間、背筋に冷たいものが走るはずです。数時間にわたって作り込んだ複雑な図面、緻密なレイアウト、そして膨大な注釈。AutoCADが予期せぬエラーで落ち、デスクトップに虚しく表示される「プログラムが応答していません」の文字。

もし、あなたが「マクロの記録」を卒業し、真の自動化エンジニアを目指すなら、この絶望を「システムによる自動復旧」という技術的挑戦へ昇華させなければなりません。

今日は、AutoCADがバックグラウンドで生成している「救いの手」――オートセーブファイル(.sv$)をVBAでスキャンし、未保存のデータを自動で検知・復旧する、プロフェッショナルなリカバリユーティリティの開発術を伝授します。

1. 仕組みを理解する:AutoCADの「影」を追え

自動復旧ツールを作る前に、まずは敵(あるいは味方)の正体を知る必要があります。AutoCADは、万が一のクラッシュに備えて、作業ディレクトリ内に「影」のようなファイルを作成しています。

拡張子 正体 特徴
.dwg 本尊 あなたが普段保存しているメインファイル。
.bak バックアップ 前回「保存」ボタンを押した時点の状態。
.sv$ オートセーブ 今回のターゲット。 一定時間ごとに自動書き出しされる「最新の断片」。

プロフェッショナルなエンジニアは、単に「ファイルがあるか」を見ません。「どのファイルが最も新しいタイムスタンプ(更新日時)を持っているか」という、オブジェクトのメタデータに注目します。

2. 設計図:リカバリ・アルゴリズム

今回のプログラムのロジックは、以下の4ステップで構成します。

1. 探索(Scan): 指定されたディレクトリ内の `.sv$` ファイルをすべて洗い出す。
2. 選別(Identify): 更新日時(LastModified)を比較し、最も新しいファイルを特定する。
3. 検証(Verify): そのファイルが「本当に救う価値があるものか」を判定する。
4. 復元(Restore): ファイル名を `.dwg` に書き換え、AutoCADで開く。

3. 実装:リカバリ・エンジン・コード

ここでは、初心者の方でも扱いやすいよう、参照設定の手間を省いた「レイトバインディング(遅延結合)」方式で記述します。これをそのまま標準モジュールに貼り付けてみてください。

Option Explicit

''' <summary>
''' 指定したフォルダ内の最新のオートセーブファイル(.sv$)を探し、
''' 元のファイル名として復元を試みるメインルーチン
''' </summary>
Sub RecoverLastAutoSave()
    Dim fso As Object
    Dim targetFolder As String
    Dim fileItem As Object
    Dim latestFile As Object
    Dim latestDate As Date
    Dim recoveredPath As String
    Dim originalName As String
    
    ' --- 1. 初期設定 ---
    ' 本来はクラッシュした図面のパスを指定すべきですが、
    ' 今回はデモとして、現在開いている図面のパス、または作業ディレクトリを指定します。
    ' クラッシュ時は図面が開けないため、ユーザーにフォルダを選択させるのが実務的です。
    
    targetFolder = GetFolderViaDialog() ' フォルダ選択ダイアログを呼び出し
    If targetFolder = "" Then Exit Sub ' キャンセルされた場合
    
    ' FileSystemObjectの生成 (FileSystemObjectはファイル操作の「重み」を扱うための強力な武器)
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    latestDate = #1/1/1900# ' 初期値として極めて古い日付を設定
    
    ' --- 2. スキャン・フェーズ ---
    On Error GoTo ErrorHandler
    
    For Each fileItem In fso.GetFolder(targetFolder).Files
        ' 拡張子が ".sv$" であることを確認
        If LCase(fso.GetExtensionName(fileItem.Name)) = "sv$" Then
            ' 最も新しい更新日時を持つファイルを特定
            If fileItem.DateLastModified > latestDate Then
                latestDate = fileItem.DateLastModified
                Set latestFile = fileItem
            End If
        End If
    Next fileItem

    ' --- 3. 復元・フェーズ ---
    If Not latestFile Is Nothing Then
        ' 元のファイル名(拡張子を除いた部分)を取得
        originalName = fso.GetBaseName(latestFile.Path)
        ' 復元先のフルパスを作成 (.dwg に変更)
        recoveredPath = targetFolder & "\" & originalName & "_Recovered.dwg"
        
        Debug.Print "発見された最新のバックアップ: " & latestFile.Path
        Debug.Print "復元日時: " & latestFile.DateLastModified
        
        ' ファイルをコピーして復元(元の.sv$を壊さないための安全策)
        fso.CopyFile latestFile.Path, recoveredPath, True
        
        MsgBox "リカバリ成功!" & vbCrLf & _
               "ファイル名: " & originalName & "_Recovered.dwg" & vbCrLf & _
               "更新日時: " & latestDate, vbInformation, "Recovery Complete"
               
        ' 復元したファイルをAutoCADで開く
        ThisDrawing.Application.Documents.Open recoveredPath
    Else
        MsgBox "対象となる .sv$ ファイルが見つかりませんでした。", vbExclamation, "No Backup Found"
    End If

    Set fso = Nothing
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "Critical Error"
    Set fso = Nothing
End Sub

''' <summary>
''' ユーザーにフォルダを選択させる補助関数
''' </summary>
Function GetFolderViaDialog() As String
    Dim shellApp As Object
    Set shellApp = CreateObject("Shell.Application")
    ' BrowseForFolder(Window, Title, Options, Root)
    ' ※簡易的な実装のため、標準のフォルダ選択を利用
    With shellApp.BrowseForFolder(0, "スキャン対象のフォルダを選択してください", 0)
        If Not .Self Is Nothing Then
            GetFolderViaDialog = .Self.Path
        Else
            GetFolderViaDialog = ""
        End If
    End With
End Function

4. コードの深層解説:なぜこう書くのか?

ここからは、単なるコードの書き写しではない、エンジニアとしての「思考プロセス」を解説します。

① なぜ `FileSystemObject` (FSO) を使うのか?

VBA標準の `Dir` 関数は高速ですが、ファイルの「更新日時」や「属性」といった詳細なメタデータを取得するのが苦手です。プロフェッショナルは、オブジェクトのライフサイクル(いつ作られ、いつ更新されたか)を正確に把握するために、`Scripting.FileSystemObject` を選択します。これは、OSレベルのファイル操作を制御するための「重い」しかし「信頼できる」道具です。

② 「上書き」ではなく「コピー」という設計思想

コード内で `fso.CopyFile` を使っています。これは非常に重要です。もし、復元に失敗したり、ファイルが破損していたりした場合、元の `.sv$` ファイルまで書き換えてしまっていたら、二度と復旧できなくなります。「元データを保護しつつ、新しい成果物を作る」。これが、堅牢なシステムを設計する際の鉄則です。

③ 例外処理(Error Handling)の重要性

`On Error GoTo ErrorHandler` を忘れてはいけません。ファイルが他のプロセス(AutoCAD自身など)によってロックされている場合、プログラムは即座にクラッシュします。エンジニアの仕事は、正常な動作を書くことではなく、「異常な状態が起きた時に、いかに優雅に(Gracefully)立ち振る舞うか」にあります。

5. 次のステップへ:ここをクリアすれば基本はバッチリ!

このツールを使いこなせるようになったら、あなたはもう「マクロを記録するだけの人」ではありません。

  • 応用編1: 復元したファイルを自動的に特定のサーバーへバックアップする機能。
  • 応用編2: `.sv$` ファイルだけでなく、`.bak` ファイルも比較対象に含め、両方の整合性をチェックする機能。
  • 応用編3: クラッシュ履歴をログファイル(.txt)に書き出し、いつ、どのファイルで問題が起きたかを管理する機能。

これらの実装ができるようになれば、あなたはAutoCAD VBAの「マスター」への階段を駆け上がることになります。

「コードは、単なる命令の羅列ではない。それは、エンジニアの知性と、ユーザーへの思いやりを形にしたものである。」

さあ、次はあなたの手で、このリカバリエンジンをさらに進化させてみてください。応援していますよ!

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