【テクニカル・上級編】【初心者向け】Visioの「自動保存」と「回復用ファイル」をVBAで制御し、作業中のデータ消失を防ぐ – Visio VBA解析バイブル

スポンサーリンク

序文:Visioという魔物と対峙するアーキテクトの作法

Visioは、数あるMicrosoft Officeスイートの中でも特異な存在だ。複雑なシェイプ、コネクタの再計算、そして膨大なジオメトリデータ。これらがメモリ空間を圧迫し、不意のクラッシュ(ABEND)を引き起こす様を、私は幾度となく目にしてきた。

初心者は「自動保存があるから大丈夫だ」と高を括る。しかし、真のエンジニアは知っている。VBAによる重厚な自動化処理の最中に、OS標準の自動回復機能が不意に介入することが、どれほど致命的なデッドロックやリソース競合を招くかを。

今回は、Visioの「自動回復(AutoRecover)」をVBAから完全に掌握し、独自の「堅牢なバックアップ戦略」を構築する手法を伝授する。これは単なるコードの書き写しではない。システムの安定稼働を担保するための、設計思想の伝承である。

—

1. 自動回復機能のメカニズムとVBAによる制御

Visioの自動回復機能は、`Application.AutoRecoverInterval` プロパティによって制御される。単位は「分」だ。しかし、大量のシェイプをループで生成している最中にこのインターバルが訪れると、描画エンジンとファイルI/Oが衝突し、パフォーマンスが著しく低下する。

自動回復設定の動的制御

大規模な自動化処理を実行する際は、一時的に自動回復を無効化し、処理の節目で明示的に保存を行うのが定石だ。

‘ — Visio Applicationの状態を完全に制御する —
Public Sub OptimizeVisioEnvironment(ByVal isProcessing As Boolean)
With Application
If isProcessing Then
‘ 処理開始時:自動回復をオフにし、画面更新を止める
.AutoRecoverInterval = 0
.ScreenUpdating = False
.EventsEnabled = False
Else
‘ 処理終了時:自動回復を10分に戻し、画面更新を再開する
.AutoRecoverInterval = 10
.ScreenUpdating = True
.EventsEnabled = True
End If
End With
End Sub

—

2. 「SaveCopyAs」による非破壊的バックアップの極意

`ThisDocument.Save` は、現在作業中のファイルを直接上書きする。しかし、保存処理中に万が一クラッシュした場合、そのファイル自体が破損(Corruption)するリスクがある。

プロフェッショナルは `SaveCopyAs` を選択する。これは、現在開いているドキュメントの状態に影響を与えず、スナップショットとして別ファイルに書き出すメソッドだ。

Windows APIを併用した堅牢なパス生成

バックアップ先として一時フォルダ(Temp)を確保する場合、VBA標準の `Environ` 関数よりも、Windows APIを用いた方が環境依存のトラブルを回避できる。

‘ Windows APIの宣言:一時パス取得
If VBA7 Then
Private Declare PtrSafe Function GetTempPath Lib “kernel32” Alias “GetTempPathA” _
(ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Else
Private Declare Function GetTempPath Lib “kernel32” Alias “GetTempPathA” _
(ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
End If

”’

”’ 現在のドキュメントの安全なスナップショットを作成する
”’

Public Sub CreateResilientBackup()
Dim targetDoc As Visio.Document
Set targetDoc = ActiveDocument

‘ ドキュメントが一度も保存されていない(新規作成直後)場合はスキップ
If targetDoc.Path = “” Then
Debug.Print “Warning: Document has no path. Save it manually first.”
Exit Sub
End If

Dim tempPath As String
tempPath = GetSystemTempPath()

Dim fileName As String
fileName = “Backup_” & Format(Now, “yyyyMMdd_HHmmss”) & “_” & targetDoc.Name

On Error Resume Next
‘ SaveCopyAsにより、現在の作業を妨げずに裏側で保存
targetDoc.SaveCopyAs tempPath & fileName

If Err.Number <> 0 Then
‘ エラーハンドリング:ログ出力や管理者通知を行う
Debug.Print “Backup failed: ” & Err.Description
Else
Debug.Print “Backup created: ” & tempPath & fileName
End If
On Error GoTo 0
End Sub

Private Function GetSystemTempPath() As String
Dim buffer As String 255
Dim length As Long
length = GetTempPath(255, buffer)
GetSystemTempPath = Left(buffer, length)
End Function

—

3. メモリ管理とオブジェクトのライフサイクル

Visio VBAで最も多いクラッシュ原因は、オブジェクトの「解放漏れ」だ。特に `Selection` や `Window` オブジェクト、そして `Page` オブジェクトをループ内で生成し続けると、メモリリークが発生し、やがてVisioは沈黙する。

確実な参照破棄のパターン

「Nothingを代入する」という行為を軽んじてはならない。特にCOMオブジェクトの階層が深いVisioにおいて、これは儀式ではなく義務である。

Public Sub SafeProcessShapes()
Dim vsoPage As Visio.Page
Dim vsoShape As Visio.Shape
Dim i As Long

Set vsoPage = ActivePage

Try
‘ 大量処理のシミュレーション
For i = 1 To vsoPage.Shapes.Count
Set vsoShape = vsoPage.Shapes(i)

‘ ここで複雑な計算やプロパティ変更を行う
‘ 例: vsoShape.Cells(“Width”).Formula = “20mm”

‘ ループ内でも使い終わったオブジェクトは即座に解放
Set vsoShape = Nothing
Next i

Catch:
‘ エラー発生時のロールバック処理などを記述
Finally:
‘ 最後に必ず親オブジェクトを解放
Set vsoPage = Nothing
‘ ガベージコレクションを促す(気休めではない、COMの参照カウントを下げる)
End Try
End Sub

—

4. PDF出力による「視覚的バックアップ」の自動化

データとしてのVSDXの保存も重要だが、システム管理者やエンドユーザーにとって、ある時点の「図面状態」がPDFで残っていることは、最強の回復手段となる。VSDXが破損しても、PDFがあれば情報の再構築が可能だからだ。

”’

”’ 高品質なPDF出力を制御する
”’

Public Sub ExportHighQualityPDF(ByVal targetDoc As Visio.Document)
Dim pdfPath As String
pdfPath = Replace(targetDoc.FullName, “.vsdx”, “.pdf”)

‘ PDF出力設定の最適化
‘ 1: 全ページ出力, 2: 標準品質, 3: 構造タグを含める
On Error GoTo PDFError
targetDoc.ExportAsFixedFormat visFixedFormatPDF, pdfPath, visDocExIntentPrint, visDocExScopeAllDoc

Debug.Print “PDF Export Success: ” & pdfPath
Exit Sub

PDFError:
Debug.Print “PDF Export Failed: ” & Err.Description
End Sub

—

5. 結論:アーキテクトが守るべき一線

初心者は「機能」を実装することに腐心する。しかし、シニアエンジニアは「失敗した後の世界」を設計する。

1. 自動回復に頼らない: `AutoRecoverInterval` はあくまで補助。VBA処理中は自前で `SaveCopyAs` を叩く。
2. リソースを食い潰さない: `Set Object = Nothing` を徹底し、Visioのメモリ空間をクリーンに保つ。
3. 環境を汚さない: Windows APIを活用し、一時ファイルやバックアップの場所を厳密に管理する。

Visio VBAの真髄は、図形を描くことではなく、複雑な図形データという名の「不安定なメモリの塊」をいかに淑やかに飼い慣らすかにある。このコードと設計思想が、貴殿のシステムの堅牢性を一段上の次元へと引き上げることを切に願う。

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