[VBA]ADODB.Recordset.Findの実行時エラー3001

投稿者:

Accessに次のようなテーブルがあるとする。

このテーブルから「コード」が「1」のレコードを検索するVBAを書くと次のようになる。

Public Sub example1()
    Dim rs As New ADODB.Recordset
    
    rs.Open "テーブル1", CurrentProject.Connection, adOpenKeyset, adLockOptimistic
    
    rs.MoveFirst
    rs.Find "コード=1"
    
    If Not rs.EOF Then
        Debug.Print rs![名前] & " " & rs![年齢]
    Else
        Debug.Print "該当データ無し"
    End If
    rs.Close
End Sub

これを実行すると次のような結果になる。

では、条件が二つになった時どうなるだろう。
Findメソッドの引数をSQLのWHERE句のように条件をANDやORで繋げればいけそうな気がする。

Public Sub example2()
    Dim rs As New ADODB.Recordset
    
    rs.Open "テーブル1", CurrentProject.Connection, adOpenKeyset, adLockOptimistic
    
    rs.MoveFirst
    rs.Find "コード=1 AND 名前='佐藤'"  '複数条件のWHERE句
    
    If Not rs.EOF Then
        Debug.Print rs![名前] & " " & rs![年齢]
    Else
        Debug.Print "該当データ無し"
    End If
    rs.Close
End Sub

ところが、上のコードを実行すると実行時エラーが発生する。

「実行時エラー '3001':引数が間違った型、許容範囲外、または競合しています。」

このメッセージだけでは何がいけないのかさっぱりわからないが、どうやらFindメソッドは二個以上の条件を処理できないようだ。

でも、システムを構築する上で、どうしても二つ以上のフィールドの値を条件にしてレコードセットを検索したいケースがあるだろう。そんな時はFilterプロパティにWHERE条件を入れると良い。レコードセットの内容が条件に合致したレコードのみになり、条件に合うデータが無いときはRecordCountプロパティの値が0になる。

Public Sub example3()
    Dim rs As New ADODB.Recordset
    
    rs.Open "テーブル1", CurrentProject.Connection, adOpenStatic, adLockReadOnly
    
    rs.Filter = "コード=1 AND 名前='佐藤'"
    
    '↓RecordCountを調べて条件に合致したデータがあるか確認
    If rs.RecordCount > 0 Then
        Debug.Print rs![名前] & " " & rs![年齢]
    Else
        Debug.Print "該当データ無し"
    End If
End Sub

実行結果は次の通り

例ではレコードセットから1レコードのみデータを取り出しているが、条件に合致するレコードが複数ある場合はForやWhileでループさせて取り出す。

余談だが──RecordCountプロパティを使うときはカーソルタイプをadOpenKeysetかadOpenStaticにすること。adOpenDynamicとadOpenForwardOnlyはレコードセットをオープンした直後は全レコードがメモリに読み込まれず、レコード数が不明のためプロパティの値が-1となってしまうからだ。

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください