【Access VBA】DAOループの「無限地獄」を完全封印せよ:現場で一生使える堅牢なイディオム
Access開発において、DAO(Data Access Objects)によるレコードセット操作は避けて通れない「基本中の基本」だ。しかし、この「基本」こそが、多くの現場で無限ループやメモリリークを引き起こす火種となっている。
君が書いたコードで、Accessが突然フリーズし、タスクマネージャーから強制終了する羽目になったことはないか? それは、単なるケアレスミスではない。「レコードセットのライフサイクル」を設計思想に組み込めていない証拠だ。
今回は、DAOループ処理における「MoveNext忘れ」を構造的に排除し、プロとして恥じない堅牢なテンプレートを伝授する。
—
1. なぜ「MoveNext忘れ」は起きるのか?
DAOの`Do While Not .EOF`ループは、記述の自由度が高いがゆえに、論理的な落とし穴が多い。特に、条件分岐内で`Exit Sub`や`GoTo`を多用すると、制御の糸が切れる。
初心者は「ループの最後に`MoveNext`を書く」というルールを覚えるが、これは中級者への道でしかない。真のエンジニアは「MoveNextを忘れないコード」ではなく、「MoveNextを忘れる余地のない構造」を書く。
—
2. 鋼鉄のDAOループ・テンプレート
現場でそのまま使える、バグを生まない標準的なコードパターンを公開する。
Public Sub ProcessRecords_Robust()
Dim db As DAO.Database
Dim rs As DAO.Recordset
‘ 1. オブジェクトの初期化
Set db = CurrentDb
Set rs = db.OpenRecordset(“SELECT FROM T_TargetTable”, dbOpenDynaset)
‘ 2. 空レコードセットの早期リターン(安全性の確保)
If rs.EOF Then
Debug.Print “対象データなし”
GoTo Cleanup
End If
‘ 3. ループの定型パターン
Do Until rs.EOF
‘ —————————————————-
‘ ここにビジネスロジックを記述
‘ —————————————————-
‘ 注意: この中で Exit Sub 等を多用しないこと。
‘ 代わりに GoTo Cleanup を使い、終了処理を担保する。
‘ —————————————————-
rs.MoveNext ‘ ループの末尾で必ず移動
Loop
Cleanup:
‘ 4. リソースの確実な解放(メモリリーク対策)
If Not rs Is Nothing Then
rs.Close
Set rs = Nothing
End If
Set db = Nothing
End Sub
このコードが「伝説」たりえる3つの理由
1. `Do Until .EOF` の採用: `Do While Not .EOF`よりも条件が直感的で、意図が明確になる。
2. 早期リターンと`Cleanup`ラベル: 関数内でエラーが発生したり、特定の条件でループを抜けたい場合でも、`GoTo Cleanup`で必ずメモリ解放のセクションを通る。これで「開けっ放しのレコードセット」を撲滅できる。
3. 明示的なリセット: `Set rs = Nothing` を忘れない。Access VBAのガベージコレクションを信用してはならない。リソース解放はエンジニアの義務だ。
—
3. さらに先へ:トランザクションを組み合わせる場合
レコードセットをループして更新を行う場合、一つ一つの変更を保存する(自動コミット)のはパフォーマンスの観点からも、データの整合性の観点からも愚策だ。
必ず `DBEngine.BeginTrans` と `CommitTrans` を活用せよ。
DBEngine.BeginTrans ‘ トランザクション開始
On Error GoTo RollbackHandler
Do Until rs.EOF
rs.Edit
rs!Processed = True
rs.Update
rs.MoveNext
Loop
DBEngine.CommitTrans ‘ 全処理成功時にコミット
Exit Sub
RollbackHandler:
DBEngine.Rollback ‘ エラー時は全てなかったことにする
MsgBox “エラー発生: 全処理をロールバックしました。”
—
最後に:なぜ「動くだけ」ではダメなのか
AccessのDAOは、ファイルベースのエンジンとして非常に優秀だが、メモリ管理が甘いコードは、長期間運用するうちに必ずデータベースの肥大化やパフォーマンスの劣化というツケを払うことになる。
「動くコード」を書くのはAIでもできる。だが、「誰が後から読んでもバグを混入させる余地がない構造」を作るのは、君たちエンジニアの腕の見せ所だ。
このテンプレートを自身のライブラリに組み込み、二度と無限ループの地獄を見ないような、堅牢なシステムを構築してほしい。現場の課題は、君のコード一つで解決できるのだから。
