【実務・中級編】DAOでレコードセットをループする際の「MoveNext」忘れを防ぐ定型パターン – Access VBA解析バイブル

スポンサーリンク

【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でもできる。だが、「誰が後から読んでもバグを混入させる余地がない構造」を作るのは、君たちエンジニアの腕の見せ所だ。

このテンプレートを自身のライブラリに組み込み、二度と無限ループの地獄を見ないような、堅牢なシステムを構築してほしい。現場の課題は、君のコード一つで解決できるのだから。

タイトルとURLをコピーしました