【実務・中級編】【初心者】DAO.Recordsetの「EOF」判定の落とし穴:レコードが存在しない場合の安全なループ処理 – Access VBA解析バイブル

スポンサーリンク

【Accessの神髄】なぜあなたのコードは止まるのか?DAO.Recordsetの「EOF」を完全掌握せよ

現場で「なぜかループが走らない」「レコードがないとエラーになる」という壁にぶつかっていないだろうか。

Access VBAを用いた業務自動化において、`DAO.Recordset`は心臓部だ。しかし、この心臓部の扱いを誤れば、システムは簡単に呼吸を止める。特に、「レコードが1件も存在しない状態」への配慮を欠いたコードは、爆弾を抱えたまま走っているようなものだ。

今回は、伝説的アーキテクトの視点から、DAOループの「正しい作法」と、現場で生き残るための堅牢な実装術を伝授する。

1. なぜ「EOF」だけでは不十分なのか

初心者がやりがちな、最も脆弱なパターンがこれだ。

‘ 【危険なコード】初心者がやりがちな実装
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset(“T_受注データ”)

Do While Not rs.EOF ‘ ここで詰まる可能性がある
Debug.Print rs!受注ID
rs.MoveNext
Loop
rs.Close

一見動くように見える。だが、もしテーブルが空だったら?あるいは抽出条件で1件もヒットしなかったら?
「レコードが存在しない」とき、`rs`は生成されるが、その状態は`EOF`かつ`BOF`でもある。この状況で`rs!受注ID`にアクセスしようとすれば、即座に実行時エラーが発生する。

プロの視点: 「データが必ずある」という前提は、システム開発における最大の慢心だ。データは常に「ゼロ」から「無限」の可能性を秘めていると仮定せよ。

2. 堅牢なループ処理の「黄金パターン」

現場のプロダクションコードでは、レコードの有無を判定し、空であれば即座に終了させるフローが鉄則だ。`EOF`のみに頼らず、`BOF`と組み合わせて制御するのが最も美しい。

推奨される実装コード

Public Sub ProcessOrders()
Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb
‘ パフォーマンスを考慮し、必要な列だけを選択する
Set rs = db.OpenRecordset(“SELECT 受注ID, 受注日 FROM T_受注データ WHERE 処理済 = False”, dbOpenSnapshot)

‘ 【重要】レコードの有無を最初に判定する
If rs.EOF Then
Debug.Print “対象レコードは存在しません。”
rs.Close
Exit Sub
End If

‘ ここまで到達すれば、確実にデータは存在する
rs.MoveFirst
Do Until rs.EOF
‘ 処理内容を記述
Debug.Print “処理中: ” & rs!受注ID

rs.MoveNext
Loop

rs.Close
Set rs = Nothing
Set db = Nothing
End Sub

3. アーキテクトからの3つの鉄則

コードを「動くもの」から「壊れないもの」に変えるための、現場で使える知見を授ける。

① dbOpenSnapshot の活用

`dbOpenSnapshot`を指定することで、読み取り専用の軽量なレコードセットが作成される。更新が不要な集計や参照処理で、わざわざ重たい`Dynaset`(既定値)を使う理由はない。メモリ消費を抑え、ロックの競合を防ぐことは、マルチユーザー環境での基本だ。

② 明示的なクローズとメモリ解放

`rs.Close`と`Set rs = Nothing`を省略するエンジニアがいるが、これはメモリリークの温床だ。Accessは小規模なアプリであっても、長時間稼働させればオブジェクトの残滓がパフォーマンスを劣化させる。「開いたら閉じる」。この当たり前の規律が、システムの寿命を延ばす。

③ エラーハンドリングの組み込み

上記コードに、必ず `On Error GoTo` を追加すること。データベース連携において「エラーが起きないこと」を祈るのではなく、「エラーが起きた時にどう振る舞うか」を設計するのが、エンジニアの仕事だ。

結論:コードは「対話」である

今回紹介したパターンは、Access開発の基礎中の基礎だ。しかし、この基礎を疎かにするエンジニアは、一生「謎のエラー」に追いかけ回されることになる。

システムはあなたが書いたコードの通りにしか動かない。データがない状態を「異常」ではなく「正常なフローの一部」として扱うこと。それが、堅牢な業務自動化ツールを作るための第一歩だ。

さあ、今すぐあなたの既存コードを見直してほしい。そこに「レコードがゼロのとき」の優しさはあるだろうか?

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