【入門編】【全対象】VSDXの保存処理中にVisioがフリーズするのを防ぐDoEventsと進捗表示 – Visio VBA解析バイブル

スポンサーリンク

こんにちは! Visio VBAの自動化の世界へようこそ。
マクロの記録ボタンを押すだけのステージから一歩進んで、「自分の手でVisioを自在にコントロールしたい」と願うあなたへ、今日はとても実践的で、かつ現場で必ず直面する「大きな壁」を突破する技術をお伝えします。

ここをクリアすれば、Visio VBAの挙動の裏側にある「Visioの呼吸(イベントループ)」が手に取るようにわかるようになりますよ。しっかりついてきてくださいね!

—

巨大なVSDXの保存でVisioが「フリーズ」する絶望感

何百枚ものシェイプが緻密に配置された巨大なネットワーク図や、複雑なプラント図。その労作をVBAで「さあ、保存しよう!」と `ActiveDocument.Save` を実行した瞬間……。

画面が真っ白になり、タイトルバーには「応答なし」の文字。
「あぁ、またフリーズした……。クラッシュして今日の作業が消えたかもしれない」と、冷や汗をかいた経験はありませんか?

Visioは非常に高機能なグラフィックエンジンを持っているがゆえに、ファイルサイズが大きくなると、保存処理の間、画面の描画やユーザーからの入力を完全にシャットダウンしてしまいます。シングルスレッドの宿命ですね。

ユーザーは「止まっているのか、動いているのか」すら分からず、イライラしてタスクマネージャーから強制終了してしまう……。これをスマートに解決するのが、今回テーマにする「DoEventsによる非同期的な制御と進捗(プログレスバー)の表示」です。

—

そもそも `DoEvents` って何をしているの?

プログラミング初学者のうちは、「魔法の呪文」のように見えがちな `DoEvents` 関数。
これの本質は、一言で言うと「Visioに深呼吸をさせる命令」です。

VBAが重い処理(ファイル保存や巨大ループ)を始めると、Visioは他のすべての作業を放棄してその計算に没頭します。そのため、Windowsからの「生きてる?」というシグナル(メッセージ)を無視し続け、結果として「応答なし」と判定されます。

そこで、コードの合間に `DoEvents` を挟むと、VBAは一時的に処理の手を止め、Windowsにコントロールを返します。
これにより、

  • ユーザーが動かしたマウスの動きを検知する
  • 「キャンセル」ボタンが押されていないか確認する
  • 画面のプログレスバーの表示を新しく書き換える

といった「裏で行うべき仕事」を処理する余裕が生まれるのです。

—

実践! ユーザーフォームを使った「フリーズしない保存」の実装

百聞は一見に如かず。実際に動くコードを見ていきましょう。
ここでは、以下の2ステップで実装します。

1. 進捗状況を表示するユーザーフォーム(`frmProgress`)の作成
2. 重い保存処理と `DoEvents` を組み合わせた標準モジュールの記述

ステップ1:ユーザーフォームの準備

VBE(Visual Basic Editor)を開き、新しいユーザーフォーム(名前:`frmProgress`)を追加してください。

  • フォームの中に `Label` コントロールを1つ置き、名前を `lblStatus` にします(進捗メッセージ用)。
  • もう一つ、横長の `Label`(または `Frame`)を置き、名前を `barProgress` にします(これが進捗バーの代わりになります)。

ステップ2:標準モジュールにコードを書く

以下のコードを標準モジュールに貼り付けてください。

Option Explicit

‘ ==============================================================================
‘ 巨大VSDXファイルの安全な保存と、進捗表示を行うプロシージャ
‘ ==============================================================================
Sub SaveDocumentSafelyWithProgress()
Dim targetDoc As Document
Set targetDoc = ActiveDocument

‘ 新規保存などでファイル名がまだない場合のガード
If targetDoc.Path = “” Then
MsgBox “一度手動で名前を付けて保存してから実行してください。”, vbExclamation, “保存エラー”
Exit Sub
End If

