【入門編】【初心者】Application.Echoを制御する汎用クラス:エラー発生時でも画面描画を確実に復帰させる – Access VBA解析バイブル

スポンサーリンク

こんにちは!Access VBAの開発現場で、日夜データと格闘お疲れ様です。
先輩エンジニアの私です。

マクロの記録から一歩踏み出し、自らVBAを書き始めると、こんな壁にぶつかりませんか?

「大量のデータを処理しているとき、画面がバババッと激しく点滅して、なんだか動作も遅い気がする…」

そう、Accessは処理のたびに画面(フォームやクエリの実行結果など)を一生懸命再描画しようとするため、画面がちらつき(フリッカー)、パフォーマンスも低下します。これをピタッと止めてくれるのが、魔法の呪文`Application.Echo False`です。

「画面を描画しないで処理だけしてね!」とAccessにお願いするこのメソッド、処理速度が劇的に上がり、見た目もスマートになります。

しかし!ここにAccess VBA開発者が必ず一度はハマる「魔の罠」があります。

今回は、初心者の方が絶対に知っておくべき「Echoの恐怖」と、それを美しく、そして絶対に安全に回避する「汎用クラスモジュール」の設計思想を、優しく、かつ本質的に伝授します。ここをクリアすれば、あなたのVBAスキルはワンランク上のステージに到達しますよ!

1. 画面描画を止める `Application.Echo` の光と闇

まずは基本のおさらいです。
Accessで大量のレコードを更新したり、複数のクエリを連続して実行したりするとき、以下のようにコードを書きますよね。

Sub Sample_WithoutEcho()
‘ 画面の描画を停止!
Application.Echo False

‘ — ここに重い処理を書く —
‘ 例: 大量のデータ更新クエリの実行など
DoCmd.SetWarnings False
DoCmd.OpenQuery “qAppend_MonthlyData”
DoCmd.SetWarnings True
‘ —————————-

‘ 画面の描画を復帰!
Application.Echo True
MsgBox “処理が完了しました!”, vbInformation
End Sub

素晴らしい!これを使えば、画面のチラつきが消え、処理スピードも向上します。
……が、プログラミングの神様はそんなに甘くありません。

初心者が陥る「画面が二度と戻らない」ホラー現象

もし、上記の「重い処理」の最中に、予期せぬエラー(例えば、参照先データがない、主キーが重複した、など)が発生したらどうなるでしょうか?

VBAはエラーで強制停止します。その瞬間、コードの実行はストップするため、`Application.Echo True`(画面を戻すコード)が一生実行されません。

結果どうなるか?

  • Accessの画面が真っ白、あるいは最後の画面でフリーズしたようになる。
  • マウスを動かしても反応が鈍い(実際は裏で動いているか、操作を受け付けなくなっている)。
  • 最悪の場合、Accessを強制終了するしかない。

現場でこれやると、ユーザーから「なんかAccessが壊れました!」と青ざめた顔で駆け寄られることになります。これが、`Application.Echo` の恐ろしい「闇」です。

2. エラーが起きても絶対に復帰させる!「クラス」という防波堤

「じゃあ、エラー処理(`On Error GoTo`)を毎回書けばいいんでしょ?」
そう思ったあなた、鋭いですね。確かに各プロシージャの最後にエラー処理を書く手もありますが、何十個もあるプロシージャに毎回同じボイラープレート(お決まりのコード)を書くのは、エンジニアとしてスマートではありません。

ここで登場するのが、「クラスモジュール」です!

「クラスって何?難しそう……」と思った方、大丈夫です。
今回は、『生まれた瞬間にEchoを止め、消滅する瞬間に自動的にEchoを戻してくれる頼もしい用心棒』という役割を持つクラスを作ります。

VBAのオブジェクトには「ライフサイクル(生成されてから消滅するまでの寿命)」という概念があります。これを利用すると、「エラーが起きようが、途中でマクロが強制終了しようが、メモリから消える時に必ず後片付けをしてくれる」という強固な仕組みが作れるのです。

3. 実装:汎用Echo制御クラス(`clsScreenLock`)の作成

百聞は一見にしかず。実際にコードを書いてみましょう。

手順1:クラスモジュールの追加

