トップ > スキル : アプリケーション > VBA for Access > 応用編(データベースオブジェクト DAOとADO)
データを操作する
データを操作するための基本となるオブジェクトは、レコードを操作する対象となるRecordsetオブジェクトです。
Recordsetオブジェクトには以下のような3種類があります。
- ■ テーブルタイプ(dbOpenTable)
- テーブルレコードの集合を表します。直接テーブルのレコードを追加、更新、削除する時に利用しますが、レコードセットできるのは、ローカルのAccessテーブルのみです。
レコードをセットすると、テーブルビューで開いた状態と同じになり、すべてメモリ内に読み込まれます。目的とするレコードの検索などには重宝しますが、多数のレコードをメモリ上に読み込むので、パフォーマンスの低下の原因になります。 - ■ スナップショットタイプ(dbOpenSnapshot)
- クエリを実行した結果の集まりを表します。このタイプで開くと、読み取り専用となり、レコードの変更はできません。
- ■ ダイナセットタイプ(dbOpenDynaset)
- クエリの実行した結果の集まりを表しますが、レコードの追加、更新、削除などを行えるタイプです。
レコードセットの読み書きが可能なので、一般的に広く利用されます。また、すべてのレコードをメモリ内に一時的に貯め込むことはしません。複数のテーブル、クエリフィールドがある場合、必要なフィールドレコードのみをメモリ内に格納します。
OpenRecordsetメソッド
【書式】 Set オブジェクト変数 = OpenRecordset(ソース[,タイプ][,オプション][,ロック])
- ソース:テーブル名、クエリ名、またはレコードを返すSQLステートメントを指定。
- タイプ:引数のソースに指定したRecordsetの種類を指定。省略した場合は、引数ソースの値に基づいて自動的に設定。
- オプション:Recordsetの特性を定数の組み合わせで指定。省略した場合は、特性は設定されない。
- ロック:Recordsetのロック状態を定数で指定。省略した場合は、dbPessimisticが設定される。
タイプの定数
定数 | 説明 |
dbOpenTable | テーブルタイプのRecordsetオブジェクトを開き、レコードの追加、更新、削除を行う。 |
dbOpenDynamic | 動的タイプのRecordsetオブジェクトを開く。 |
dbOpenDynaset | ダイナセットタイプのRecordsetオブジェクトを開き、1つまたは複数のテーブル、クエリに対して、レコードの追加、更新、削除を行う。 |
dbOpenSnapshot | スナップショットタイプのRecordsetオブジェクトを開くが、読み取り専用となるので、データの検索、レポートの作成に使用する。 |
オプションの定数
定数 | 説明 |
dbAppendOnly | 新しいレコードと追加できるが、既存のレコードの編集や削除はできない。(ダイナセットタイプのみ使用できる) |
dbForwardOnly | 前方スクロールタイプのRecordsetオブジェクトを作成する。(スナップショットタイプのみ使用できる) |
dbReadOnly | 他のユーザからのRecordset変更を拒否する。 |
dbConsistent | 一貫性のある更新のみ可能にする。 |
ロックの定数
定数 | 説明 |
dbReadOnly | ユーザのRecordsetオブジェクトの変更を拒否する。 |
dbPessimistic | 排他的ロックを行う。 |
dbOptimistic | 共有的ロックを行う。 |
dbOptimisticValue | 共有的同時実行を行う。 |
dbOptimisticBatch | バッチ更新を可能にする。 |
レコードセットを開く
データ操作は、Recordsetオブジェクトを用いて、レコードセットを開くことから始まります。このレコードを開くということは、テーブルやクエリを開くのではなく、メモリ上でこれらを開くことを意味します。
◆ テーブルタイプを扱う
テーブルタイプのRecordsetオブジェクトを作成することができるのは、ローカルテーブルのみであることを覚えておきましょう。
まず、以下のような「T_商品リスト」を用意しておきます。

このテーブルのレコードをメモリ上で開いて、どのようなリストであるかをイミディエイトウィンドウで表示させてみます。
※ イミディエイトウィンドウを表示させておきます。操作は、メニュー[表示]-[イミディエイトウィンドウ]をクリック。または、ショートカットキーでCtrl+Gを押します。
《 記述例 》
次のような記述をします。
Sub テーブルリスト() Dim db As dao.Database Dim rs As dao.Recordset Set db = CurrentDb() Set rs = db.OpenRecordset("T_商品リスト", dbOpenTable) Do Until rs.EOF Debug.Print rs!ID & "," & rs!商品名 & ":" & rs!単価 rs.MoveNext Loop rs.Close Set rs = Nothing db.Close Set db = Nothing End Sub
実行すると、以下のような結果を表示します。テーブルのレコードをそのまま表示されていることが確認できます。

