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 Function
ADO操作によるレコードセット操作
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 Function
ADO接続の場合、参照設定が必要です。
参照設定されていない場合、実行時以下のエラーが表示されます。
ツールの参照設定から、【ActiveX Data Objects x.x Library】にチェックを入れてください。(お使いの環境において最新のライブラリーにチェックしてください)
※1 ADOのOpenメソッドのロックタイプ規定値は読み取り専用(adLockReadOnly)となっていますので、adLockOptimisticを指定する必要があります。
ADOとDAOの違いで気を付ける点
編集前のeditコマンド
DAOの場合、レコードを更新する際は事前に.editコマンドで編集することを宣言する必要がありますが、ADOの場合は不要です。
取得したレコードセットからデータを抽出する方法
その他、一旦取得したレコードセットからさらにデータを抽出する方法としてfindコマンドがありますが、DAOの場合は複数のフィールドに対して条件を指定できますがADOで指定できる条件は1つだけです。
このため複数の条件を指定したい場合はADOの場合filterプロパティを使用します。
通常、条件を指定してレコードセットを取得するものですが、それなりの事情があって一旦取得したレコードセットからさらに絞り込む場合です。