【実務・中級編】【上級者向け】Visio図面をPDF出力する際、出力先のPDFが他プロセスで開かれている場合の「リトライ・待機ロジック」 – Visio VBA解析バイブル

スポンサーリンク

Visio VBAの「PDF出力」を極める:ファイルロックを無力化する堅牢な待機ロジック

Visioを用いた自動化において、PDF出力はルーチンワークの要だ。しかし、多くの開発者がこの「単純な出力処理」で膝を屈する。PDFが他プロセス(Acrobatやプレビュー表示)で掴まれたまま、VBAが後続の保存処理を強行し、実行時エラー「-2032466928 (87e20010)」を叩き出して沈没する。

「エラーハンドラで無視すればいい」などと考えるのは、アマチュアの思考だ。本稿では、ファイルシステムとOSの挙動を制御下に置き、確実にPDFを生成するための「リトライ・待機ロジック」の極意を伝授する。

—

なぜ「単純な保存」では通用しないのか

Windowsのファイルシステムは排他的だ。PDF出力コマンド `ExportAsFixedFormat` を叩いた瞬間、OSはファイルハンドルを確保しようとするが、既にファイルがロックされていれば即座に拒絶する。

ここで重要なのは、「いつロックが解除されるか」は予測不能であるという点だ。ユーザーがプレビューを閉じ忘れているかもしれないし、インデックスサービスがバックグラウンドでスキャンしているかもしれない。したがって、開発者が実装すべきは「失敗してもいいから、再試行せよ」という動的待機ロジックである。

—

実装すべき「高信頼性PDF出力ロジック」

単なる `Sleep` は悪手だ。固定待ち時間はシステムの応答性を著しく低下させる。以下は、指数バックオフの概念を取り入れ、タイムアウトまでリトライを繰り返すプロダクションコードだ。

Option Explicit

‘ Windows API: Sleepを使用し、CPU負荷を抑えて待機する
If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As LongPtr)
Else
Private Declare Sub Sleep Lib “kernel32″ (ByVal dwMilliseconds As Long)
End If

”’

”’ ファイルロックを考慮した堅牢なPDFエクスポート
”’

Public Function ExportVisioToPdfRobust(ByVal doc As Visio.Document, ByVal filePath As String) As Boolean
Const MAX_RETRIES As Integer = 5 ‘ 最大リトライ回数
Const WAIT_MS As Long = 1000 ‘ 基本待機時間(ms)
Dim retryCount As Integer
Dim success As Boolean

retryCount = 0
success = False

Do While retryCount < MAX_RETRIES On Error Resume Next ' PDFエクスポート実行 doc.ExportAsFixedFormat visFixedFormatPDF, filePath, _ visDocExIntentPrint, visPrintAll If Err.Number = 0 Then success = True On Error GoTo 0 Exit Do Else ' ここでエラーコードをログ出力すると解析が容易になる Debug.Print "PDF出力失敗 (試行: " & retryCount + 1 & ") Err: " & Err.Description Err.Clear On Error GoTo 0 ' 指数バックオフ的待機(試行回数に応じて待機時間を増やす) Sleep WAIT_MS (retryCount + 1) retryCount = retryCount + 1 End If Loop ExportVisioToPdfRobust = success End Function ---

アーキテクトからの設計上の忠告

このコードを実装する上で、以下の3点を肝に銘じてほしい。

1. ファイルハンドルの「完全な解放」を待て

もし同名ファイルが既に開かれている場合、たとえVBAでリトライをかけても、ユーザーが操作している限り成功しない。UI側で「PDFファイルを閉じてからOKを押してください」というダイアログを出す設計(人間との協調)と、このリトライロジックを組み合わせるのが、真に「止まらない」自動化の姿だ。

2. 書き込み権限とパスの正規化

`Environ(“USERPROFILE”)` や `Desktop` を直接指定するのは危険だ。権限不足によるエラーと、ロックによるエラーを取り違えるとデバッグが迷宮入りする。ファイルパスは必ずフルパスで指定し、ディレクトリの存在確認(`Dir`関数)を処理の直前に行うこと。

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

大規模な図面の場合、`ExportAsFixedFormat` 自体に時間がかかる。この処理を走らせる前に、`Application.ScreenUpdating = False` を実行するのは基本だが、PDF出力中はVisioのCOMサーバーが一時的に重い計算を行う。無理なマルチスレッド化やタイマー割り込みは避け、同期処理で確実に完了を待つのが最も安定する。

—

最後に:なぜ「泥臭い実装」が必要なのか

我々のような自動化エンジニアにとって、一番の敵は「たまに失敗する」コードだ。100回中99回成功しても、重要な会議の直前に1回失敗すれば、それはエンジニアの敗北を意味する。

今回示した「リトライ・待機ロジック」は、単なるコードの断片ではない。システムが不安定であることを前提に、それを制御下におくという「設計思想」そのものだ。

あなたのデスクにあるその自動化ツールに、この「不屈のロジック」を組み込んでほしい。それが、世界最高峰のエンジニアとしての最低限の流儀だ。

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