【入門編】【中級者向け】PDF出力中にVisioが応答なしになるのを防ぐためのDoEvents配置と進捗バーの実装 – Visio VBA解析バイブル

スポンサーリンク

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出力だけでなく、大量の図形を整列させたり、外部データベースと連携する際にも応用できる汎用テクニックです。

「プログラムを動かす」段階から、「ユーザーの快適性を守り、堅牢なシステムを作る」段階へ。その一歩を、今日踏み出していただけたなら幸いです。

何か詰まったら、いつでも聞いてください。コードは、論理的に組めば必ず応えてくれます。頑張りましょう!

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