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

スポンサーリンク

Access VBAの「空の罠」を殲滅せよ:RecordsetのEOF/BOFを制する者がデータベースを制する

Access VBAで業務アプリを構築する際、避けては通れないのが「レコードセットの操作」だ。だが、多くのエンジニアがここで躓く。データが存在しないレコードセットに対し、無防備に `MoveFirst` を叩き込み、ランタイムエラーでアプリをクラッシュさせる。

「データはあるはず」という思い込みは、開発者の傲慢だ。現場のデータは常に揺らぎ、予期せぬ欠落を生む。今回は、Access VBAにおけるRecordsetのEOF/BOF判定を「極限まで堅牢にする」ためのアーキテクチャを伝授する。

なぜ `If Not rs.EOF Then` だけでは不十分なのか

初心者はよくこう書く。

rs.MoveFirst
If Not rs.EOF Then
Debug.Print rs!ID
End If

これは危険極まりない。`Recordset` は開いた瞬間にカレントレコードがどこにあるか保証されていない場合があるからだ。また、フィルタリングの結果、0件だった場合に `MoveFirst` を実行すれば、即座に「現在のレコード位置が指定されていません」というエラーが飛んでくる。

真にプロフェッショナルなコードは、「空であることを許容し、なおかつ最短距離で安全を確保する」

堅牢なRecordset操作の黄金パターン

実務で私が採用している「鉄板の設計パターン」がこれだ。このパターンを使えば、空のレコードセットによるエラーは100%撲滅できる。

Public Sub ProcessData()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String

Set db = CurrentDb
strSQL = “SELECT FROM T_売上明細 WHERE 処理フラグ = False”

‘ dbOpenDynasetで開くのが基本。用途に応じてdbOpenSnapshotを使い分けよ
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)

‘ 【重要】まずEOFを確認する。ここで空なら即座に脱出する
If rs.EOF Then
Debug.Print “対象データは存在しません。”
GoTo Cleanup
End If

‘ ここに来た時点でデータは必ず存在する
‘ MoveFirstは省略可能だが、明示的に書くことで可読性を担保する
rs.MoveFirst

Do Until rs.EOF
‘ 業務ロジックをここに記述
Debug.Print “処理中ID: ” & rs!ID

rs.MoveNext
Loop

Cleanup:
‘ 【必須】オブジェクトの解放。これを怠る者はメモリリークの温床を作る
If Not rs Is Nothing Then
rs.Close
Set rs = Nothing
End If
Set db = Nothing
End Sub

このコードが「極限」である理由

1. 先制的なガード節: `If rs.EOF Then` で即座に終了させることで、後続のネストを深くせず、コードの可読性を保つ。
2. Goto文によるクリーンアップ: 正常系・異常系を問わず、最後は必ずメモリを解放する構造を強制している。
3. 明示的な解放: `Set rs = Nothing` はAccess VBAにおける作法であり、オブジェクトのライフサイクルを正しく管理する証だ。

レコードセット操作における「3つの禁忌」

現場で見かける「ダメなコード」には共通点がある。これだけは避けてほしい。

1. `rs.RecordCount` を過信すること:
DAOの `RecordCount` は、全データを走査するまで正確な件数を返さないことがある。`If rs.RecordCount > 0` を条件にするのは非常に非効率かつ不正確だ。常に `EOF` を信じろ。

2. エラーハンドリングを怠ること:
「データがないこと」はエラーではなく「仕様」だ。`On Error Resume Next` で強引に無視するのは、真のエラーまで握りつぶす愚策である。

3. DAOとADOの混同:
Accessのローカルテーブルを操作するなら、必ず `DAO` を使え。ADOは外部DBとの連携には強力だが、Access内部ではオーバーヘッドが大きく、パフォーマンスを著しく低下させる。

最後に:エンジニアとしての矜持

VBAは「誰でも書ける言語」だ。しかし、「誰でも書けるからこそ、品質の差が残酷なほど出る」。

空のデータセットを扱うとき、単に「エラーを消す」のではなく、「なぜデータが空なのか」「空だった場合にどういう挙動がユーザーにとって最適か」を設計レベルで考えること。それが、単なるプログラマーと、システムを構築するエンジニアの境界線だ。

このパターンをテンプレート化し、貴方のリポジトリに保存してほしい。その小さな積み重ねが、堅牢な業務アプリを支える基盤となる。

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