※ メモリの解放
レコードセットを開くとメモリ内にデータが読み込まれます。よって、処理を終了する場合は、メモリ上のデータを解放してあげる必要があります。もし、解放しなければパフォーマンスの低下をおこしたり、他のユーザがそのテーブルにフルアクセスできないことが生じます。
Closeメソッドでオブジェクト変数を閉じて、その後、Setステートメントでオブジェクト変数にNothingを代入します。
◆ ダイナセットタイプを扱う
Recordsetオブジェクトの中で用途の高いのがdbOpenDynasetタイプです。ダイナセットタイプは、ローカルテーブルやリンクテーブルのほか、クエリやSQLステートメントでも作成可能です。スナップショットタイプと異なる点は、レコードの追加、更新、削除ができることです。
《 記述例 》
「T_商品リスト」テーブルの定価を1割増しで書き換える記述は以下のようになります。
例1)OpenRecordsetメソッドを使った方法
Sub 単価1割増し() Dim db As DAO.Database Dim rs As DAO.Recordset Set db = CurrentDb() Set rs = db.OpenRecordset("T_商品リスト", dbOpenDynaset) Do Until rs.EOF rs.Edit rs!単価 = rs!単価 * 1.1 rs.Update rs.MoveNext Loop rs.Close: Set rs = Nothing db.Close: Set db = Nothing End Sub
※ Updateメソッド(レコードを更新して保存する)を用いる場合は、事前にEditメソッドでデータを編集することを宣言します。
動作を実行して、「T_商品リスト」テーブルを開くと、単価が1割増しの値段に更新されたことが確認できます。

例2)SQLステートメントを使った方法
SQLステートメントを利用することで、記述を簡潔にすることができます。以下のように記述します。
Sub 単価1割増し2() Dim db As DAO.Database Dim mySQL As String Set db = CurrentDb() mySQL = "UPDATE T_商品リスト set 単価=単価*1.1;" db.Execute mySQL db.Close: Set db = Nothing End Sub
Exicuteメソッドは、DAOでアクションクエリ(この例は更新クエリ)を実行するメソッドになります。選択クエリを選んでしまうとエラーが発生します。結果は、先ほどのOpenRecordsetメソッドと同じ結果となります。
クエリの操作
新規にクエリを作成して、そのクエリからレコードセットを開いて利用するには、CreateQueryDefメソッドを使用します。
CreateQueryDefメソッド
【書式】 Set querydef = object.CreateQueryDef(クエリ名,SQL文)
- クエリ名:新規に作成するクエリ名
- SQL文:クエリの内容をSQLで指定
《 記述例 》
一時的なクエリを作成して、そのクエリを元にRecordsetオブジェクトを作成するには、以下のように記述します。
Sub クエリ作成1() Dim db As DAO.Database Dim rs As DAO.Recordset Dim qry As QueryDef Dim mySql As String Set db = CurrentDb() mySql = "SELECT *, Format(単価*1.05,'0') AS 税込単価 FROM T_商品リスト;" Set qry = db.CreateQueryDef("Q_商品リスト", mySql) Set rs = qry.OpenRecordset Do Until rs.EOF Debug.Print rs!ID & "," & rs!商品名 & ":\" & _ rs!単価 & ":\" & rs!税込単価 rs.MoveNext Loop rs.Close: Set rs = Nothing db.Close: Set db = Nothing End Sub
結果は以下のようにイミディエイトウィンドウに表示されます。ただし、これは新規クエリとして実行されたテーブルの結果となります。実体として作成されるクエリは、モジュールを保存した後、または再びデータベースを開いた時に、表示されます。

《 記述例 》
一時的な更新クエリを作成して、[単価]フィールドの金額を2割引きのレコードとするには、以下のように記述します。
Sub クエリ作成2() Dim db As DAO.Database Dim qry As QueryDef Dim mySql As String On Error GoTo Err_go Set db = CurrentDb() mySql = "UPDATE T_商品リスト SET 単価=[単価]*0.8;" Set qry = db.CreateQueryDef("", mySql) qry.Execute db.Close: Set db = Nothing Exit Sub Err_go: MsgBox Err.Number & ":" & Err.Description End Sub
T_商品リストの単価が8割の値段になっていることが確認できます。


Recordsetオブジェクトのまとめ
Recordsetオブジェクトを使用するには定型文を覚える必要があります。DAOは、まずこの理解度を深めることで働きを知ることができます。
【定型文】
① Dim db As DAO.Database
② Dim rs As DAO.Recordset
③ Set db = CurrentDb()
④ Set rs = db.OpenRecordset("クエリ名")
①と②は、それぞれDatabaseオブジェクトとRecordsetオブジェクトの変数を宣言しています。③と④のSetステートメントは、オブジェクト変数にオブジェクトを関連付ける役割があります。
CurrentDb()関数は、開いているデータベースを返す関数なので、db変数にデータベースそのものを格納します。そして、OpenRecordsetメソッドはrs変数にどのデータの集合体を扱わせるかを指定します。
このように段階的に記述することで、扱わせるデータを指定することになります。