【入門編】【上級】ステンシルファイルが破損した際の修復とバックアップ自動生成 – Visio VBA解析バイブル

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

壊れたステンシルに怯えないために —— Visio VBAによる「自動復旧&バックアップ」の極意

こんにちは。現場で設計図や自動化ツールを構築しているエンジニアの皆さん、今日もコードを書いていますか?

Visioを使って大規模な図面を自動生成していると、必ずと言っていいほど直面する「厄介な問題」があります。それは、「自作したステンシルファイル(.vssx)が、何らかの理由で開けなくなる(破損する)」という事態です。

ネットワーク越しの保存失敗、突然のPCフリーズ、あるいはファイル共有の競合……。これらが原因で、昨日まで動いていたマクロが突然「ファイルが見つかりません」や「ファイルが破損しています」と悲鳴を上げ、業務が止まってしまう。これは、ツールを「便利」から「不安定」へと一気に引き下げてしまう致命的なトラブルです。

今日は、そんなトラブルを未然に防ぎ、もし壊れても自動で「バックアップから復旧」させる、プロフェッショナルな堅牢(ロバスト)な運用フローをVBAで実装する方法を伝授します。

「マクロの記録」から一歩踏み出し、システムの「信頼性」を設計するエンジニアの視点を手に入れましょう。

1. なぜ「ただ開くだけ」では不十分なのか?

初学者のうちは、以下のようなコードを書きがちです。

' 初心者レベル:壊れたら止まってしまうコード
Sub SimpleOpen()
    Dim st As Visio.Document
    Set st = Visio.Documents.Open("C:\MyStencil.vssx")
    ' もしここでファイルが壊れていたら、エラーでマクロが強制終了する
End Sub

このコードの最大の問題は、「エラーが発生したときの出口(エラーハンドリング)がない」ことです。

エンジニアとして一段上のステージに立つには、「失敗することを前提とした設計」が必要です。
1. 整合性チェック: ファイルが正常に開けるか確認する。
2. 自動バックアップ: 正常な状態を常に別の場所に保存しておく。
3. 自動復旧: 失敗したら、バックアップを本番ファイルとして上書き・再ロードする。

この3段構えこそが、現場で通用する「プロの設計」です。

2. 実装の全貌:堅牢なステンシル管理エンジン

それでは、実際に使えるコードを見ていきましょう。ここでは、ファイルの操作を強力に行える `FileSystemObject` (FSO) を活用します。

【完全版】ステンシル・ガード・プロトコル

このコードを標準モジュールに貼り付けてください。

Option Explicit

' --- 設定エリア ---
Private Const STENCIL_PATH As String = "C:\Automation\MyCustomStencil.vssx" ' 本番ファイル
Private Const BACKUP_DIR As String = "C:\Automation\Backups\"             ' バックアップ保存先
' ------------------

''' <summary>
''' ステンシルを安全に読み込むメインルーチン
''' </summary>
Sub SafeStencilLoader()
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Dim targetStencil As Visio.Document
    Dim isSuccess As Boolean
    
    Debug.Print "--- ステンシル読み込みプロセス開始 ---"
    
    ' 1. まずは本番ファイルを読み込めるか試みる
    isSuccess = TryOpenStencil(STENCIL_PATH, targetStencil)
    
    If isSuccess Then
        Debug.Print "成功: 本番ステンシルを正常にロードしました。"
    Else
        Debug.Print "警告: 本番ファイルに問題を検知。復旧プロセスを開始します..."
        
        ' 2. 失敗した場合、バックアップを探して復旧を試みる
        isSuccess = AttemptRecovery(fso, targetStencil)
        
        If Not isSuccess Then
            MsgBox "致命的なエラー: バックアップファイルも見つからないか、破損しています。" & vbCrLf & _
                   "手動での復旧が必要です。", vbCritical, "システムエラー"
            Exit Sub
        End If
        Debug.Print "成功: バックアップからの復旧に成功しました。"
    End If
    
    ' 3. 読み込み成功後の処理(例:マスターの取得など)
    MsgBox "ステンシルが準備できました。業務を開始できます。", vbInformation
    
    ' 後片付け(オブジェクトの解放)
    Set targetStencil = Nothing
    Set fso = Nothing
End Sub

''' <summary>
''' ステンシルを開くことを試みる関数(エラーをトラップする)
''' </summary>
Private Function TryOpenStencil(filePath As String, ByRef doc As Visio.Document) As Boolean
    On Error Resume Next ' エラーが起きても次に進む(ここが肝!)
    
    Set doc = Visio.Documents.Open(filePath)
    
    If Err.Number = 0 And Not doc Is Nothing Then
        TryOpenStencil = True
    Else
        ' エラー内容をデバッグ出力
        Debug.Print "エラー発生 (" & Err.Number & "): " & Err.Description
        TryOpenStencil = False
    End If
    
    On Error GoTo 0 ' エラーハンドリングを通常に戻す
    Err.Clear
End Function

