こんにちは!Access VBAでの開発、日々お疲れ様です。
マクロの記録から一歩踏み出し、自らコードを書いてシステムを構築する面白さを味わい始めている頃ではないでしょうか。
さて、大量のデータを処理したり、複数のクエリを連続して実行したりするとき、画面がパカパカと激しく点滅したり、余計なウィンドウが切り替わったりしてイライラした経験はありませんか?「なんだか動作も遅い気がする……」と感じる原因の多くは、実は「パソコンが一生懸命、画面の描き替え(描画)を行っているから」なんです。
そんな時に大活躍するのが `Application.Echo` という魔法のメソッドです。これを使えば、処理中の画面描画をピタッと止めて、裏側で高速に処理を終わらせることができます。
しかし、ここにはプロの現場でも時々やらかしてしまう「大きな罠」が潜んでいます。もし描画を止めたままエラーが起きて強制終了してしまったら……?画面が真っ白、あるいはフリーズしたかのような状態で、ユーザーはパニックになってしまいますよね。
今回は、どんな予期せぬエラーが起きても、絶対に画面描画を安全に復帰させる「汎用クラスモジュール」の設計術を、優しく、そして本質的なところまで徹底的に解説します。ここをクリアすれば、あなたの書くAccess VBAは一段とプロフェッショナルな仕上がりになりますよ!
—
1. なぜ `Echo` メソッドの直接使用は危険なのか?
まずは基本からおさらいしましょう。
`Application.Echo False` を実行すると、Accessは画面の更新をストップします。これにより、フォームのちらつきが消え、処理速度が目に見えて向上します。処理が終わったら `Application.Echo True` で元に戻す、というのが基本の使い方です。
しかし、通常のプロシージャ(標準モジュール)で以下のように書くと、どうなるでしょうか?
Sub DangerousProcess()
Application.Echo False ‘ 画面描画を停止
‘ — ここで何らかの重い処理 —
Dim x As Long
x = 1 / 0 ‘ ← 【致命傷】ゼロ除算エラーが発生!
Application.Echo True ; 画面描画を復帰(※ここまで到達しない!)
End Sub
お分かりいただけたでしょうか?
エラーが発生した瞬間、コードの実行は中断され、`Application.Echo True` の行は永遠に実行されません。その結果、Accessの画面は描画が停止したままフリーズしたかのような幽霊状態になり、ユーザーは強制終了せざるを得なくなります。
これを防ぐために標準モジュールでは `On Error Goto ErrorHandler` を毎回書く必要がありますが、正直、すべてのプロシージャにこれを書くのは面倒ですし、書き忘れるリスクもあります。
「ならば、エラーが起きようとも、スコープを抜ける時に確実に描画を復帰させる仕組みを作ればいい!」
そこで登場するのが、オブジェクトのライフサイクルを利用した「Echo制御クラス」です。
—
2. クラスモジュールによるライフサイクル管理の思想
オブジェクト指向のVBAにおける最大の武器、それは「クラスのライフサイクル(インスタンスが生成されてから消滅するまでの流れ)」を制御できることです。
VBAのクラスには、以下の特別なイベントプロシージャが用意されています。
- `Class_Initialize` (インスタンスが生成された瞬間に自動実行される)
- `Class_Terminate` (インスタンスが変数から解放され、消滅する瞬間に自動実行される)
この仕組みを使えば、「クラスを生成した瞬間にEchoをFalseにし、クラスが破棄される瞬間に自動的にEchoをTrueに戻す」という、極めて安全で美しい構造が作れます。これなら、万が一エラーでコードが中断し、VBAが変数を片付ける時(Terminate)でも、確実に画面描画を復帰させることができます。
—
3. 実装:安全なEcho制御クラス(clsSafeEcho)の作成
それでは、実際に手を動かしてクラスを作ってみましょう。
AccessのVBAエディタ(VBE)を開き、[挿入] > [クラス モジュール] を選択してください。
作成したクラスモジュールのプロパティウィンドウで、名前を `clsSafeEcho` に変更します。そして、以下のコードをそのまま貼り付けてください。
‘ ==============================================================================
‘ クラス名: clsSafeEcho
‘ 概要: 画面描画(Echo)を安全に制御し、エラー時でも確実に復帰させるクラス
‘ ==============================================================================
Option Explicit
‘ クラスが初期化された(生まれた)ときの処理
Private Sub Class_Initialize()
‘ 画面描画をストップしてパフォーマンスを向上させる
Application.Echo False
End Sub
‘ クラスが破棄される(消滅する)ときの処理
Private Sub Class_Terminate()
‘ どんな状況であれ、このインスタンスがメモリから消える時に必ず描画を復帰させる
Application.Echo True
End Sub
たったこれだけです!たった数行ですが、ここにAccess VBAの極意が詰まっています。
—
4. 現場で使う:標準モジュールからの呼び出し方
では、先ほど作ったクラスを実際の業務ロジックでどのように使うのかを見てみましょう。
標準モジュールに以下のコードを記述して実行してみてください。
Sub ExecuteAwesomeProcess()
‘ 安全装置付きEchoクラスのインスタンスを生成
‘ ※この瞬間に Application.Echo False が走ります
Dim safeEcho As clsSafeEcho
Set safeEcho = New clsSafeEcho
On Error GoTo ErrorHandler
‘ — ここからメインの処理 —
Debug.Print “重い処理を実行中…”
‘ わざとエラーを起こしてみるテスト(コメントアウトを外すとエラーになります)
‘ Dim i As Long: i = 1 / 0
‘ 処理が正常に終わった
MsgBox “処理が正常に完了しました!”, vbInformation
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しましたが、画面は正常に復帰します。” & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical
‘ ※ここでエラー処理をしてプロシージャを抜けますが、
‘ safeEcho変数はこのスコープを抜ける瞬間に自動的に破棄(Terminate)されるため、
‘ 確実に Application.Echo True が実行されます!
End Sub
このコードの何が素晴らしいのか?
1. 書き方がシンプル: 処理の最初に `Set safeEcho = New clsSafeEcho` と書くだけで、あとは何も意識しなくてよくなります。
2. エラーに強い: `GoTo ErrorHandler` でジャンプしようが、予期せぬエラーで強制終了しようが、VBAが変数の寿命を終わらせる(=スコープから外れる)タイミングで、必ず `Class_Terminate` が走り、画面が元通りになります。
3. 「切り忘れ」がゼロに: 人間の手で `Echo True` を書き忘れるヒューマンエラーを、構造的に完全に排除できます。
—
5. さらに実用的にする発展テクニック
実際の開発では、「いま現在のステータスバーにメッセージを表示しながらEchoを止めたい」という要望もよくあります。クラスを少し拡張して、ステータスバーの制御も一緒に包み込んであげると、さらに実用的になりますよ。
‘ === 発展版: clsSafeEchoWithStatus ===
Option Explicit
Private m_ShowStatus As Boolean
‘ 初期化時にメッセージを受け取れるようにする
Public Sub Initialize(Optional ByVal statusMessage As String = “”)
Application.Echo False
If statusMessage <> “” Then
SysCmd acSysCmdSetStatus, statusMessage
m_ShowStatus = True
End If
End Sub
Private Sub Class_Terminate()
‘ ステータスバーをクリア
If m_ShowStatus Then
SysCmd acSysCmdClearStatus
End If
‘ 確実に画面復帰
Application.Echo True
End Sub
呼び出し側のイメージ:
Dim safeEcho As clsSafeEchoWithStatus
Set safeEcho = New clsSafeEchoWithStatus
safeEcho.Initialize “データを一括更新しています… しばらくお待ちください。”
‘ … 重い処理 …
このように、クラスに「責務(画面の保護と復帰)」を閉じ込めることで、メインの業務ロジックが驚くほどスッキリと読みやすくなります。
—
まとめ
今回は、`Application.Echo` を安全に制御するための汎用クラスモジュール設計について解説しました。
- `Application.Echo False` は画面のちらつきを抑え、高速化に不可欠だが、エラー時の復帰漏れというリスクがある。
- クラスのライフサイクル(`Initialize` と `Terminate`)を利用することで、エラーや強制終了時でも確実に描画を復帰させることができる。
- ロジックと環境制御を分離することで、コードの保守性と安全性が飛躍的に向上する。
「動けばいいや」のコードから、「エラーが起きても絶対に破綻しない美しい設計」へ。このクラスモジュールをあなたの引き出しに一つ加えておくだけで、Access開発のクオリティは一段とプロの領域に近づきます。
ここをクリアしたあなたなら、もうAccess VBAの基礎はバッチリです!ぜひ明日の開発から取り入れて、快適なVBAライフを送ってくださいね。
