AccessのVBAでレコードを操作したいときに利用するレコードセット。
レコードセットを使ってデータベースを読み書きする方法はADO接続とDAO接続があります。
ADO・DAOどちらを使うべきか
古くから実装されているのがDAOで、後発の接続方法としてADOが利用できるようになりました。
DAOもAODもほぼ同じことができるので基本的には処理速度が速い方がいいですよね。
一般的には以下のように言われています。
- Accessのテーブルを操作する場合はDAOの方が速い
 - その他のDBへ外部接続したテーブルを操作する場合はADOの方が速い
 
DAOはAccessのJETエンジンに特化した接続であるため、ACCESSのテーブルへのアクセスがADOより高速です。
しかし、高速と言っても若干高速ぐらいですので、やりやすい方法で実装し実際の検索があまりにも遅い時にチューニングとしてDAOとAODを切り替えてみるというレベルで良いのでは?と思います。
そもそも極端に遅い場合はDAOだ、ADOだという前にSQLの構成に問題がある場合もありますので・・・。
ADO,DAOのレコードセットの使用方法
今回は顧客テーブルから誕生月が3月ユーザーを検索してプレゼント発送日を更新するという処理を想定してみました。
要するに検索+更新のレコードセット操作方法です。
DAO接続によるレコードセット操作
Private Function DAO接続() As Boolean
    Dim myDb    As DAO.Database     'データベースオブジェクト
    Dim myRs    As DAO.Recordset    'レコードセットオブジェクト
    Dim strSQL  As String       'SQL文用文字列
    
    'エラートラップ
    On Error GoTo Err_Exit
    
    '関数の戻り値初期化
    DAO接続 = False
    
    Set myDb = CurrentDb '現在のデータベースをセット
    
    'SQL文作成(誕生月指定)
    strSQL = "SELECT * FROM 顧客テーブル WHERE 誕生月 = 3"
    
    'レコードセット取得
    Set myRs = myDb.OpenRecordset(strSQL)
  
    With myRs
        '対象データがなければ終了
        If .EOF Or .BOF Then
            MsgBox "該当データがありません。処理を終了します。", vbOKOnly + vbInformation
            GoTo End_Proc
        Else
            '先頭レコードに移動
            .MoveFirst
            While Not .EOF
                '対象データを編集モードにする
                .Edit
                'プレゼント発送日にシステム日付を代入
                .Fields("プレゼント発送日") = Date
                '更新実行
                .Update
                '次のレコードに移動
                .MoveNext
            Wend
        End If
    End With
    MsgBox "処理を終了しました。", vbOKOnly + vbInformation
    
End_Proc:
    'オブジェクトの開放
    Set myRs = Nothing: Close
    Set myDb = Nothing: Close
    
    '正常終了
    DAO接続 = True
    
    Exit Function
  
Err_Exit:
    'エラーNOとエラーの詳細を表示
    MsgBox Err.Number & ":" & Err.Description, vbOKOnly + vbCritical, "DAO接続()"
    'オブジェクトの開放
    Set myRs = Nothing: Close
    Set myDb = Nothing: Close
  
End FunctionADO操作によるレコードセット操作
Private Function ADO接続() 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接続 = False
    
    '現在のデータベースへ接続
    Set myCn = CurrentProject.Connection
    
    'ADOレコードセットのインスタンス作成
    Set myRs = New ADODB.Recordset
    
    'SQL文作成(誕生月指定)
    strSQL = "SELECT * FROM 顧客テーブル WHERE 誕生月 = 3"
    
    'レコードセット取得・・・(※1)
    myRs.Open strSQL, myCn, , adLockOptimistic
  
    With myRs
        '対象データがなければ終了
        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接続 = True
    
    Exit Function
  
Err_Exit:
    'エラーNOとエラーの詳細を表示
    MsgBox Err.Number & ":" & Err.Description, vbOKOnly + vbCritical, "ADO接続()"
    'オブジェクトの開放
    Set myRs = Nothing: Close
    Set myCn = Nothing: Close
  
End FunctionADO接続の場合、参照設定が必要です。
参照設定されていない場合、実行時以下のエラーが表示されます。

ツールの参照設定から、【ActiveX Data Objects x.x Library】にチェックを入れてください。(お使いの環境において最新のライブラリーにチェックしてください)

※1 ADOのOpenメソッドのロックタイプ規定値は読み取り専用(adLockReadOnly)となっていますので、adLockOptimisticを指定する必要があります。
ADOとDAOの違いで気を付ける点
編集前のeditコマンド
DAOの場合、レコードを更新する際は事前に.editコマンドで編集することを宣言する必要がありますが、ADOの場合は不要です。
取得したレコードセットからデータを抽出する方法
その他、一旦取得したレコードセットからさらにデータを抽出する方法としてfindコマンドがありますが、DAOの場合は複数のフィールドに対して条件を指定できますがADOで指定できる条件は1つだけです。
このため複数の条件を指定したい場合はADOの場合filterプロパティを使用します。
通常、条件を指定してレコードセットを取得するものですが、それなりの事情があって一旦取得したレコードセットからさらに絞り込む場合です。

💡 Accessでここまでやるのは大変…
そう感じたら、次の選択肢を知るチャンスです。
👉 Accessの限界を超える方法はこちら

		
			
			
			
			
			
			
			
			
コメント