【Visio VBA掌握】データ消失をゼロにする——「自動回復」制御と堅牢なバックアップ戦略
ビジネスの現場において、プログラムの異常終了や予期せぬクラッシュで数時間の作業が水泡に帰すことほど愚かなことはありません。特にVisioは、複雑なシェイプの接続や大量のデータリンクを扱うため、メモリ消費が激しく、VBAの書き方一つで不安定になりやすいアプリケーションです。
「自動保存の設定はしてあるから大丈夫」……もしあなたがそう考えているなら、それはチーフアーキテクトとしては「甘い」と言わざるを得ません。
今回は、Visioの標準機能である「自動回復(AutoRecover)」をVBAから完全に制御し、さらに独自の「チェックポイント保存」を実装することで、いかなる事態でもデータを守り抜く堅牢な設計手法を伝授します。
—
1. なぜ「標準の自動保存」だけでは不十分なのか
Visioには `Application.AutoRecoverInterval` というプロパティが存在します。これは分単位で自動回復用の情報を保存する設定ですが、VBA開発者が知っておくべき「落とし穴」が2つあります。
1. マクロ実行中のブロッキング: 大規模なループ処理や複雑な図面生成を行っている最中、Visioの標準自動保存タイマーはしばしば無視されるか、あるいは保存処理そのものがマクロと競合してエラーの原因になります。
2. 「回復」であって「保存」ではない: 自動回復ファイル(.iniやテンポラリファイル)は、正常終了時には削除されます。つまり、論理的なバグで図面が破壊された状態で「保存」してしまった場合、過去の正常な状態には戻せません。
結論: プロフェッショナルなツールを作るなら、システムの自動機能に依存せず、VBA側で「保存のライフサイクル」を設計に組み込む必要があります。
—
2. Visioの自動回復設定をVBAで最適化する
まず、環境設定をプログラムから制御する方法を押さえます。ユーザーの設定に依存せず、実行時に最適なインターバルを強制します。
自動回復インターバルの制御
Sub OptimizeAutoRecoverSettings()
‘ 自動回復の間隔を10分に設定(0を指定すると無効化)
‘ 実務上、5分〜10分がパフォーマンスと安全性のバランスが良い
On Error Resume Next
Application.AutoRecoverInterval = 10
‘ 設定が反映されたかログ出力(デバッグ用)
Debug.Print “AutoRecover Interval set to: ” & Application.AutoRecoverInterval & ” minutes”
On Error GoTo 0
End Sub
この設定は `Application` レベル(Visio全体)に影響するため、ツール開始時に設定し、終了時に元の値に戻すのがマナーですが、基本的には「10」程度の安全圏で固定運用するのが定石です。
—
3. 堅牢な「チェックポイント保存」の実装
次に、作業中のファイルを保護するための「世代管理バックアップ」の手法を導入します。これは、既存のファイルを上書きするのではなく、特定のタイミングで「別名保存」を実行するロジックです。
失敗しない保存ロジックの3原則
1. パスの存在確認: 保存先ディレクトリが存在するか必ず確認する。
2. 排他制御の考慮: ファイルが既に開かれていないか、書き込み権限があるかをチェックする。
3. パフォーマンスの考慮: 1シェイプ描画ごとに保存してはいけない。処理の「区切り(トランザクションの終了)」で実行する。
実践コード:タイムスタンプ付きバックアップ
”
‘ @description 作業中のドキュメントをタイムスタンプ付きでバックアップ保存する
‘ @param targetDoc 対象のDocumentオブジェクト
”
Public Sub CreateSafetyBackup(ByRef targetDoc As Visio.Document)
Dim backupPath As String
Dim timeStamp As String
Dim folderPath As String
On Error GoTo ErrorHandler
‘ 1. 保存先パスの構築(元のファイルと同じディレクトリの「Backup」フォルダ)
If targetDoc.Path = “” Then
‘ 未保存の新規ファイルの場合はドキュメントフォルダ等へ
folderPath = Environ(“USERPROFILE”) & “\Documents\Visio_Temp_Backup\”
Else
folderPath = targetDoc.Path & “Backup\”
End If
‘ フォルダが存在しない場合は作成
If Dir(folderPath, vbDirectory) = “” Then
MkDir folderPath
End If
‘ 2. タイムスタンプ生成 (yyyyMMdd_HHmmss)
timeStamp = Format(Now, “yyyyMMdd_HHmmss”)
‘ 3. ファイル名の構築(拡張子は元のファイルに合わせる)
‘ 例: MyDrawing_20231027_153000.vsdx
backupPath = folderPath & Left(targetDoc.Name, InStrRev(targetDoc.Name, “.”) – 1) & _
“_” & timeStamp & “.vsdx”
‘ 4. 別名でコピーを保存 (SaveAsCopy を使用するのがコツ)
‘ SaveAs だと作業中のファイルそのものが切り替わってしまうが、
‘ SaveAsCopy は現在の作業状態をスナップショットとして別ファイルに書き出すだけ
targetDoc.SaveAsCopy backupPath
Debug.Print “Backup created: ” & backupPath
Exit Sub
ErrorHandler:
‘ 保存失敗でメイン処理を止めてはいけない。ログ出力に留めるのがプロの設計。
Debug.Print “Backup failed: ” & Err.Description
End Sub
—
4. 大規模処理における「安全な自動保存」の組み込み方
数千個のシェイプを生成するような自動化ツールでは、処理の途中でクラッシュするとダメージが甚大です。以下のように、一定件数ごとに保存を実行する「バッチ処理パターン」を推奨します。
Sub MassDrawingProcess()
Dim i As Long
Dim doc As Visio.Document
Set doc = ActiveDocument
Const SAVE_INTERVAL As Long = 100 ‘ 100ステップごとに保存
On Error GoTo Finalize
‘ パフォーマンス向上のため画面更新停止
Application.ScreenUpdating = False
For i = 1 To 1000
‘ — ここに複雑な描画ロジック —
Call DummyDrawingTask(i)
‘ 指定間隔ごとにバックアップを実行
If i Mod SAVE_INTERVAL = 0 Then
‘ ユーザーにストレスを与えないようDoEventsでOSに制御を戻す
DoEvents
Call CreateSafetyBackup(doc)
‘ メインファイルも上書き保存してメモリをリフレッシュ
doc.Save
End If
Next i
Finalize:
Application.ScreenUpdating = True
If Err.Number <> 0 Then
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End If
End Sub
—
5. アーキテクトが教える「運用の極意」
ファイルパスの「深すぎ問題」を回避せよ
Windowsのパス長制限(260文字)は、VBAでも依然として敵です。バックアップフォルダを深く作りすぎると、`SaveAsCopy` でエラーを吐きます。バックアップ先は可能な限り浅い階層か、相対パスで管理することを徹底してください。
PDF出力との連携
「保存」とセットで「PDF出力」を自動化する要望も多いでしょう。しかし、PDF出力はVisioの印刷エンジンを回すため、非常に重い処理です。バックアップのたびにPDFを出すのではなく、「最終保存(Complete)」のタイミングのみに限定すべきです。
データベース連携時の注意
データベースから取得した値をシェイプに流し込んでいる最中に保存を行う場合、`Recordset` が開いたままだとファイルI/Oに負荷がかかる場合があります。保存の直前には、可能な限りデータ接続をクローズするか、メモリ上の配列にデータを展開してから描画・保存サイクルに入るのが、クラッシュを避ける鉄則です。
まとめ
Visio VBAにおける「保存」は、単なるメソッドの呼び出しではありません。それはユーザーの資産を守るための設計思想そのものです。
1. `AutoRecoverInterval` で最低限の保険をかける。
2. `SaveAsCopy` を活用し、作業を止めずにスナップショット(世代バックアップ)を残す。
3. 大量処理では `Mod` 演算子を使い、適切なインターバルで保存を差し込む。
この3点を守るだけで、あなたの作成するツールの信頼性は劇的に向上します。泥臭いバックアップ処理をエレガントに実装してこそ、真のエンジニアです。