‘ 1. 進捗表示用フォームをモードレス(画面を固まらせない形式)で表示
Dim progForm As frmProgress
Set progForm = New frmProgress
progForm.Show vbModeless
progForm.lblStatus.Caption = “保存の準備を行っています…”
progForm.barProgress.Width = 0

‘ 2. 画面の自動更新を停止(描画コストをカットして高速化)
Application.ScreenUpdating = False

On Error GoTo ErrorHandler

‘ — 擬似的に進捗を刻みながら保存処理を行うステップ —
‘ ※Visioの標準Saveメソッドは一瞬で実行されるため、大きな図面での
‘ 「データ整理・最適化」のフェーズを模したループと組み合わせます。

progForm.lblStatus.Caption = “図面データを最適化中… (1/3)”
progForm.barProgress.Width = 50 ‘ 50ピクセル進むイメージ
DoEvents ‘ ← ここでVisioに呼吸をさせ、「応答なし」を防ぐ!

‘ (もしここで独自の複雑なシェイプ操作やデータ処理があれば挟む)

progForm.lblStatus.Caption = “ディスクへの書き込み中… (2/3)”
progForm.barProgress.Width = 120
DoEvents

‘ 実際の保存実行
targetDoc.Save

progForm.lblStatus.Caption = “保存を完了しています… (3/3)”
progForm.barProgress.Width = 200
DoEvents

‘ わずかに完了の余韻を見せるためのウェイト(必要に応じて)
Dim startTime As Double
startTime = Timer
Do While Timer < startTime + 0.5 DoEvents Loop ' 後片付け Unload progForm Application.ScreenUpdating = True MsgBox "図面の保存が正常に完了しました!", vbInformation, "完了" Exit Sub ErrorHandler: ' エラー時の後片付け On Error Resume Next Unload progForm Application.ScreenUpdating = True MsgBox "保存中にエラーが発生しました: " & Err.Description, vbCritical, "エラー" End Sub ---

ここでエンジニアとして伝授したい「重要なお約束」

上記のコードで、`DoEvents` と並んで非常に重要な役割を果たしているのが、この行です。

Application.ScreenUpdating = False

Visioは、VBAからシェイプが1つ変更されるたび、あるいはプロパティが書き換わるたびに、「画面を再描画せねば!」と裏で必死にグラフィックボードを叩きます。これがマクロを劇的に遅くする最大の原因です。
「重い処理の直前で画面更新を止め、終わったら `True` に戻す」。これはプロのVisio VBAプログラマにとって常識中の常識です。

⚠️ 注意点:`DoEvents` の魔力に溺れるな

`DoEvents` は救世主ですが、諸刃の剣でもあります。
`DoEvents` を挟むと、ユーザーが再びVisioを操作できるようになります。つまり、「保存処理の真っ最中に、ユーザーが別のシェイプを削除したり、もう一度ボタンを押してしまうリスク」が生まれます。

これを防ぐために、実務では以下のような対策を組み合わせます。

  • 処理中はフォーム以外の操作を受け付けない工夫をする
  • 2重クリックを防ぐためのフラグ変数(`isSaving As Boolean` など)を用意する

—

まとめ:ここをクリアすればVisio VBAは怖くない!

今回は、VSDX保存時のフリーズを防ぐための `DoEvents` と進捗表示のテクニックを解説しました。

  • 「応答なし」の正体は、VisioがCPUを独占してWindowsの声を聞けなくなっている状態。
  • `DoEvents` を挟むことで、Visioに「深呼吸(イベント処理)」をさせ、フリーズを防ぐ。
  • `Application.ScreenUpdating = False` との合わせ技で、高速かつスマートなUIを実現する。

このパターンをマスターすれば、ただ動くだけのプログラムから、「ユーザーに優しい、プロフェッショナルなツール」へとあなたのVBAスキルは大きく飛躍します。

ここをクリアできれば、Visio VBAの基本構造はもうバッチリです!
ぜひ、あなたの現場の巨大な図面ファイルで試してみてくださいね。次回の解説もお楽しみに!

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