【実務・中級編】【上級者向け】VSDXファイル破損時の自動復旧を試みる、バイナリ構造を考慮したバックアップ・リストア戦略 – Visio VBA解析バイブル

スポンサーリンク

【Visio VBA】VSDX破損の絶望を回避せよ。極限の自動復旧・バックアップ戦略

VisioのVSDXファイルは、その本質が「ZIP圧縮されたXMLパッケージ」であることはご存知だろう。この構造は柔軟だが、同時に書き込み中のプロセス断絶や、メモリ上のオブジェクト整合性崩壊による「破損(Corruption)」という致命的なリスクと隣り合わせだ。

「保存しておけば安心」という認識は甘い。特に自動化スクリプトが複雑化し、大量のシェイプを動的に生成する環境では、Visioのインスタンスが不整合を抱えたままファイルをロックし、二度と開けない死の宣告を受けることが往々にしてある。

本稿では、VBAという制約の中で、いかにして「堅牢な防波堤」を構築するか、その設計思想と実装を伝授する。

—

1. 破損のメカニズムとバックアップの哲学

VSDXが破損する最大の原因は、「Visioがファイルをロックした状態での強制終了」と「未完了のXMLツリー書き込み」にある。

一般的な「名前を付けて保存」を繰り返すコードでは、一時ファイルが消去されないまま残存し、次回の書き込みで競合を引き起こす。真のバックアップ戦略には、以下の3つのレイヤーが必要だ。

  • Transactional Layer: 現在の作業ファイルとは別に、確実に整合性が保たれた「一つ前の正常な状態」を保持する。
  • Integrity Check Layer: ファイルを開く前に、それが論理的に破損していないか(DAOやXML構造の異常検知)を検証する。
  • Automated Recovery Layer: 破損検知時に、自動的にバックアップからリストアし、ログを吐き出す。

—

2. 実装コード:堅牢なバックアップ・リストア・エンジン

以下のコードは、単なるコピーではない。`FileSystemObject`を用いた非同期的なバックアップ生成と、エラーハンドリングによる動的復旧のテンプレートだ。

‘ ———————————————————
‘ Module: Mod_RobustBackup
‘ Description: VSDXの破損を未然に防ぐバックアップ戦略
‘ ———————————————————
Option Explicit

Public Sub SecureSave(ByVal targetDoc As Visio.Document)
Dim fso As Object
Dim backupPath As String
Dim sourcePath As String

Set fso = CreateObject(“Scripting.FileSystemObject”)
sourcePath = targetDoc.FullName
backupPath = sourcePath & “.bak”

On Error GoTo ErrorHandler

‘ 1. 現在のファイルを上書き保存
targetDoc.Save

‘ 2. 保存完了後に即座にバックアップへコピー(版管理)
‘ ファイルがロックされている場合はこの時点でエラーになるため、
‘ エラーハンドラで捕捉する設計にする
fso.CopyFile sourcePath, backupPath, True

Debug.Print “Backup succeeded: ” & backupPath
Exit Sub

ErrorHandler:
MsgBox “バックアップの作成に失敗しました。ディスク容量または権限を確認してください。”, vbCritical
End Sub

Public Function OpenAndVerify(ByVal filePath As String) As Visio.Document
Dim fso As Object
Dim app As Visio.Application

Set fso = CreateObject(“Scripting.FileSystemObject”)
Set app = Application

On Error GoTo RecoveryFlow

‘ ファイルを開く
Set OpenAndVerify = app.Documents.Open(filePath)
Exit Function

RecoveryFlow:
‘ 破損検知時:バックアップからリストアを試みる
If fso.FileExists(filePath & “.bak”) Then
If MsgBox(“ファイルが破損している可能性があります。バックアップから復旧しますか?”, vbYesNo) = vbYes Then
fso.CopyFile filePath & “.bak”, filePath, True
Set OpenAndVerify = app.Documents.Open(filePath)
Else
Err.Raise vbObjectError + 1, , “ユーザーが復旧を拒否しました。”
End If
Else
Err.Raise vbObjectError + 2, , “バックアップファイルが存在しません。手動復旧が必要です。”
End If
End Function

—

3. なぜこの設計なのか:アーキテクトの視点

1. `DoEvents`の呪いを避ける

多くの初心者は、長時間処理中に`DoEvents`を乱用する。これはVisioのイベントキューを汚染し、ファイル保存時の整合性を著しく低下させる。バックアップ処理は、「メインの編集ロジック」と「ファイルIOロジック」を明確に分離せよ。

2. なぜ `.bak` なのか

拡張子を`.vsdx`から変えるのではなく、あえて元の拡張子を維持するか、あるいは`.bak`として分離するかの選択は重要だ。システム管理上、ファイル検索や自動集計ツールに誤認させないためには、`.bak`という明確な識別子を持つことで、自動クリーンアップスクリプトを別途走らせる余地を残すのが定石だ。

3. パフォーマンスへの配慮

大規模な図面ファイルにおいて、`fso.CopyFile`は負荷が高い。本番環境では、ファイルサイズが100MBを超える場合は、バックアップを「定時(例えば30分ごと)」ではなく「差分発生時」に行うか、`Windows API`を用いてI/Oの優先順位を制御することをお勧めする。

—

結論:自動化は「防衛」から始まる

自動化ツールの価値は、その「速度」ではなく「停止しないこと」にある。VBAでVSDXを扱う以上、OSのファイルシステムとの距離は近い。

今回提示したコードをベースに、あなたのプロジェクトの要件に合わせて「エラーログの書き出し(DBやテキストファイルへの追記)」を追加すれば、さらに堅牢性は増すはずだ。

「ファイルはいつか壊れる。だからこそ、壊れた瞬間を最小のコストで無効化する」。 これこそが、我々エンジニアが目指すべきプロフェッショナリズムのあり方である。

さあ、コードを書き換え、今日からあなたのVisio図面を「落ちない資産」へと変貌させよう。

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