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

VBA_Access

DAO

レコードの移動

レコードセットを作成したということは、メモリ上に複数のでデータを格納したことになりますが、レコードセットを用いて、テーブルやクエリのデータを参照できるのは1レコードだけになります。処理の対象となっているレコードを「カレントレコード」と呼びます。

※ Recordsetオブジェクトを作成した直後のカレントレコードは先頭レコードになる。


目的のレコードを指定するには、Move系メソッドを使用します。

メソッド名 説明
MoveFirst レコードセット内の先頭レコードに移動。
MoveLast レコードセット内の末尾レコードに移動。
MoveNext レコードセット内の次のレコードに移動。
MovePrevious レコードセット内の前のレコードに移動。
Move 移動するレコード数を引数として指定でき、正数は末尾に向かい、負数は先頭に向かって移動。
Moveメソッド

【書式】 Recordset型オブジェクト変数.Move 移動レコード数[,開始位置]

  • 移動レコード数:移動するレコードの数を指定。
  • 開始位置:adBookMarkCurrentが既定値。adBookMarkFirstは先頭レコードを基準、adBookMarkLastが最後のレコードを基準位置とする。
《 記述例 》

テーブルを開いた直後から、レコードを5つ移動させそこからら3つの次のレコードをイミディエイトウィンドウに表示させるには、以下のような記述をします。

	Sub レコードの移動()
		Dim db As DAO.Database
		Dim rs As DAO.Recordset
		Dim i As Integer

		Set db = CurrentDb()
		Set rs = db.OpenRecordset("T_商品リスト", dbOpenTable)
    
		rs.Move 5
    
		For i = 1 To 3
			Debug.Print rs!ID & ":" & rs!商品名 & ":" & rs!単価
			rs.MoveNext
		Next i

		rs.Close: Set rs = Nothing
		db.Close: Set db = Nothing
	End Sub
    

開いた直後は先頭レコードになり、そこから5レコード進み(先頭レコード(1)+ 5=6)、その移動位置から3つのレコードを表示されます。

《 記述例 》

テーブルに格納されているレコードの最後の2件を表示するには、以下のような記述をします。

	Sub 最後から2件のレコード()
		Dim db As DAO.Database
		Dim rs As DAO.Recordset
		Dim i As Integer

		Set db = CurrentDb()
		Set rs = db.OpenRecordset("T_商品リスト", dbOpenTable)
    
		rs.MoveLast
    
		For i = 1 To 2
			Debug.Print rs!ID & "," & rs!商品名 & ":\" & rs!単価
			rs.MovePrevious
		Next i

		rs.Close: Set rs = Nothing
		db.Close: Set db = Nothing
	End Sub
    

イミディエイトウィンドウにレコードの末尾から2件のレコードが表示されます。

◆ BOFプロパティとEOFプロパティ

レコード数は、どのデータベースでも有限です。例えば、Moveメソッドでテーブルに10件しかレコードがない場合、移動数を「20」などとして指定するとエラーが発生し、以下のようなエラーメッセージが表示されます。

このメッセージは、レコードセットの範囲外(エラーナンバー3201)であることを意味するエラーになります。一般的にはエラートラップ処理を記述して、エラー対処する必要があります。


DAOのレコードセットでは、カレントレコードが先頭なのか、末尾なのかを判断できるBOFプロパティと、EOFプロパティが用意されています。
これらのプロパティは、Recordsetオブジェクトにレコードが格納されているか、またはレコードセットの範囲内であるかを確認する時に利用します。

■ BOFプロパティ
BOFプロパティ(Bigin Of File)は、カレントレコードの位置がRecordsetオブジェクトの先頭のレコードより前にあるかどうかを判定する時に利用します。
先頭レコードよりも前に移動した時はTrue(-1)を返し、それ以外はFalse(0)を返します。
■ EOFプロパティ
EOFプロパティ(End Of File)は、カレントレコードの位置がRecordsetオブジェクトの末尾のレコードより後にあるかどうかを判定する時に利用します。
最後のレコードよりも後ろに移動した時はTrue(-1)を返し、それ以外はFalse(0)を返します。
【BOFプロパティとEOFプロパティの留意点】
  • BOFプロパティ、またはEOFプロパティがTrue(-1)の時は、カレントレコードは未定義の状態であり、処理はできない。
  • BOFプロパティとEOFプロパティの両方ともTrue(-1)の時は、Recordsetオブジェクトにはレコードが1つもないことになります。
  • レコードセットの範囲外を指定すると、エラーが発生する。
《 記述例 》

T_商品リストの商品名と単価をメッセージ表示するには、以下のように記述します。

	Sub テーブルデータの書き出し()
		Dim db As dao.Database
		Dim rs As dao.Recordset
		Dim dataMsg As String

		Set db = CurrentDb()
		Set rs = db.OpenRecordset("T_商品リスト")
    
		Do Until rs.EOF
			dataMsg = dataMsg & rs!商品名 & ":\" & rs!単価 & vbNewLine
			rs.MoveNext
		Loop
    
		MsgBox dataMsg, , "T_商品リスト表示"
		
		rs.Close: Set rs = Nothing
		db.Close: Set db = Nothing
	End Sub
    

T_商品リストのすべての商品名と単価を表示するために、EOFプロパティを利用し、EOFプロパティがTrueになるまで1件ずつレコードを表示する処理となります。

カレントレコードの編集

Recordsetオブジェクトを作成して、レコードの編集を行うにはEditメソッド、Updateメソッドを使用します。但し、レコードを編集できるのはテーブルタイプ、ダイナセットタイプのRecordsetオブジェクトになり、スナップショットタイプは読み取り専用なので編集はできません。

◆ EditメソッドとUpdateメソッド

現在読み込まれているレコードに対してEditメソッドを実行すると、そのレコードの編集ができるようになります。しかし、Editメソッドを実行して編集しただけでは、実際のレコードの更新は行われません。
編集した内容を反映するにはUpdateメソッドを実行します。よって、Updateメソッドは更新した内容を保存する処理することになります。
編集する内容をEditメソッドとUpdateメソッドの間に記述するのが基本形となります。

《 記述例 》

DMテーブルのDM題名の前に記号(■)を付加するには、次のように記述します。

	Sub DM題名変更()
		Dim db As DAO.Database
		Dim rs As DAO.Recordset

		Set db = CurrentDb()
		Set rs = db.OpenRecordset("DMテーブル")
    
		Do Until rs.EOF
			rs.Edit
			rs!DM題名 = "■ " & rs!DM題名
			rs.Update
			rs.MoveNext
		Loop
    
		rs.Close: Set rs = Nothing
		db.Close: Set db = Nothing
	End Sub
    

すべてのレコードを編集するので、カレントレコードを移動する必要があります。Do Until Loopステートメントですべてのレコードを一度カレントレコードにして編集します。

留意点として、レコードを更新する際は警告メッセージが表示されないので、Ifステートメントを利用して、更新するかどうかのメッセージを作成した方が良いでしょう。