Visio VBAの「応答なし」を撲滅せよ:PDF出力の進捗を可視化する極意
こんにちは。現場でVisioと格闘する皆さんの「なぜか固まる」「終わるまで祈るしかない」という悩みを解消するために、今日は少しだけ踏み込んだ話をしましょう。
マクロの記録で生成されたコードは便利ですが、あれは「個人の作業」をなぞるだけ。業務で扱う数千の図形をPDF化するような重いタスクにおいて、OSは容赦なく「応答なし(Not Responding)」という死刑宣告を突きつけてきます。
今日は、Visioを「止める」のではなく「対話する」コードへ進化させる、プロの戦術を伝授します。
—
1. なぜVisioはPDF出力中に「固まる」のか?
Visioの `Export` メソッドは非常に強力ですが、実行中はVisioのメインスレッドを完全に占有します。OSから見れば「ウィンドウからの応答がない」状態になるため、Windowsが気を利かせて(あるいは余計なお世話で)「応答なし」と判断するわけです。
これを解決するカギは、「OSに呼吸の隙間を与える」こと。これが `DoEvents` の真髄です。
—
2. ユーザーフォームで「進捗バー」を実装する
まずは、VBAの「ユーザーフォーム(UserForm)」を1つ作成してください。名前は `frmProgress` とし、その中に `lblBar` という名前のラベルを配置します。このラベルの背景色を赤や青にして、幅を動かすことで進捗を表現します。
実装コード:PDF変換の制御ユニット
以下のコードは、単なるPDF出力ではなく、進捗を管理しながら安全に処理を回すためのテンプレートです。
‘ メイン処理:PDF一括出力のエンジニアリング
Public Sub ExportPagesToPDFWithProgress()
Dim i As Long
Dim totalPages As Long
Dim doc As Visio.Document
Dim progressForm As New frmProgress
Set doc = ActiveDocument
totalPages = doc.Pages.Count
‘ プログレスバーの初期化
progressForm.Show vbModeless
progressForm.lblBar.Width = 0
For i = 1 To totalPages
‘ — ここが魔法の鍵 —
‘ OSにメッセージキューを処理させ、フリーズを回避する
DoEvents
‘ 進捗計算(パーセンテージ)
Dim percent As Double
percent = i / totalPages
progressForm.lblBar.Width = 200 percent ‘ 200はフォームの幅
progressForm.Repaint ‘ 再描画を強制
‘ PDFエクスポート処理
‘ ファイル名は適宜変更してください
doc.Pages(i).Export “C:\Output\Page_” & i & “.pdf”
‘ 処理の重みに応じて少しだけ待機時間を設けるのも手
‘ Sleep 100 ‘ API宣言が必要ですが、安定性は向上します
Next i
Unload progressForm
MsgBox “全ページのPDF化が完了しました!”, vbInformation
End Sub
—
3. なぜ `DoEvents` は慎重に使うべきなのか?
「じゃあ、すべてのループに `DoEvents` を入れればいいのか?」というと、それは違います。
- パフォーマンスの代償: `DoEvents` はOSに対して「他の処理があれば先にやっていいよ」と許可を出すコマンドです。あまりに短いループで多用しすぎると、逆に処理速度が劇的に低下します。
- 再入の危険性: `DoEvents` 中にユーザーが「×」ボタンを押すと、マクロの実行途中でフォームが閉じられ、メモリリークや予期せぬエラーが発生します。
解決策: フォームの「閉じるボタン」を無効化する、あるいはフラグ管理で処理の中断を制御する設計が、プロの現場では必須です。
—
4. プロの現場での「鉄則」
初学者のうちはコードを動かすことに精一杯ですが、中級者へステップアップするなら、以下の3点を意識してください。
1. エラーハンドリングの徹底: `On Error GoTo Cleanup` を必ず仕込み、どんなエラーが起きても必ずオブジェクトを解放し、フォームを閉じること。
2. 画面更新の制御: `Application.ScreenUpdating = False` を活用して、PDF出力以外の余計な描画を止めることで、処理速度を向上させます。
3. パスの検証: `Dir()` 関数を使って、保存先のフォルダが存在するか、書き込み権限があるかを処理前にチェックする。ここをサボると、長時間の処理の最後にエラーで落ちるという「悲劇」が待っています。
—
最後に:コードは「生き物」です
Visio VBAは古い言語ですが、その分、設計者の意図がダイレクトに反映される面白い言語です。今回紹介した「進捗バー」と「DoEvents」の組み合わせは、PDF出力だけでなく、大量の図形を整列させたり、外部データベースと連携する際にも応用できる汎用テクニックです。
「プログラムを動かす」段階から、「ユーザーの快適性を守り、堅牢なシステムを作る」段階へ。その一歩を、今日踏み出していただけたなら幸いです。
何か詰まったら、いつでも聞いてください。コードは、論理的に組めば必ず応えてくれます。頑張りましょう!
