Access VBAの「Edit/Update」はなぜ遅いのか?トランザクションの真実を掌握せよ
Accessで業務システムを構築する際、多くの開発者が陥る罠がある。それは「ループ内で無防備にRecordsetを叩く」ことだ。
`rs.Edit` と `rs.Update` を1レコードごとに繰り返すコードを書いていないだろうか? もしそうなら、あなたのアプリケーションは、本来の性能の10%も引き出せていない。今回は、Accessのパフォーマンスと堅牢性を左右する「トランザクションのスコープ」について、エンジニアの視点で深掘りする。
—
1. なぜ「1レコード単位の更新」が罪深いのか
Access(ACEエンジン)は、ディスクI/Oに対して非常に繊細だ。`rs.Update` を実行するたびに、データベースエンジンは以下の処理を強制される。
1. ページロックの獲得と解放
2. インデックスの再計算と整合性チェック
3. トランザクションログのフラッシュ(ディスク書き込み)
これを数千件のレコードで行えば、OSのキャッシュを汚し、オーバーヘッドが積み重なって処理が止まる。VBAのコードが遅いのではない。「データベースとの対話回数」が多すぎるのが原因だ。
—
2. トランザクション・スコープの極意
パフォーマンスと安全性を両立する唯一の解は、「DAOのトランザクションを明示的に制御すること」に尽きる。
`DBEngine.BeginTrans` から `CommitTrans` までの間、ACEエンジンは書き込みをメモリ上でバッファリングする。このスコープを「処理の塊(ビジネスロジックの1単位)」と一致させることで、ディスクI/Oを劇的に削減できる。
堅牢な実装サンプル
以下のコードは、エラーハンドリングを完備した、そのままプロダクションで使えるテンプレートだ。
Public Sub BatchUpdateExample()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim ws As DAO.Workspace
Set db = CurrentDb
Set ws = DBEngine(0) ‘ デフォルトのワークスペース
‘ 処理の開始:トランザクションを宣言
ws.BeginTrans
On Error GoTo RollbackHandler
Set rs = db.OpenRecordset(“T_Master”, dbOpenDynaset)
Do While Not rs.EOF
rs.Edit
rs!Processed = True
rs!LastUpdate = Now
rs.Update ‘ ここでのUpdateはメモリ上のバッファ操作に留まる(高速)
rs.MoveNext
Loop
‘ 全ての更新をコミット
ws.CommitTrans
rs.Close: Set rs = Nothing
Exit Sub
RollbackHandler:
‘ 異常発生時は必ずロールバックし、不整合を防ぐ
ws.Rollback
MsgBox “エラー発生。トランザクションをロールバックしました: ” & Err.Description, vbCritical
If Not rs Is Nothing Then rs.Close: Set rs = Nothing
End Sub
—
3. ここで差がつく:設計上の注意点
このコードをただコピペするだけでは一流とは言えない。以下の「アーキテクチャの視点」を忘れてはならない。
- ロックの衝突を避ける: トランザクションを長く開きすぎると、他のユーザーが同じテーブルにアクセスできなくなる(ロック待機が発生する)。「1つのトランザクションは、数千レコード程度」か「処理時間にして数秒以内」を目安に区切るのがプロの流儀だ。
- Updateの前にEditを置く理由: `rs.Edit` はレコードを編集モードにするための儀式ではない。対象のレコードをロックし、整合性を担保するための重要なステップだ。これを省略したり、バッファを無視して書き込もうとする設計は、マルチユーザー環境で必ずバグを生む。
- CurrentDbの再利用: `CurrentDb` は呼び出すたびに新しいインスタンスを生成する可能性がある。必ず変数に格納し、そのインスタンスを使い回すこと。
—
結び:エンジニアとしての矜持
VBAは「古い言語」と揶揄されることもある。だが、AccessのDAOとトランザクションを正しく制御できるエンジニアは、現代でも極めて希少だ。
「コードの行数」ではなく、「データベースエンジンがどう動くか」を想像せよ。
今回提示したトランザクションの制御は、あなたの作るツールの「遅い・止まる・壊れる」を「爆速・堅牢・快適」へと変えるはずだ。さあ、今すぐ既存のコードをリファクタリングして、その劇的な変化を体感してほしい。
