Access VBAの「フリーズ」を解消せよ!DAO.RecordsetとSysCmdで魅せるプロフェッショナルな進捗バー実装術
こんにちは。Accessの現場で、何万件ものレコードを処理する際、「プログラムが止まってしまったのでは?」と不安になった経験はありませんか?
画面が白くなり、マウスカーソルが砂時計のまま動かない――。これはユーザーにとって最大のストレスです。しかし、実はこれ、「進捗状況を可視化していない」という、エンジニア側のちょっとした手抜きによるものかもしれません。
今日は、Access VBAの心臓部である`DAO.Recordset`と、隠れた名機能`SysCmd`を駆使して、あなたのバッチ処理を「信頼されるシステム」へと昇華させる極意を伝授します。
—
1. なぜ「進捗バー」が必要なのか?
プログラムの処理時間は、PCのスペックやデータ量に依存します。ユーザーは「あとどれくらいで終わるのか」が分からないと、不安から何度もクリックを連打し、結果としてデータベースのロックやシステムクラッシュを招きます。
`SysCmd`関数は、Accessの画面最下部(ステータスバー)に情報を表示する、いわば「システムからの生存信号」です。これがあるだけで、ユーザーは安心し、無駄な操作を控えてくれるようになります。
—
2. 魔法のメソッド:`AbsolutePosition` と `RecordCount`
今回の主役は、`DAO.Recordset`オブジェクトが持つ2つのプロパティです。
- `RecordCount`: 全レコードの総数。
- `AbsolutePosition`: 現在処理しているレコードの「0から始まる」現在位置。
この2つを組み合わせれば、進捗率は「現在位置 ÷ 総数」というシンプルな算数で算出できます。
—
3. 実践!進捗バー実装コード
まずは、標準的なバッチ処理のテンプレートを見てください。これをコピペして、あなたの処理に組み込むだけで、見違えるほどプロフェッショナルな挙動に変わります。
Public Sub RunBatchProcess()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim totalRecords As Long
Dim currentPos As Long
Set db = CurrentDb
Set rs = db.OpenRecordset(“T_あなたの重いテーブル”, dbOpenDynaset)
‘ レコードセットの総数を確定させる(重要!)
If Not (rs.BOF And rs.EOF) Then
rs.MoveLast
totalRecords = rs.RecordCount
rs.MoveFirst
End If
‘ ステータスバーの初期化
SysCmd acSysCmdInitMeter, “データ処理を実行中…”, totalRecords
Do While Not rs.EOF
‘ — ここに本来の重い処理を書く —
‘ 例: データの更新など
‘ DoEvents ‘ 必要に応じてUIの更新を許可する
‘ 現在位置を取得して進捗バーを更新
currentPos = rs.AbsolutePosition + 1 ‘ 0から始まるので+1する
SysCmd acSysCmdUpdateMeter, currentPos
rs.MoveNext
Loop
‘ 最後にバーを閉じる(忘れないように!)
SysCmd acSysCmdRemoveMeter
rs.Close
Set rs = Nothing
Set db = Nothing
MsgBox “処理が完了しました!”, vbInformation
End Sub
コードの重要ポイント
1. `rs.MoveLast` してから `rs.MoveFirst`:
`RecordCount`プロパティは、一度最後まで移動しないと正確な数を返さないことがあります。この儀式は、DAOを扱う際の「お約束」です。
2. `acSysCmdInitMeter`:
進捗バーの初期化です。ここで最大値を設定します。
3. `acSysCmdRemoveMeter`:
処理が終わった後にバーを消さないと、ステータスバーが不自然なまま残ります。後片付けはエンジニアの嗜みです。
—
4. 初学者が陥りやすい罠
「処理が遅すぎてバーが更新されない」
レコードが1件ずつ更新されるたびに`SysCmd`を呼び出すと、逆にオーバーヘッド(処理負荷)で処理時間が延びることがあります。もし10万件以上のデータを扱うなら、「100件ごとに更新する」といった工夫を入れましょう。
‘ 100件に1回だけ更新する例
If currentPos Mod 100 = 0 Then
SysCmd acSysCmdUpdateMeter, currentPos
End If
`DoEvents` の副作用
`DoEvents`を入れると画面描画がスムーズになりますが、ユーザーが途中で「閉じる」ボタンを押してしまうリスクも生まれます。`DoEvents`を使う際は、処理中に中断されてもデータが壊れないよう、トランザクション(`BeginTrans` / `CommitTrans`)を検討するのが中級者へのステップアップです。
—
最後に:エンジニアとしての矜持
コードを書くことは、単に動くものを作ることではありません。「使う人がどう感じるか」を想像することが、優れたエンジニアの条件です。
この進捗バーを実装するだけで、あなたのAccessは「ただのツール」から「配慮の行き届いたシステム」へと生まれ変わります。ここをクリアできれば、DAOの扱いに関してはもう基礎をマスターしたと言って過言ではありません。
さあ、あなたのAccessにも、この「命の鼓動」を吹き込んでみてください。応援しています!
