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

スポンサーリンク

【Visio VBA極意】PDF出力の「ファイルロック問題」を完全制圧するリトライ・待機ロジック

こんにちは。業務自動化の現場で、Visioの図面と格闘し続けている皆さんに、一つお聞きしたいことがあります。

「PDF書き出しの途中で『ファイルが使用中です』とエラーが出て、マクロが止まってしまったことはありませんか?」

これ、自動化エンジニアにとって「あるある」ですが、放置してはいけない致命的な問題です。特に、生成したPDFを即座にメール送信したり、共有フォルダへコピーしたりする自動化パイプラインにおいて、このエラーは天敵。

今回は、単にコードを動かすだけでなく、「外部プロセスの状態をどうハンドリングするか」という、プロのエンジニアが必ず通る「堅牢性」の極意を伝授します。

—

なぜ、PDF出力は失敗するのか?

結論から言うと、「OSのファイルロック」と「Visioの非同期処理(のような挙動)」のタイムラグが原因です。

VBAで `ExportAsFixedFormat` を実行した瞬間、OSはファイルを作成しようとしますが、直前のプロセス(例えば、以前開いていたPDFビューアや、ウイルス対策ソフトのスキャン)がそのファイルを掴んでいると、アクセス権限で弾かれます。

ここで「マクロを一度止めて、手動でリトライ」しているうちは、まだ初級者。今回は、「ファイルが空くまで粘り強く待機し、それでもダメなら潔く諦める」というインテリジェントなロジックを実装します。

—

堅牢なPDF書き出しロジックの全貌

まずは、以下のコードをご覧ください。これが「現場で生き残るためのコード」です。

Option Explicit

‘ PDF出力の最大待機時間(秒)
Private Const MAX_WAIT_TIME As Integer = 10

Public Sub ExportVisioToPdfRobust(doc As Visio.Document, outputPath As String)
Dim startTime As Single
Dim isSuccess As Boolean

startTime = Timer
isSuccess = False

‘ 1. ファイルがロックされているか確認しつつリトライ
Do While Timer – startTime < MAX_WAIT_TIME On Error Resume Next ' エラーを一旦無視してファイル開閉テスト ' ファイルが開けるか試す(排他制御の確認) Dim fNum As Integer fNum = FreeFile Open outputPath For Append As #fNum Close #fNum If Err.Number = 0 Then ' ロックが解除された!書き出し開始 On Error GoTo 0 doc.ExportAsFixedFormat visFixedFormatPDF, outputPath isSuccess = True Exit Do End If On Error GoTo 0 DoEvents ' OSに制御を戻し、CPU負荷を抑える(重要!) Loop ' 2. 結果の判定 If isSuccess Then MsgBox "PDF出力が完了しました:" & outputPath, vbInformation Else MsgBox "エラー:指定時間は待機しましたが、ファイルがロックされています。", vbCritical End If End Sub ---

コード解説:なぜこの書き方なのか?

1. `Open … For Append` のトリック

これがプロの知恵です。「ファイルが書き込める状態か?」を確認する最も手っ取り早い方法は、実際にファイルを「追加書き込みモード」で開いてみることです。もし他のアプリが掴んでいれば、ここでエラーが発生します。これを利用して、ロック状態を検知しています。

2. `DoEvents` の魔法

このキーワードを忘れると、PCがフリーズしたような状態になります。`DoEvents` は「OSさん、今のうちに他の処理(描画更新やマウス操作など)をやっていいよ」と許可を与えるコマンドです。これをループ内に入れることで、PCを固まらせずにスマートに待機できます。

3. `On Error Resume Next` と `On Error GoTo 0` のセット

エラーが発生することを前提とした処理(今回のようなロック確認)では、一時的にエラーを無視する必要があります。しかし、そのまま放置するのは絶対にNG。必ず `GoTo 0` で通常の「エラー発生時に止まる」モードに戻しましょう。これを怠ると、後続のバグが見抜けなくなります。

—

さらに上のレベルを目指すあなたへ

このコードは、いわば「PDF出力の盾」です。しかし、さらに精度を高めるなら以下の工夫も検討してみてください。

  • 待機間隔の調整: `Sleep` 関数(Windows API)を呼び出し、`DoEvents` の間に数十ミリ秒のインターバルを入れると、よりCPUに優しい挙動になります。
  • ファイルパスの正規化: ファイルパスに特殊文字や、長すぎるパスが含まれていないかを事前にバリデーションする関数を作っておくと、より完璧です。

まとめ:自動化とは「失敗を予測すること」

初心者の方は「コードが動くこと」を目指しますが、熟練のエンジニアは「いかに失敗しても、システムを壊さず、適切に終了できるか」を考えます。

PDFのロック解除を待つという、この小さな工夫一つで、あなたの作ったマクロは「たまにエラーが出る困ったマクロ」から、「夜間に放置しても確実にタスクを完遂する頼れるツール」へと進化します。

ぜひ、あなたの現場のVisioファイルに、この「待機ロジック」を組み込んでみてください。ここをクリアすれば、もうあなたは初心者ではありません。自信を持って、次の自動化の海へ漕ぎ出しましょう!

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