Access

【AccessVBA】レコードセットからデータを検索する方法(find or filter)

レコードセットの検索
記事内に商品プロモーションを含む場合があります

ADOやDAOで取得したレコードセットからデータを絞り込んで検索する方法にはfindコマンドを使う方法があります。

ただ、ADOでfindコマンドを使うためには制約事項があるためADOでレコードを検索する場合はfilterプロパティの利用をお勧めします。

ADO レコード セットの Find メソッドには、いくつかの制限があります。

  • 1 つのフィールドを検索にのみ使用できます。
  • 文字列リテラルで引用符を許可されていません。
  • 式を検索することはできません。

この問題を回避する方法の 1 つでは、 Filterプロパティを使用します。

引用:マイクロソフト公式サイト

ADOとDAOのレコード検索サンプルプログラム

今回は顧客テーブルのレコードセットをオープンし、レコードセットから誕生月が3月で都道府県が東京都のユーザーを検索してプレゼント発送日を更新するという処理を想定してみました。

このように条件が複数(誕生月+都道府県)の場合、ADOではfindfirstを使うことができません。

そこで、DAOではfindfirstを使ったプログラム、ADOではfilterを使ったプログラムをご紹介します。

DAOレコードセットからデータを検索する方法

Private Function DAO接続_find() As Boolean
    Dim myDb    As DAO.Database     'データベースオブジェクト
    Dim myRs    As DAO.Recordset    'レコードセットオブジェクト
    Dim strSQL  As String       'SQL文用文字列
    
    'エラートラップ
    On Error GoTo Err_Exit
    
    '関数の戻り値初期化
    DAO接続_find = False
    
    Set myDb = CurrentDb '現在のデータベースをセット
    
    'SQL文作成(誕生月指定)
    strSQL = "SELECT * FROM 顧客テーブル"
    
    'レコードセット取得
    Set myRs = myDb.OpenRecordset(strSQL)
  
    With myRs
        '対象データがなければ終了
        If .EOF Or .BOF Then
            MsgBox "該当データがありません。処理を終了します。", vbOKOnly + vbInformation
            GoTo End_Proc
        Else
            '条件に一致する最初のデータを検索
            .FindFirst "誕生月 = 3 AND 都道府県='東京都'"
            
            '条件に一致するデータがある限りループ
            While Not .NoMatch
                '対象データを編集モードにする
                .Edit
                'プレゼント発送日にシステム日付を代入
                .Fields("プレゼント発送日") = Date
                '更新実行
                .Update
                '次のレコードを検索
                .FindNext "誕生月 = 3 AND 都道府県='東京都'"
            Wend
        End If
    End With
    MsgBox "処理を終了しました。", vbOKOnly + vbInformation
    
End_Proc:
    'オブジェクトの開放
    Set myRs = Nothing: Close
    Set myDb = Nothing: Close
    
    '正常終了
    DAO接続_find = True
    
    Exit Function
  
Err_Exit:
    'エラーNOとエラーの詳細を表示
    MsgBox Err.Number & ":" & Err.Description, vbOKOnly + vbCritical, "DAO接続()_find"
    'オブジェクトの開放
    Set myRs = Nothing: Close
    Set myDb = Nothing: Close
  
End Function

ADOレコードセットからデータを検索する方法

Private Function ADO接続_filter() As Boolean

    Dim myCn     As ADODB.Connection    'ADOコネクションオブジェクト
    Dim myRs     As ADODB.Recordset     'ADOレコードセットオブジェクト
    Dim strSQL   As String              'SQL文用文字列
    
    'エラートラップ
    On Error GoTo Err_Exit
    
    '関数の戻り値初期化
    ADO接続_filter = False
    
    '現在のデータベースへ接続
    Set myCn = CurrentProject.Connection
    
    'ADOレコードセットのインスタンス作成
    Set myRs = New ADODB.Recordset
    
    'SQL文作成(誕生月指定)
    strSQL = "SELECT * FROM 顧客テーブル"
    
    'レコードセット取得
    myRs.Open strSQL, myCn, , adLockOptimistic
  
    With myRs
        '検索条件をフィルターに適用
        myRs.Filter = "誕生月 = 3 AND 都道府県='東京都'"
        
        '対象データがなければ終了
        If .EOF Or .BOF Then
            MsgBox "該当データがありません。処理を終了します。", vbOKOnly + vbInformation
            GoTo End_Proc
        Else
            '先頭レコードに移動
            .MoveFirst
            While Not .EOF
                'プレゼント発送日にシステム日付を代入
                .Fields("プレゼント発送日") = Date
                '更新実行
                .Update
                '次のレコードに移動
                .MoveNext
            Wend
        End If
    End With
    MsgBox "処理を終了しました。", vbOKOnly + vbInformation
    
End_Proc:
    'オブジェクトの開放
    Set myRs = Nothing: Close
    Set myCn = Nothing: Close
    
    '正常終了
    ADO接続_filter = True
    
    Exit Function
  
Err_Exit:
    'エラーNOとエラーの詳細を表示
    MsgBox Err.Number & ":" & Err.Description, vbOKOnly + vbCritical, "ADO接続_filter()"
    'オブジェクトの開放
    Set myRs = Nothing: Close
    Set myCn = Nothing: Close
  
End Function

ADOを使うかDAOを使うか悩んだらこちらの記事も参考にされてください。

レコードセット
【AccessVBA】ADOとDAOを使ってレコードセットを読み書きする方法AccessのVBAでレコードを操作したいときに利用するレコードセット。 レコードセットを使ってデータベースを読み書きする方法はA...
ABOUT ME
アズビーパートナーズ
プログラマー→社内SE→SIerのお仕事をしています。 メーカー勤務を経て、中小企業の社内SE、フリーランスなど様々な形態で働いてきました。 業務上生まれた困った…を解決してきたTipsを備忘録も兼ねて公開しています。 困っている誰かのお役に立てれば幸いです。