【Visio VBA】画面描画OFFの「死の罠」を回避する。真に堅牢な例外処理設計
Visioの自動化において、`Application.ScreenUpdating = False` を使わない手はない。数万のシェイプを動かす際、これを書くか書かないかで処理速度は100倍変わる。しかし、多くのエンジニアがここで致命的なミスを犯している。
「処理の途中でエラーが発生した際、ScreenUpdatingがFalseのまま放置され、Visioがフリーズ(あるいは描画不能)状態になる」 という悲劇だ。
これは単なるコーディングミスではない。Visioというエンジンの「状態」を制御する責任を放棄しているに等しい。今日は、私が大規模自動化プロジェクトで必ず採用している、「絶対に画面更新を死なせない」ための例外処理パターンを伝授する。
—
なぜ、単純な `On Error GoTo` では不十分なのか
初心者は次のように書く。
‘ 悪い例:典型的な地雷
Application.ScreenUpdating = False
‘ … 複雑な処理 …
Application.ScreenUpdating = True
もし「複雑な処理」の中で実行時エラーが起きると、コードは中断し、`ScreenUpdating = True` に到達することなく終了する。Visioは「更新停止」のフラグを抱えたまま、ユーザーは何も操作できないブラックボックスを手に入れることになる。
これを防ぐには、「どの経路を通っても必ず復旧コードを通る」という構造的な保証が必要だ。
—
「Try-Finally」パターンをVisio VBAで再現する
VBAには本来 `Try-Catch-Finally` 構造はない。だが、ラベルジャンプを駆使することで、物理的に「Finally」ブロックを作り出すことができる。これが、現場で生き残るための「鉄板コード」だ。
堅牢なプロシージャ・テンプレート
Public Sub RobustAutomatedTask()
Dim isScreenUpdating As Boolean
‘ 1. 現在の状態を退避(入れ子呼び出しに対応するため)
isScreenUpdating = Application.ScreenUpdating
‘ 2. 描画OFF
Application.ScreenUpdating = False
On Error GoTo ErrHandler
‘ — ここに本来の業務ロジックを書く —
Call ExecuteComplexLogic
‘ ————————————
CleanExit:
‘ 3. 「Finally」相当の処理:描画を元の状態に戻す
Application.ScreenUpdating = isScreenUpdating
Exit Sub
ErrHandler:
‘ エラーログ出力やユーザーへの通知
Debug.Print “Error: ” & Err.Description
MsgBox “処理中にエラーが発生しました。詳細はログを確認してください。”, vbCritical
Resume CleanExit
End Sub
この設計の3つのこだわり
1. 状態の退避: `Application.ScreenUpdating` を直接 `False` にするのではなく、現在の状態を `Boolean` 変数に保持する。これにより、この関数が他の関数から呼び出されても、元の状態を壊さない。
2. CleanExitラベル: エラーがあろうとなかろうと、必ず `CleanExit` を通過させる。
3. Resumeの活用: `Resume` は単なるエラー復旧手段ではない。終了処理を確実に実行するための「出口へのゲート」として利用する。
—
実務で陥る「ファイル・DB連携」の罠
このパターンを適用しても、外部連携時には別の落とし穴がある。例えば、VisioからExcelやSQL Serverへ書き出す際、「処理の途中でVisio側がエラーで止まったのに、外部リソースへの接続(ロック)が解除されていない」というケースだ。
- 接続のスコープ管理: データベース接続やファイル開閉は、必ず `RobustAutomatedTask` のようなメイン制御関数ではなく、個別の「クリーンアップ処理」を持つオブジェクトに委譲せよ。
- イベントの無効化: `Application.EnableEvents = False` も同様に `ScreenUpdating` とペアで管理すべきだ。大規模なVisioアドインでは、イベントの暴走がメモリリークを引き起こす。
—
アーキテクトからの提言:コードは「状態」を意識せよ
VBAを書くことは、Visioという巨大なオブジェクトグラフを操作することだ。あなたが書いた1行のコードが、Visioの描画エンジンにどのような負荷をかけ、どんな「状態(State)」を残すかを常に想像してほしい。
「動くコード」ではなく「止まらないコード」を書く。
この視点を持つだけで、あなたの書くツールは、単なるマクロから「業務を支えるシステム」へと進化する。まずは、この `ScreenUpdating` 制御パターンをあなたのライブラリの標準テンプレートとして組み込んでみてほしい。
それが、プロのエンジニアとしての第一歩だ。
