トップ > スキル : アプリケーション > VBA for Access > 応用編(データベースオブジェクト DAOとADO)

VBA_Access

DAO

データを操作する

データを操作するための基本となるオブジェクトは、レコードを操作する対象となる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変数にどのデータの集合体を扱わせるかを指定します。

このように段階的に記述することで、扱わせるデータを指定することになります。