Accessの「シングルスレッドの呪縛」を解き放つ:TimerIntervalで実現する擬似マルチスレッドの極意
こんにちは。現場で泥臭い自動化を積み重ね、Accessの深淵を覗いてきたエンジニアです。
Access VBAは「シングルスレッド(一度に一つのことしかできない)」という制約を持っています。そのため、重い計算や長時間のデータ処理を走らせると、画面がフリーズして「応答なし」になってしまう……そんな経験はありませんか?
今回は、「フォームのタイマーイベント(TimerInterval & OnTimer)」を使い、UIを固めずに裏側でこっそり処理を進める「擬似マルチスレッド」の手法を伝授します。これさえマスターすれば、Accessの挙動は一気にプロフェッショナルなものに変わります。
—
1. なぜ「TimerInterval」なのか?
Accessのフォームには、一定時間ごとに呼び出される「時計」のような機能があります。それが `TimerInterval` プロパティです。
- TimerInterval: 何ミリ秒おきにイベントを発生させるかを決める(単位はミリ秒。1000なら1秒)。
- OnTimer: 時間が来るたびに実行されるイベントプロシージャ。
通常、Accessで重い処理を行うと、その処理が終わるまで画面は「死んだ」状態になります。しかし、このタイマーイベントを活用すれば、「短時間の処理を何度も繰り返す」という手法で、ユーザーが操作している間もバックグラウンドでデータ監視や更新を行うことが可能になるのです。
—
2. 実践:バックグラウンド・データチェッカーの実装
今回は、「3秒おきにテーブルの更新状況をチェックし、変更があればラベルに通知する」という仕組みを作ってみましょう。
手順:
1. フォームをデザインビューで開きます。
2. 「プロパティシート」を開き、以下の設定を行います。
- タイマー間隔 (TimerInterval): `3000` (3秒)
3. フォームに「lblStatus」という名前のラベルを配置します。
コードを実装する
フォームのモジュール(コード画面)に以下を記述してください。
Option Compare Database
Option Explicit
‘ フォームが読み込まれた時にタイマーを開始する
Private Sub Form_Load()
‘ タイマー間隔はプロパティシートでも設定可能ですが、コードで制御すると確実です
Me.TimerInterval = 3000
Me.lblStatus.Caption = “監視中…”
End Sub
‘ 一定時間ごとに呼び出されるメイン処理
Private Sub Form_Timer()
‘ ポイント:一度の処理を極めて短くすること!
‘ 長いループ処理をここに書くと、結局フリーズします。
Dim db As DAO.Database
Dim rs As DAO.Recordset
‘ CurrentDbは毎回生成すると重いため、本来はモジュールレベルで保持するのがベスト
Set db = CurrentDb
‘ 擬似的なデータチェック(例:未処理データのカウント)
Set rs = db.OpenRecordset(“SELECT Count() FROM T_Orders WHERE Status = ‘未処理'”)
If rs(0) > 0 Then
Me.lblStatus.Caption = “警告: ” & rs(0) & ” 件の未処理データがあります!”
Me.lblStatus.ForeColor = vbRed
Else
Me.lblStatus.Caption = “すべて正常です。”
Me.lblStatus.ForeColor = vbBlack
End If
‘ オブジェクトの解放(メモリ管理の基本中の基本)
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
—
3. 陥りやすい罠と「プロの鉄則」
この手法を使う上で、絶対に守るべき「3つの鉄則」があります。
① 「重い処理」を一度に書かない
`OnTimer` 内で10秒かかる処理を書いてはいけません。タイマーはあくまで「細切れのタスク」を実行するためのものです。もし大きな処理が必要なら、フラグを立てて「少しずつ進める(イテレータパターン)」工夫が必要です。
② CurrentDbの扱いに注意
`CurrentDb` は呼び出すたびに新しいインスタンスを生成します。タイマーで頻繁に呼び出す場合、メモリの無駄遣いになります。
- 改善策: `Private db As DAO.Database` をモジュールの先頭で宣言し、`Form_Load` で一度だけ `Set db = CurrentDb` してください。
③ エラーハンドリングは必須
タイマーイベントでエラーが発生すると、Accessは容赦なく停止します。`On Error Resume Next` を多用するのは避け、必ずエラーログを吐き出すか、通知する仕組みを入れてください。
—
最後に:ここをクリアすれば、あなたはもう初心者じゃない
この「タイマーによる擬似マルチスレッド」は、Access開発の幅を劇的に広げます。
例えば、チャットのようなリアルタイム通知、バックグラウンドでのCSVインポート監視、あるいはオートセーブ機能……。
Accessは古いと言われますが、こうした「泥臭い工夫」を組み込むことで、驚くほどモダンで快適なツールに化けます。
まずはこのコードをコピペして、自分の環境で動かしてみてください。画面が固まらずにデータが更新されるのを見たとき、きっとAccess VBAの本当の楽しさがわかるはずです。
もし分からないことがあれば、いつでも聞いてくださいね。応援しています!