''' <summary>
''' バックアップからファイルを復元し、本番ファイルを書き換えるプロセス
''' </summary>
Private Function AttemptRecovery(fso As Object, ByRef doc As Visio.Document) As Boolean
    Dim backupFile As String
    backupFile = BACKUP_DIR & "Backup_Latest.vssx"
    
    ' バックアップが存在するか確認
    If Not fso.FileExists(backupFile) Then
        AttemptRecovery = False
        Exit Function
    End If
    
    ' --- 復旧フロー ---
    ' 1. 壊れた可能性がある本番ファイルを一旦削除(またはリネーム)
    ' ※ここではシンプルに削除してバックアップで上書きします
    On Error Resume Next
    If fso.FileExists(STENCIL_PATH) Then fso.DeleteFile STENCIL_PATH, True
    On Error GoTo 0
    
    ' 2. バックアップを本番のパスにコピー
    fso.CopyFile backupFile, STENCIL_PATH
    
    ' 3. 再度、新しくなった(復旧した)ファイルを読み込む
    AttemptRecovery = TryOpenStencil(STENCIL_PATH, doc)
End Function

''' <summary>
''' 【重要】正常な状態のステンシルをバックアップとして保存する
''' </summary>
Sub CreateManualBackup()
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ' ディレクトリがなければ作成
    If Not fso.FolderExists(BACKUP_DIR) Then
        ' ※実際にはフォルダ作成が必要(簡略化のためここでは存在前提)
    End If
    
    ' 現在開いているステンシルをバックアップとして保存
    ' ※運用上、定期的に実行するか、正常終了時に呼び出すのがベスト
    On Error Resume Next
    Dim doc As Visio.Document
    Set doc = Visio.Documents.Open(STENCIL_PATH)
    
    If Not doc Is Nothing Then
        doc.SaveAs BACKUP_DIR & "Backup_Latest.vssx"
        MsgBox "バックアップを最新状態に更新しました。", vbInformation
    Else
        MsgBox "バックアップ対象のファイルが開けません。", vbExclamation
    End If
    On Error GoTo 0
    
    Set fso = Nothing
End Sub

3. アーキテクトの視点:コードの「重み」を理解する

このコードをただコピペするだけでは、あなたはまだ「使い手」です。「作り手」になるために、なぜこのような書き方をしているのか、その本質を解説します。

① `On Error Resume Next` の正しい使い方

多くの初心者は、エラーを回避するためにこの命令を多用してしまいます。しかし、これは「エラーを無視する」のではなく、「エラーが起きることを予期して、制御下に置く」ために使うものです。
今回の `TryOpenStencil` 関数では、ファイルが開けるかどうかを「判定」するために、あえてエラーを無視して `Err.Number` をチェックしています。これが、エラーを「制御」するということです。

② `FileSystemObject (FSO)` の採用

VBA標準の `Dir` 関数は軽量ですが、ネットワークパスや特殊なファイル属性の扱いに弱いです。`Scripting.FileSystemObject` を使うことで、ファイルの存在確認、削除、コピーといった操作を、より堅牢(プロフェッショナル)に行うことができます。

③ オブジェクトのライフサイクル

コードの最後で `Set doc = Nothing` としている部分に注目してください。Visioのようなメモリを大量に消費するアプリケーションでは、使い終わったオブジェクトを明示的に解放することは、長時間動かし続ける自動化ツールにおいて、「メモリリーク(動作がどんどん重くなる現象)」を防ぐための鉄則です。

4. 陥りやすい罠(トラブルシューティング)

この仕組みを運用する上で、以下の点に注意してください。

  • ファイルロック問題: 他のユーザーがステンシルを開いている最中に、VBAがバックアップを上書きしようとするとエラーになります。運用ルールとして「ステンシル使用中は編集中に閉じてもらう」などの運用設計もセットで考えましょう。
  • 権限の問題: `C:\Automation\` などのフォルダに対して、実行ユーザーに「書き込み権限」があることを必ず確認してください。権限がないと、バックアップ作成時に静かに失敗します。
  • バックアップの世代管理: 今回のコードは `Backup_Latest.vssx` という名前で最新の1つだけを保存していますが、より高度なシステムにするなら、ファイル名に `Format(Now, “yyyymmdd_hhnnss”)` を付けて、日付ごとに保存するように改良しましょう。

最後に:ここをクリアすれば、Visio VBAの基本はバッチリです

「動けばいい」というコードから、「壊れても大丈夫」というシステムへ。

この考え方を持つだけで、あなたの作るツールの価値は劇的に変わります。ユーザー(同僚やクライアント)は、エラーで止まらないツールに対して、絶大な信頼を寄せてくれるはずです。

まずは、小さなプログラムからで構いません。`On Error` を使いこなし、失敗のケースを想定してコードを書いてみてください。その積み重ねが、あなたを伝説的なエンジニアへと導いてくれます。

さあ、次の自動化に向けて、一歩踏み出しましょう!応援していますよ。

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