Access VBAの「画面フリーズ事故」を撲滅せよ:`Application.Echo`を安全に操るクラス設計術
こんにちは。Accessの深淵へようこそ。
Access VBAで大量のデータを処理する際、`Application.Echo False`を使って画面描画を停止させ、速度を劇的に向上させるテクニックは「基本のキ」です。しかし、この手法には「エラー発生時に画面が真っ白のまま固まり、ユーザーが操作不能になる」という致命的なリスクが潜んでいます。
今回は、このリスクを根本から断ち切るための「`Application.Echo`制御クラス」を設計します。ここをマスターすれば、あなたの書くコードは「堅牢なプロのツール」へと一歩進化します。
—
なぜ `Application.Echo` は危険なのか?
`Application.Echo False` を実行すると、Accessは画面更新を停止し、処理速度を優先させます。しかし、もし処理中にエラーが発生して `End` ステートメントでプログラムが終了したり、未処理の例外で止まったりするとどうなるでしょうか?
Accessは「描画停止」の命令を抱えたまま停止します。 結果として、フォームやデータシートが更新されず、ユーザーは「Accessがフリーズした」と誤解してタスクマネージャーで強制終了する羽目になります。
これを防ぐ唯一の正攻法が、「クラスの終了処理(Terminate)」を自動発火させる仕組みです。
—
「自動復帰」を実現する `clsScreenControl` クラス
VBAのクラスモジュールには、そのオブジェクトがメモリから消える瞬間に必ず実行される `Class_Terminate` という魔法のイベントがあります。これを利用し、「処理が終わったとき(正常終了でもエラー終了でも)」に必ず描画を戻す仕組みを作ります。
1. クラスモジュールの作成
VBAエディタで「挿入」→「クラスモジュール」を選択し、名前を `clsScreenControl` としてください。
‘ — クラス名:clsScreenControl —
Option Compare Database
Option Explicit
‘ クラスが生成された瞬間に画面描画を止める
Private Sub Class_Initialize()
Application.Echo False
End Sub
‘ クラスが破棄される瞬間に画面描画を戻す
‘ これにより、エラーで処理が中断されても確実に画面は復帰する
Private Sub Class_Terminate()
Application.Echo True
End Sub
これだけで、`Application.Echo` の管理を「状態」から「オブジェクトの生存期間」へと昇華させることができました。
—
実際に使ってみる:劇的にシンプルになるメイン処理
では、このクラスをどう使うのか。実務的なコードで見てみましょう。
Sub UpdateDatabaseProcess()
‘ クラスをインスタンス化(ここで描画が停止する)
Dim sc As New clsScreenControl
On Error GoTo ErrorHandler
‘ ここに重い処理を記述
‘ 例:大量の更新クエリやループ処理
Debug.Print “重い処理を実行中…”
‘ 意図的なエラーテスト(コメントアウトして試してみてください)
‘ Err.Raise 999
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しましたが、画面描画は自動的に復旧しています。” & vbCrLf & _
“エラー内容: ” & Err.Description
‘ ここで End や Exit Sub しても、sc変数が破棄される瞬間に
‘ Class_Terminate が呼び出され、Echo が True に戻る!
End Sub
—
ここがポイント:なぜこれで解決するのか?
初心者が陥りやすい罠は、「`On Error` でジャンプした先で `Echo True` を書き忘れること」です。
しかし、このクラスを使うと:
1. `Sub` が終わる(正常終了・エラー終了問わず)
2. ローカル変数である `sc` がメモリから解放(破棄)される
3. `Class_Terminate` が自動的に発火し、`Application.Echo True` が実行される
「コードの書き忘れ」という人間由来のバグを、言語仕様の力で封殺しているのです。 これが、伝説的なアーキテクトが好む「自己完結型の設計」です。
—
さあ、次のステップへ
今回のコードは、さらに応用が効きます。
- `DoCmd.Hourglass`(砂時計カーソル)の制御も `Class_Initialize` に追加すれば、処理中ずっと砂時計を表示し、終われば自動で戻すことができます。
- `Application.SetOption “Confirm Action Queries”, False` を組み込めば、アクションクエリの警告ダイアログの抑制・復帰も自動化できます。
Access VBAは、このように「オブジェクトのライフサイクル」を意識するだけで、驚くほど洗練された動作を実現できます。「マクロの記録」の先にある、安定したシステム構築の世界へようこそ。
あなたの開発現場が、このコードで少しでも快適になりますように。また次の技術でお会いしましょう。
