【入門編】RecordsetのEOFとBOFを正しく判定する:空レコードセットによるエラーの撲滅 – Access VBA解析バイブル

スポンサーリンク

伝説のエンジニアが教える「Recordsetの罠」:EOFとBOFを制する者はAccessを制す

こんにちは。Accessという広大な海を航海する皆さんに、今日はひとつ、「絶対に避けては通れない、けれど多くの人が誤解している本質」をお伝えします。

Access VBAでデータベースを操作する際、避けて通れないのが「Recordset(レコードセット)」という概念です。しかし、初学者が最も頻繁に遭遇し、そして最も心を折られるのが「空のレコードセットを操作しようとして発生する実行時エラー」です。

今日は、なぜエラーが起きるのか、どうすれば完璧に防げるのか。その極意を伝授します。これさえ理解すれば、あなたの書くコードの堅牢性は一気にプロレベルへと引き上がりますよ。

1. なぜ「空のレコードセット」は牙を剥くのか?

まず、レコードセットを「本棚」に例えてみましょう。
クエリを実行してデータを取り出すことは、倉庫から「特定の条件に合う本」を箱に入れて持ってくる作業と同じです。

  • データがある場合: 箱の中に本が入っています。
  • データがない場合: 「箱自体はあるけれど、中身は空っぽ」の状態です。

初心者がやりがちなのは、「箱があるんだから、とりあえず1冊目を取り出そう(`rs.MoveFirst` や `rs!フィールド名`)」とすることです。中身が空なのに取り出そうとすれば、当然「現在のレコードがない」という怒りのエラーが返ってきます。

2. EOFとBOF:魔法のフラグを読み解く

Access VBAには、この「箱の中身の状態」を教えてくれる2つの魔法のフラグがあります。

  • BOF (Beginning of File): 「先頭よりも前」にいるよ!
  • EOF (End of File): 「末尾よりも後ろ」にいるよ!

この2つは、「現在のカーソル位置が、データの範囲外にあるかどうか」を示すセンサーです。

究極の判定パターン

データが1件もない時、実は `BOF` も `EOF` も同時に `True` になります。これこそが「空っぽ」の証明です。

‘ 堅牢なレコードセット走査の雛形
Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb
Set rs = db.OpenRecordset(“T_売上データ”, dbOpenDynaset)

‘ ここが重要!データが存在するかを先に確認する
If rs.EOF And rs.BOF Then
‘ データが1件もなかった場合の処理
MsgBox “対象データが存在しません。”, vbExclamation
Else
‘ データがある場合のみ、走査を開始する
Do Until rs.EOF
Debug.Print rs!売上金額 ‘ 安全に値にアクセスできる
rs.MoveNext
Loop
End If

‘ 最後に必ず「閉じる」と「解放」を忘れないこと(メモリリーク対策)
rs.Close
Set rs = Nothing
Set db = Nothing

3. なぜ「If rs.EOF Then」だけでは不十分なのか?

よくある間違いとして、「`If rs.EOF Then`」だけを判定に使う人がいます。しかし、これでは不完全です。

実は、`OpenRecordset` を実行した直後、カーソルは常に「先頭のレコード」を指そうとします。もしデータが空なら、カーソルは「先頭の前(BOF)」かつ「末尾の後ろ(EOF)」という特殊な状態になります。

プロのアーキテクトとして言わせてもらえば、「空チェックには必ず `rs.EOF And rs.BOF` を使う」のが鉄則です。これが最も意図が明確で、後からコードを読む他者にも「ここは空判定をしているんだな」と一目で伝わります。

4. 現場で使える「プロの作法」

最後に、現場で評価されるエンジニアになるための「コードの作法」を3つ授けます。

1. 「閉じ忘れる」は最大の罪:
`rs.Close` を書かないと、メモリ上にデータが残り続け、Accessが重くなる原因になります。`Set rs = Nothing` までセットで癖づけましょう。
2. `MoveNext` を忘れない:
`Do Until` ループの中で `rs.MoveNext` を書き忘れると、永遠に同じレコードを読み続ける「無限ループ」に陥ります。プログラムがフリーズしたら、まずここを疑ってください。
3. 読み取り専用なら `dbOpenSnapshot`:
データを更新する必要がない場合は、`dbOpenSnapshot` を指定しましょう。動作が劇的に軽くなります。

最後に:基本こそが最強の武器

いかがでしたか?「空のレコードセット」という小さな壁を乗り越えることは、Access VBAで大規模なシステムを構築するための第一歩です。

コードは、あなたの指示を忠実に実行する部下のようなものです。「空かもしれない」という疑いの目を持って優しく接してあげれば、きっとあなたの期待に応えてくれるはずですよ。

ここをクリアしたあなたなら、もう中級者への入り口に立っています。自信を持って、次のコードを書いてみてください。また迷ったときは、いつでもここに戻ってきてくださいね。応援しています!

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