1. VBAエディタ(VBE)を開きます。
2. メニューの [挿入] > [クラス モジュール] をクリックします。
3. プロパティウィンドウで、このモジュールの名前を `clsScreenLock` に変更します。

手順2:コードの記述

以下のコードを、新しくできた `clsScreenLock` の中に丸ごとコピー&ペーストしてください。

Option Explicit

‘ =================================================================
‘ クラス名: clsScreenLock
‘ 概要: 画面描画(Echo)を制御し、エラーや終了時に確実に復帰させる汎用クラス
‘ =================================================================

‘ クラスが初期化された(生まれた)時に実行されるイベント
Private Sub Class_Initialize()
On Error GoTo ErrorHandler

‘ 画面の描画を停止し、ステータスバーにメッセージを表示
Application.Echo False, “処理を実行中です。しばらくお待ちください…”
Exit Sub

ErrorHandler:
‘ 万が一初期化時にエラーが出た場合は描画を強制復帰
Application.Echo True
MsgBox “画面制御の初期化に失敗しました: ” & Err.Description, vbCritical
End Sub

‘ クラスが破棄された(消滅する)時に実行されるイベント
Private Sub Class_Terminate()
On Error Resume Next

‘ 【超重要】どんな状況であれ、このクラスがメモリから解放される瞬間、
‘ 必ず画面描画を元の状態(True)に戻す!
Application.Echo True

‘ ステータスバーをクリア
SysCmd acSysCmdClearStatus

On Error GoTo 0
End Sub

たったこれだけです!
このクラスのミソは `Class_Terminate` という特別なイベント。VBAでは、このモジュールの変数が役割を終えて消える時、エラーの有無に関わらず100%このコードが実行されます。 つまり、消滅の瞬間に必ず画面が復帰する仕組みというわけです。

4. 現場での使い方:驚くほどシンプルで安全なコード

では、先ほど作った用心棒クラスを、実際の業務ロジックでどのように使うのかを見てみましょう。標準モジュールに以下のように書きます。

Sub ExecuteHeavyProcess()
‘ 1. 用心棒クラスの変数を宣言する
Dim screenLock As clsScreenLock

‘ 2. クラスの実体を生成する(ここで自動的に Echo False になる!)
Set screenLock = New clsScreenLock

‘ — ここからメインの処理(エラーが起きても怖くない!) —

‘ わざとエラーが起きそうな処理や、時間のかかる処理を書く
DoCmd.SetWarnings False

‘ 例としてクエリを実行
DoCmd.OpenQuery “qUpdate_CustomerStatus”

‘ もしここで何らかのエラーが発生して処理が止まっても……
‘ このプロシージャを抜ける瞬間に screenLock 変数メメモリから消えるため、
‘ 自動的に clsScreenLock の Terminate が発動し、画面は必ず元に戻ります!

DoCmd.SetWarnings True
‘ ——————————————————–

‘ 3. 正常終了時のメッセージ
MsgBox “すべての処理が正常に完了しました!”, vbInformation

‘ (※変数 screenLock はプロシージャ終了時に自動破棄されます)
End Sub

この書き方の何がスゴいのか?

1. `Application.Echo True` を書き忘れることが物理的に不可能になる
コードの途中で `Exit Sub` で抜けようが、予期せぬエラーで止まろうが、変数 `screenLock` の寿命が尽きた瞬間に安全装置が作動します。
2. コードの見通しが圧倒的に良くなる
「画面を止める」「戻す」という定型作業をクラスに丸投げできるため、肝心のビジネスロジック(データの処理)だけに集中できます。

5. 先輩エンジニアからのメッセージ

今回は、Access VBAにおける `Application.Echo` のリスクと、それをオブジェクト指向的なアプローチ(クラスモジュール)でエレガントに解決する方法を解説しました。

「マクロの記録」から抜け出した初学者の壁は、「エラーが起きたときの後始末(例外処理とリソースの解放)」をいかにスマートに記述できるかにあります。

ここをクリアできたあなたは、単なる「VBAのコードを繋ぎ合わせた人」から、「堅牢なシステムを設計できるエンジニア」へと確実にステップアップしています。

ぜひ、あなたの開発するAccessデータベースにこの `clsScreenLock` を組み込んで、快適で安全な自動化ライフを手に入れてくださいね。それでは、次の開発現場でお会いしましょう!

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