トップ > スキル : アプリケーション > VBA for Access > 応用編(データベースオブジェクト DAOとADO)
レコードの移動
レコードセットを作成したということは、メモリ上に複数のでデータを格納したことになりますが、レコードセットを用いて、テーブルやクエリのデータを参照できるのは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ステートメントを利用して、更新するかどうかのメッセージを作成した方が良いでしょう。

