【特集】ADOのRecordset オブジェクトを極めよう

【特集】ADOのRecordset オブジェクトを極めよう

 

はじめに

Access VBAを学び始めたばかりのあなた、あるいは既にいくつかのプロジェクトを手掛けてきた中級者の方々へ。

ご承知のようにデータベース操作の世界では、データの扱い方がそのアプリケーションの性能を大きく左右します。

特にMicrosoft Accessでは、VBA (Visual Basic for Applications) と ADO (ActiveX Data Objects) の組み合わせで非常に強力なデータ管理が実現できます。

この記事では、初級者から中級者の方々がAccess VBAエキスパート試験勉強、あるいは日々の開発作業に役立てることを目的として、ADOを用いたデータベース操作の基礎から応用まで、実践的なコード例とともに解説しています。

あなたも ADO Recordsetオブジェクトのプロパティとメソッドを極め、さらなる高みへ昇りませんか。

ADO (ActiveX Data Objects) とは

ADO は(ActiveX Data Objects)の略で、データベースやその他のデータソースにアクセスし、操作するためのオブジェクトです。

Microsoft Access や Excel などのアプリケーションの中で Visual Basic for Applications (VBA)からこのADOを利用すると、データソースへの接続、データの抽出、操作、および更新を簡単に行うことができます。

Recordset とは

このADOではデータサーバーからクライアントのメモリ空間に以下のようなレコードの集まりを取得し、このレコードセットに対し追加・更新・削除等の操作を実施することができます。

【特集】ADOのRecordset オブジェクトを極めよう
レコードセット

Recordsetのプロパティの概要

Recordsetには次のようなプロパティがあります。

プロパティ名 説明
BOF
(Beginning Of File)
カレントレコードが最初のレコードより前にあるかどうかを判定するために使用されます。具体的にはレコードセットの現在位置が最初のレコードより前にある場合に True 、それ以外は Falseを返します。
EOF
(End Of File)
カレントレコードが最後のレコードより後にあるかどうかを判定するために使用されます。具体的にはレコードセットの現在位置が最後のレコードより後にある場合に True 、それ以外は Falseを返します。
RecordCount レコードセットに含まれるレコードの件数を返します。
CursorType レコードセットのカーソルタイプを指定します。これにより、レコードセットをどのようにナビゲート(移動)できるか(例: 前方のみ、ランダムアクセス)が決まります。
CursorLocation カーソルの場所を指定します。主にクライアントサイド(adUseClient)かサーバーサイド(adUseServer)かを選択します。
LockType レコードセットのロックタイプを指定します。これは、レコードセットがデータに対してどのような編集権限を持つかを定義します。
Source レコードセットがアクセスするデータのソース(SQLクエリやテーブル名など)を指定します。
Bookmark レコードセット内の特定のレコードに簡単に戻れるようにするためのマーカーです。このプロパティを利用すると、開発者はレコードセット内の任意の位置に「ブックマーク」を設定し、後からその位置に直接ジャンプすることができます。
【特集】ADOのRecordset オブジェクトを極めよう
しらかば堂

この「カーソル」とは、レコードセット内の現在の位置を指す示す仮想的なポインタのことです。
開発者目線でこの「カーソル」について考えると
まずデータベースへのクエリ操作を実行する主体をクライアント側におくのか、それともサーバ側におくのかということを決め
次にその主体上でこのカーソルをどう動かし、特定のレコードにアクセスしたり、レコードセット内を前後に移動するかということを決める必要があります。

【特集】ADOのRecordset オブジェクトを極めよう
しらかば堂

また「ロック」は、データベース内のレコードやリソースへのアクセスを制御する仕組みのことですが、サーバ側のデータベースに同時に複数のユーザーがアクセスしている状況下でデータベースの整合性を保証するためにこれもうまく利用する必要があります。

Recordsetのメソッドの概要

Recordsetには次のようなメソッドがあります。

メソッド名 説明
Open レコードセットを開きます。ソース、接続、カーソルタイプ、ロックタイプなどを指定できます。
Close 開かれているレコードセットを閉じます。
MoveFirst カーソルを最初のレコードに移動します。
MoveLast カーソルを最後のレコードに移動します。
MoveNext カーソルを一つ後ろに移動します。
MovePrevious カーソルを一つ前に移動します。
Find レコードセット内で特定の基準に一致するレコードを検索するために使用します。このメソッドは、指定された基準に最初に一致するレコードを見つけた場合、レコードセットのカレントレコードをそのレコードに移動します。
条件に一致するレコードが見つからない場合は、レコードセットのカレントレコードは変更されません。
Clone 既存のレコードセットの完全なコピーを作成します。
AddNew 新しいレコードを作成し、編集モードに入ります。
Update 編集中のレコードの変更を保存します。
Delete 現在のレコードを削除します。

Recordsetプロパティの詳細

それでは以下のプロパティについて順にご紹介していきましょう

  • BOF(Beginning Of File)
  • EOF(End Of File)
  • RecordCount
  • CursorType
  • CursorLocation
  • LockType
  • Source
  • Bookmark

BOF(Beginning Of File)

カレントレコードが最初のレコードより前にあるかどうかを判定するために使用されます。

具体的にはレコードセットの現在位置が最初のレコードより前にある場合に True 、それ以外は Falseを返します。

通常、BOF EOF (End Of File) プロパティは以下のようにセットで使用されることが多いですが、これらを利用するとレコードセットがであるかどうかをチェックすることができます。

Sub CheckIfRecordsetIsEmpty()
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim sql As String
    
    ' ADO オブジェクトの初期化
    Set conn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    
    ' 接続文字列の設定 (サンプルとして Access データベースを使用)
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open
    
    ' SQL クエリ (適宜変更してください)
    sql = "SELECT * FROM テーブル名"
    
    ' レコードセットを開く
    rs.Open sql, conn, adOpenStatic, adLockReadOnly
    
    ' BOF と EOF が両方 True であれば、レコードセットは空です
    If rs.BOF And rs.EOF Then
        MsgBox "レコードセットは空です。", vbInformation, "結果"
    Else
        MsgBox "レコードセットにはデータが含まれています。", vbInformation, "結果"
    End If
    
    ' クリーンアップ
    rs.Close
    conn.Close
    Set rs = Nothing
    Set conn = Nothing
End Sub

EOF(End Of File)

カレントレコードが最後のレコードより後にあるかどうかを判定するために使用されます。

具体的にはレコードセットの現在位置が最後のレコードより後にある場合に True 、それ以外は Falseを返します。

以下に データベースからレコードを取得し、EOF (End Of File) プロパティを使用してレコードセットをループ処理する基本的な VBA コードの例を以下に示します。

この例では、データベース接続を開設し、SQL クエリを実行してレコードセットを取得し、EOF プロパティを使用してすべてのレコードをループ処理します。

ループ内で各レコードの内容を処理し、最後にデータベース接続を閉じます。

Sub FetchDataWithADO()
' ADO オブジェクトを宣言
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sql As String

' 新しい接続オブジェクトのインスタンスを作成
Set conn = New ADODB.Connection
' 新しいレコードセットオブジェクトのインスタンスを作成
Set rs = New ADODB.Recordset

' データベース接続文字列 (ここでは例として Access データベースを使用)
' 実際のパス、データベース名、接続設定に応じて調整してください
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"

' 接続を開く
conn.Open

' 実行する SQL 文 (例としてテーブルからすべてのレコードを選択)
sql = "SELECT * FROM テーブル名"

' SQL クエリを実行し、レコードセットを開く
rs.Open sql, conn, adOpenStatic, adLockReadOnly

' レコードセットのEOFプロパティをチェックして、全レコードをループ処理
Do Until rs.EOF
' ここで各レコードに対する処理を行う
' 例: フィールドの値を取得して表示
Debug.Print rs.Fields("フィールド名").Value

' 次のレコードに移動
rs.MoveNext
Loop

' レコードセットと接続を閉じる
rs.Close
conn.Close

' オブジェクトの解放
Set rs = Nothing
Set conn = Nothing
End Sub

RecordCount

レコードセットに含まれるレコードの件数を返します。

ただし、他のユーザーによるレコード追加、削除等の影響を避け、正確なレコード数を取得するには、対象とするレコードセットは adOpenStatic または adOpenKeyset のカーソルタイプで開かれている必要があります。

ここでは、データベースからレコードセットを取得し、そのレコード数を表示する基本的な VBA コードの例を示します。

Sub ShowRecordCount()
    ' ADO オブジェクトを宣言
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim sql As String
    
    ' 新しい接続オブジェクトのインスタンスを作成
    Set conn = New ADODB.Connection
    ' 新しいレコードセットオブジェクトのインスタンスを作成
    Set rs = New ADODB.Recordset
    
    ' データベース接続文字列
    ' 実際のパス、データベース名、接続設定に応じて調整してください
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    
    ' 接続を開く
    conn.Open
    
    ' 実行する SQL 文
    sql = "SELECT * FROM テーブル名"
    
    ' SQL クエリを実行し、レコードセットを開く (静的カーソルと読み取り専用ロックを指定)
    rs.Open sql, conn, adOpenStatic, adLockReadOnly
    
    ' レコードセット内のレコードの総数を取得
    If rs.RecordCount > 0 Then
        MsgBox "レコードの総数: " & rs.RecordCount, vbInformation, "レコード数"
    Else
        MsgBox "レコードが見つかりません。", vbExclamation, "レコード数"
    End If
    
    ' レコードセットと接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub

CursorType

レコードセットのカーソルタイプは以下の定数を使って指定します。
これにより、レコードセットをどのようにナビゲート(移動)できるかが決まります。

定数 説明 用途

adOpenForwardOnly
(既定値)

前方向への移動のみが可能な、最も高速なカーソルタイプです。
このカーソルタイプは、データをシーケンシャルに最初から最後まで移動することしかできません。

データを一方向にのみ読み取る場合や、大量のデータを効率的に処理する必要があるバッチ処理やデータのインポート/エクスポート時に最適です。

例えば、ログファイルの解析や大規模なデータセットの一括処理など
adOpenKeyset

キーセットカーソルを利用するカーソルタイプでで、レコードを全ての方向に移動できます。
他のユーザーによるデータベースヘの追加や削除は見えません。

ユーザーがデータを更新する可能性があるが、データセット全体の構造(例: 行の追加や削除)は変わらないアプリケーションで有効です。

例えば、一覧表示から選択したレコードの詳細を更新する場合など
adOpenDynamic

動的カーソルを利用するカーソルタイプで、レコードを全ての方向に移動できます。
また他のユーザーによるデータベースヘの変更がリアルタイムで反映され
また他のユーザーがレコードセットを開いている間に、追加、削除、および更新が可能です。
このカーソルタイプは最も柔軟性がありますが、その分パフォーマンスが犠牲になるケースがあります。

リアルタイムでのデータ変更を反映させたいマルチユーザーアプリケーションや、高度にインタラクティブなアプリケーションで有用です。

例えば、在庫管理システムやリアルタイムの予約システムなど
adOpenStatic

静的カーソルを使用し、レコードを全ての方向に移動できます。
このカーソルタイプでは、レコードセットを開く際、データベースの静的なスナップショットを取得し、それをスクロール、参照および更新に利用します。
つまりレコードセットを開く際データベースから完全に分離したコピーをメモリ中に作成するため、他のユーザーによるデータベースの変更がレコードセットに影響を与えないようにすることができます。

データの変更を追跡する必要がなく、データセット全体を一度に表示または処理する必要がある場合に適しています。

例えばレポート生成やデータ分析時に、データの一貫性を保ちたい場合など
【特集】ADOのRecordset オブジェクトを極めよう
しらかば堂

キーセットカーソル」は、レコードセットの作成時にレコードの主キーを使用して、内部的に作成したキーセット(キーの集合)を通じてレコードセット内のデータにアクセスし、データのナビゲーション(移動)を行います。

【特集】ADOのRecordset オブジェクトを極めよう
しらかば堂

スナップショット」は、データソースからレコードセットを作成した時点の状態をキャプチャしたものです。従ってそのスナップショット上に無いデータソース上の変更を見ることはできません。

それでは以下に、具体的なVBAコードの記述例を見てみましょう。

adOpenForwardOnly (前方専用カーソル)

Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM YourTable", CurrentProject.Connection, adOpenForwardOnly

adOpenKeyset (キーセットカーソル)

Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM YourTable", CurrentProject.Connection, adOpenKeyset

adOpenDynamic (ダイナミックカーソル)

Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM YourTable", CurrentProject.Connection, adOpenDynamic

adOpenStatic (スタティックカーソル)

Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM YourTable", CurrentProject.Connection, adOpenStatic

CursorLocation

以下の図に示されるカーソルの場所をクライアントサイド(adUseClient)かサーバーサイド(adUseServer)かで選択します。

【特集】ADOのRecordset オブジェクトを極めよう
CursolLocationの違い
定数 説明 用途
adUseServer
(既定)

サーバー側(つまり、SQL Serverや他のAccessデータベース等データベースがホストされているサーバー)のカーソルを使用します。
データの操作やクエリ処理はすべてサーバー側で行われ、必要なデータのみがクライアントに送信されます。

オンライン取引システムや予約システムのように、リアルタイムでデータの更新が行われる環境では、サーバーサイドカーソルを使用してデータベースとの通信を最適化し、最新の情報を迅速に取得することが望ましいと言えます。
adUseClient

クライアント側(つまり、クライアントの役割を持ったAccessアプリケーションが動作しているコンピュータ)のカーソルを使用します。
これにより、アプリケーションはRecordsetオブジェクトをOpen時にデータベースサーバからクライアント側へデータを一度にダウンロードし、その後の操作(フィルタリング、ソート、レコードのナビゲーションなど)をクライアント側で行います。

大量のデータを取得してクライアント側で複雑なデータ操作が必要な場合(例えば、レポート生成やデータ分析)、クライアントサイドカーソルの使用が適しています。

データセット全体に対して操作を行い、ネットワーク通信のオーバーヘッドを減らすことができます。

adUseClient 選択による メリット・デメリット

上述のように adUseClient の指定がされると、RecordsetオブジェクトをOpen時に、対象となるテーブルのデータが最初にクライアント側にコピーされます。

つまりデータセット全体がクライアント側のメモリ上に読み込まれるため、Access等のアプリケーションからの直接操作が可能になり、結果として高速になります。

このようにadUseClient の利用は大量のデータをローカルで扱うことができるメリットがある一方、以下のようなデメリットもあります。

初期のデータ取得時間: 特にネットワーク経由で大量のデータを転送する場合、最初にRecordset全体をクライアント側にコピーするのに時間がかかります。

リソース消費: adUseClientを選択した場合の処理能力はクライアント側のメモリや処理能力に依存するため、大量のデータを扱う際には、クライアントのシステムリソースに十分な余裕があることを事前に確認しておく必要があります。 `

adUseClient(クライアントサイドカーソル)

クライアントサイドカーソルを使用する場合は、CursorLocation プロパティを adUseClient に設定します。この設定は、特に大量のデータに対して複雑なフィルタリングやソートを行いたい場合や、データセットをアプリケーション側で頻繁に操作する場合に適しています。

Sub FetchDataWithClientSideCursor()
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim sql As String
    
    Set conn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open
    
    ' クライアントサイドカーソルを使用
    conn.CursorLocation = adUseClient
    
    sql = "SELECT * FROM テーブル名"
    rs.Open sql, conn, adOpenStatic, adLockReadOnly
    
    ' ここでレコードセットを利用した処理を行う
    
    rs.Close
    conn.Close
    Set rs = Nothing
    Set conn = Nothing
End Sub

adUseServer(サーバーサイドカーソル)

サーバーサイドカーソルを使用する場合は、CursorLocation プロパティを adUseServer に設定します。この設定は、データのリアルタイムの更新が重要な場合や、ネットワークトラフィックを最小限に抑えたい場合に適しています。

Sub FetchDataWithServerSideCursor()
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim sql As String
    
    Set conn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open
    
    ' サーバーサイドカーソルを使用
    conn.CursorLocation = adUseServer
    
    sql = "SELECT * FROM テーブル名"
    rs.Open sql, conn, adOpenDynamic, adLockOptimistic
    
    ' ここでレコードセットを利用した処理を行う
    
    rs.Close
    conn.Close
    Set rs = Nothing
    Set conn = Nothing
End Sub

LockType

レコードセットのロックタイプを指定します。これは、レコードセットがデータに対してどのような編集権限を持つかを以下の定数を使って定義します。

このプロパティの選択は、アプリケーションの要件、データベースのパフォーマンス、データの整合性のニーズに応じて慎重に行う必要があります。

 

定数 説明 用途
adLockReadOnly
(既定)

このLockTypeは、読み取り専用のレコードセットを作成します。
他のユーザーからの変更を許可せず、データを読み取ることだけができます。

データの読み出しのみを行う場合に適しています。
adLockPessimistic

このLockTypeは、レコードを読み取り専用または編集可能モードでロックします。レコードを編集中に他のユーザーが同じレコードをロックできなくなります。
データの整合性を維持するのに役立ちます。

データの整合性を保ちたい場合に適しています。

adLockOptimistic

このLockTypeは、レコードを読み取り専用モードでロックし、編集中に他のユーザーが同じレコードを編集できるようにします。
データの整合性はコードで制御され、変更はデータベースにコミットされるまで確定されません。

多くのユーザーが同時にデータを読み込むが、更新は頻繁ではない場合に適しています。

adLockBatchOptimistic

このLockTypeは、楽観的ロックの一種で、データベースに対するコミットはバッチ単位で行われます。

 

複数のレコードをバッチとして操作する場合に適しています。

 

それでは以下具体的なVBAのコーディング例をご紹介します。

adLockReadOnly (読み取り専用ロック):

Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM YourTable", CurrentProject.Connection, , , adLockReadOnly

 

adLockPessimistic (悲観的ロック):

Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM YourTable", CurrentProject.Connection, , , adLockPessimistic

 

adLockOptimistic (楽観的ロック):

Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM YourTable", CurrentProject.Connection, , , adLockOptimistic

 

adLockBatchOptimistic (バッチ楽観的ロック):

Dim rs As Object
Set rs = CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM YourTable", CurrentProject.Connection, , , adLockBatchOptimistic

 

CursorType と LockType の組み合わせ

ここでは以下の利用シーンにて利用されるフォーム、アプリケーション等がデータベースへのアクセスの際に選択することが期待されるCursorType(カーソルタイプ)とLockType(ロックタイプ)の最適な組み合わせについて紹介します。

シナリオ 選択すべき
CursorType

選択すべき
LockType

説明
一般利用者が読み取り専用でデータレコードを参照するフォーム、DBアクセス手順を実装したい。 adOpenForwardOnly (不要) 一般利用者が利用するフォーム、DBアクセス手順はデータレコードを読み取るだけなので、ロックは不要です。読み取り専用のアクセスに最適で、効率的です。
一般利用者が読み取り専用でデータレコードを参照中に別の一般利用者がデータレコードを編集するフォーム、DBアクセス手順を実装したい。 adOpenKeyset adLockOptimistic 編集者が編集画面でデータベースを編集する際、adLockOptimisticを使用すると、ユーザーBが編集しても一般利用者の参照がブロックされません。
データベースの整合性を確保する上で重要なので
一般利用者がデータレコードを参照できないよう規制し、排他的に編集者としてデータレコードの一部を編集するフォーム、DBアクセス手順を実装したい。
adOpenKeyset adLockPessimistic

このフォーム、DBアクセス手順を利用すると、対象となるレコードセットに排他制御がかかるので

ある利用者がデータを排他的に編集している間、他の一般利用者はこのデータを参照することができません。

管理者として夜間バッチ処理で一括してデーターレコードの編集するフォーム、DBアクセス手順を実装したい。 adOpenStatic adLockBatchOptimistic このフォーム、DBアクセス手順の利用者が夜間バッチ一括等でで対象レコードセットの編集を行っている間、他の一般利用者は当該レコードセットヘの参照ができない。

 

Source

Source プロパティを使用すると、レコードセットのデータソースとして SQL クエリ文字列やテーブル名を指定できます。このプロパティを使用することで、プログラム的にレコードセットを開く前に、そのデータソースを動的に設定または変更することが可能になります。
以下は、Source プロパティを利用した VBA コードの例です。

この例では、特定のテーブルからデータを取得し、その内容を Excel のシートに出力するプロセスを実装しています。

Sub FetchAndDisplayData()
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim sqlQuery As String
    Dim ws As Worksheet
    Dim row As Integer
    
    ' 新しい接続とレコードセットオブジェクトのインスタンスを作成
    Set conn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    
    ' 接続文字列の設定 (例として Access データベース)
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    
    ' 接続を開く
    conn.Open
    
    ' SQL クエリ文字列
    sqlQuery = "SELECT * FROM あなたのテーブル名"
    
    ' Source プロパティと接続を使用してレコードセットを開く
    rs.Source = sqlQuery
    rs.Open , conn, adOpenStatic, adLockReadOnly
    
    ' Excel シートの初期化
    Set ws = ThisWorkbook.Sheets("Sheet1")
    ws.Cells.Clear
    row = 1
    
    ' レコードセットをループして、Excel シートにデータを出力
    Do While Not rs.EOF
        For i = 0 To rs.Fields.Count - 1
            ws.Cells(row, i + 1).Value = rs.Fields(i).Value
        Next i
        row = row + 1
        rs.MoveNext
    Loop
    
    ' レコードセットと接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub


このコードでは、まず接続 (ADODB.Connection) とレコードセット (ADODB.Recordset) オブジェクトを作成します。その後、接続文字列を設定してデータベースへの接続を開き、SQL クエリを Recordset Source プロパティに設定します。Open メソッドを呼び出す際に Source プロパティと接続オブジェクトを使用することで、レコードセットを開いてデータを取得します。最後に、取得したデータを Excel シートに出力し、使用したリソースを適切にクローズして解放します。

この例では、Source プロパティを利用してデータソース(この場合は SQL クエリ)を指定し、そのデータを Excel に出力しています。Source プロパティの使用により、データソースを柔軟に指定し、動的に変更することができるため、様々なシナリオでのデータ操作が可能になります。

Bookmark

Bookmark プロパティを使用すると、レコードセット内の特定のレコードにマーカーを設置して、後でその位置に簡単に戻ることができます。

これは、ユーザーがデータベースのレコードをブラウズしているときや、特定のレコード処理後に元の位置に戻りたい場合などに非常に便利です。

以下は、Bookmark プロパティを使用した基本的な VBA コードの例ですが

レコードセットからデータを取得し、特定の条件を満たす最初のレコードに Bookmark を設定してから、別の操作を行った後にその Bookmark 位置に戻しています。

Sub UseBookmark()
    Dim conn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Dim myBookmark As Variant
    
    ' 新しい接続とレコードセットオブジェクトのインスタンスを作成
    Set conn = New ADODB.Connection
    Set rs = New ADODB.Recordset
    
    ' 接続文字列の設定 (例として Access データベース)
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open
    
    ' レコードセットの開く
    rs.Open "SELECT * FROM あなたのテーブル名", conn, adOpenKeyset, adLockOptimistic
    
    ' レコードセットを走査し、特定の条件を満たすレコードに到達したら Bookmark を設定
    Do Until rs.EOF
        If rs.Fields("あなたの条件フィールド名").Value = "特定の値" Then
            ' Bookmark を設定
            myBookmark = rs.Bookmark
            Exit Do
        End If
        rs.MoveNext
    Loop
    
    ' 他の処理を行う...
    
    ' Bookmark が設定されていれば、その位置に戻る
    If Not IsEmpty(myBookmark) Then
        rs.Bookmark = myBookmark
        ' Bookmark 位置のレコードに対して何らかの処理を行う
        Debug.Print "戻った位置のレコード: " & rs.Fields("あなたの条件フィールド名").Value
    End If
    
    ' レコードセットと接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub


このVBAコードでは、最初にデータベースへの接続を開設し、指定されたSQLクエリを用いてレコードセットを開きます。

その後、ループを使用してレコードセットを走査し、条件に一致するレコードに到達したらその位置に Bookmark を設定します。別の操作を行った後、Bookmark を使用して元のレコード位置に戻り、必要ならそのレコードに対して追加の操作を行います。

このように、Bookmark プロパティを使用することで、大きなデータセット内でユーザーが特定のレコード位置を簡単に記憶し、後でそこに戻ることができます。

これは、複雑なデータベースアプリケーションやユーザーが頻繁にデータをナビゲートする必要があるアプリケーションで特に便利です。

Recordsetメソッドの詳細

ここではRecordsetオブジェクトに含まれる以下のメソッドについて詳細にご紹介します。

  • Open メソッド
  • Close メソッド
  • MoveFirst/MoveLast/MoveNext/ メソッド
  • MovePrevious メソッド
  • Find メソッド
  • Clone メソッド
  • AddNew メソッド
  • Update メソッド
  • Delete メソッド

Open メソッド

Open メソッドと Close メソッドは、データベースのレコードセットを操作するための基本的なメソッドであり

これらを使って、データベースからデータを取得したり、レコードセットを閉じてリソースを解放したりします。

ここでは、これらのメソッドの役割と使い方をわかりやすく説明します。

 

定数 説明 用途
adLockReadOnly
(既定)

このLockTypeは、読み取り専用のレコードセットを作成します。
他のユーザーからの変更を許可せず、データを読み取ることだけができます。

データの読み出しのみを行う場合に適しています。
adLockPessimistic

このLockTypeは、レコードを読み取り専用または編集可能モードでロックします。レコードを編集中に他のユーザーが同じレコードをロックできなくなります。
データの整合性を維持するのに役立ちます。

データの整合性を保ちたい場合に適しています。

adLockOptimistic

このLockTypeは、レコードを読み取り専用モードでロックし、編集中に他のユーザーが同じレコードを編集できるようにします。
データの整合性はコードで制御され、変更はデータベースにコミットされるまで確定されません。

多くのユーザーが同時にデータを読み込むが、更新は頻繁ではない場合に適しています。

adLockBatchOptimistic

このLockTypeは、楽観的ロックの一種で、データベースに対するコミットはバッチ単位で行われます。

 

複数のレコードをバッチとして操作する場合に適しています。

 

 

定数 説明 用途
adLockReadOnly
(既定)

このLockTypeは、読み取り専用のレコードセットを作成します。
他のユーザーからの変更を許可せず、データを読み取ることだけができます。

データの読み出しのみを行う場合に適しています。
adLockPessimistic

このLockTypeは、レコードを読み取り専用または編集可能モードでロックします。レコードを編集中に他のユーザーが同じレコードをロックできなくなります。
データの整合性を維持するのに役立ちます。

データの整合性を保ちたい場合に適しています。

adLockOptimistic

このLockTypeは、レコードを読み取り専用モードでロックし、編集中に他のユーザーが同じレコードを編集できるようにします。
データの整合性はコードで制御され、変更はデータベースにコミットされるまで確定されません。

多くのユーザーが同時にデータを読み込むが、更新は頻繁ではない場合に適しています。

adLockBatchOptimistic

このLockTypeは、楽観的ロックの一種で、データベースに対するコミットはバッチ単位で行われます。

 

複数のレコードをバッチとして操作する場合に適しています。

 

 

定数 説明 用途
adLockReadOnly
(既定)

このLockTypeは、読み取り専用のレコードセットを作成します。
他のユーザーからの変更を許可せず、データを読み取ることだけができます。

データの読み出しのみを行う場合に適しています。
adLockPessimistic

このLockTypeは、レコードを読み取り専用または編集可能モードでロックします。レコードを編集中に他のユーザーが同じレコードをロックできなくなります。
データの整合性を維持するのに役立ちます。

データの整合性を保ちたい場合に適しています。

adLockOptimistic

このLockTypeは、レコードを読み取り専用モードでロックし、編集中に他のユーザーが同じレコードを編集できるようにします。
データの整合性はコードで制御され、変更はデータベースにコミットされるまで確定されません。

多くのユーザーが同時にデータを読み込むが、更新は頻繁ではない場合に適しています。

adLockBatchOptimistic

このLockTypeは、楽観的ロックの一種で、データベースに対するコミットはバッチ単位で行われます。

 

複数のレコードをバッチとして操作する場合に適しています。

 

rs.Open Source, ActiveConnection, CursorType, LockType, Options


このOpen メソッドのパラメータは以下の通りです。

パラメータ
番号
説明 意味
1

Source

Sourceプロパティで指定可能
レコードセットがアクセスするデータのソースを指定します。これは SQL クエリの文字列、テーブル名、またはストアドプロシージャの名前であることが多いです。
2

ActiveConnection

レコードセットがデータを取得するために使用する Connection オブジェクトを指定します。これは、既に開かれている接続の Connection オブジェクト、または接続文字列です。

3

CursorType

CursorTypeプロパティで指定可能
レコードセットが使用するカーソルの種類を指定します。カーソルタイプによって、レコードセットのナビゲーション方法や、他のユーザーによるデータ変更の可視性などが決まります。

4

LockType

LockTypeプロパティで指定可能
レコードセットのロックの種類を指定します。これにより、レコードセットを通じてデータを更新する際のロックの挙動が決まります。

5

Options

レコードセットの開き方をさらに細かく制御するためのオプションを指定します。たとえば、コマンドタイプを指定したり、非同期でのオープンを指定することができます。
【例】
adCmdText(SQL 文字列が直接渡される)
adCmdTable(テーブル名が直接渡される)
adCmdStoredProc(ストアドプロシージャの呼び出し)


これらのパラメータを設定するやり方には次の3通りのやり方があります

  • Open メソッドのパラメータとして全て指定
  • Open メソッドのパラメータとして部分的に指定
  • Open メソッドのパラメータとして全く指定しない

の3つのシナリオがあるので、この3つのシナリオについてご紹介しておきます。

Open メソッドのパラメータとして全て指定

このやり方ではOpenメソッドのステートメントの中で
SourceActiveConnectionCursorTypeLockTypeOptions
といった全てのパラメータを明示的に指定します。

Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset

' データベースへの接続を開く
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"

' レコードセットを開く(パラメータを全て指定)
rs.Open "SELECT * FROM あなたのテーブル名", conn, adOpenStatic, adLockReadOnly, adCmdText

' 処理...

' レコードセットと接続を閉じる
rs.Close
conn.Close

Open メソッドのパラメータとして部分的に指定する場合

標準的なパターンでパラメータを部分的に指定する場合、一般的には Open メソッドで Source ActiveConnection を直接指定し、CursorType LockType はデフォルトの値を使用するか、あらかじめ Recordset オブジェクトのプロパティとして設定しておく方法があります。

これにより、データソースと接続情報を明確に指定しつつ、カーソルの挙動やロックの種類に関しては、必要に応じてカスタマイズできます。

この例では、Openメソッドのステートメントの中でカーソルのタイプやロックのタイプは指定せずに、あらかじめ Recordset オブジェクトのプロパティとして設定された値を使用しています。

Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset

' データベースへの接続を開く
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
conn.Open

' レコードセットのプロパティを事前に設定
rs.CursorType = adOpenStatic ' カーソルタイプを静的カーソルに設定
rs.LockType = adLockReadOnly ' ロックタイプを読み取り専用に設定

' レコードセットを開く(Source と ActiveConnection のみを指定)
rs.Open "SELECT * FROM あなたのテーブル名", conn

' レコードセットのデータを処理する...

' レコードセットと接続を閉じる
rs.Close
conn.Close

パラメータを全く指定しない場合

Recordset オブジェクトを使用して、後からSQLクエリを指定する場合など、Open メソッドをパラメータなしで使用することも可能です。その後、Source プロパティや ActiveConnection プロパティを設定してからデータをロードします。

この例では、Open メソッドを呼び出す前に、レコードセットのプロパティ ActiveConnection, Source, CursorType, LockTypeを設定しています。これにより、Open メソッドをパラメータなしで呼び出しています。

Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset

' データベースへの接続を開く
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"

' 新しいレコードセットのインスタンスを生成
Set rs = New ADODB.Recordset

' レコードセットのプロパティを設定
rs.ActiveConnection = conn
rs.Source = "SELECT * FROM あなたのテーブル名"
rs.CursorType = adOpenStatic
rs.LockType = adLockReadOnly

' レコードセットを開く
rs.Open

' 処理...

' レコードセットと接続を閉じる
rs.Close
conn.Close

Close メソッド

Close メソッドは、開かれているレコードセットを閉じるために使用されます。レコードセットを閉じると、そのレコードセットが使用していたリソースが解放され、データベースへの接続が閉じられます(レコードセットが単独で接続を管理している場合)。レコードセットを閉じた後は、そのレコードセット内のデータにアクセスすることはできません。

rs.Close

 

この例では、まずデータベースへの接続を開き、次に Open メソッドを使用してレコードセットを開いています。データの操作が完了したら、Close メソッドでレコードセットを閉じ、さらに接続も閉じています。この流れは、ADO を使用したデータベース操作の基本的なパターンです。

Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset

' データベースへの接続を開く
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"

' レコードセットを開く
rs.Open "SELECT * FROM あなたのテーブル名", conn, adOpenStatic, adLockReadOnly

' レコードセットのデータを操作する処理...

' レコードセットと接続を閉じる
rs.Close
conn.Close

MoveFirst/MoveNext

MoveFirst メソッドと MoveNext メソッドは、レコードセット内のレコードをナビゲート(移動)するために使用されます。

MoveFirst はレコードセットの最初のレコードに移動し、MoveNext は次のレコードに進みます。

これらのメソッドを利用することで、レコードセット内の全てのレコードを順に処理することが可能になります。以下に、これらのメソッドを利用した基本的な VBA コードの例を示します。

この例では、データベースからレコードセットを取得し、その中の全てのレコードをループして処理する方法を示します。ここでは、各レコードの特定のフィールドの値をデバッグウィンドウに出力しています。

Sub NavigateRecordset()
    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim sql As String
    
    ' データベース接続文字列の設定
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open
    
    ' SQLクエリの定義 (適宜、あなたのテーブル名やフィールド名に置き換えてください)
    sql = "SELECT * FROM あなたのテーブル名"
    
    ' レコードセットを開く
    rs.Open sql, conn, adOpenStatic, adLockReadOnly
    
    ' レコードセットの最初のレコードに移動
    rs.MoveFirst
    
    ' レコードセットの末尾に達するまでループ
    Do While Not rs.EOF
        ' 現在のレコードの処理を行う(例: フィールドの値を出力)
        Debug.Print rs.Fields("あなたのフィールド名").Value
        
        ' 次のレコードに移動
        rs.MoveNext
    Loop
    
    ' レコードセットと接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub


このコードは、最初にデータベースに接続し、指定された SQL クエリを使用してレコードセットを開きます。MoveFirst メソッドでレコードセットの最初のレコードに移動した後、EOF (End Of File) プロパティをチェックしながら MoveNext メソッドを使用してレコードセットを順に走査します。各レコードに対する処理(この例ではフィールドの値の出力)が完了したら、Close メソッドでレコードセットとデータベース接続を閉じ、最後にオブジェクトを解放します。

MoveLast/MovePrevious

MoveLast メソッドと MovePrevious メソッドを利用することで、レコードセット内のレコードを後方向にナビゲートすることができます。

MoveLast はレコードセットの最後のレコードに移動し、MovePrevious は前のレコードに戻ります。これらのメソッドを使用して、レコードセット内の全てのレコードを逆順に処理する例を以下に示します。

この例では、データベースからレコードセットを取得し、その中の全てのレコードを逆順にループして処理する方法を示します。ここでは、各レコードの特定のフィールドの値をデバッグウィンドウに出力しています。

Sub ReverseNavigateRecordset()
    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim sql As String
    
    ' データベース接続文字列の設定
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open
    
    ' SQLクエリの定義 (適宜、あなたのテーブル名やフィールド名に置き換えてください)
    sql = "SELECT * FROM あなたのテーブル名"
    
    ' レコードセットを開く
    rs.Open sql, conn, adOpenStatic, adLockReadOnly
    
    ' レコードセットの最後のレコードに移動
    rs.MoveLast
    
    ' レコードセットの先頭に達するまでループ
    Do While Not rs.BOF ' BOF (Beginning Of File) が True になるまで続ける
        ' 現在のレコードの処理を行う(例: フィールドの値を出力)
        Debug.Print rs.Fields("あなたのフィールド名").Value
        
        ' 前のレコードに移動
        rs.MovePrevious
    Loop
    
    ' レコードセットと接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub


このコードでは、最初にデータベースに接続し、指定された SQL クエリを使用してレコードセットを開きます。MoveLast メソッドでレコードセットの最後のレコードに移動した後、BOF (Beginning Of File) プロパティをチェックしながら MovePrevious メソッドを使用してレコードセットを逆順に走査します。各レコードに対する処理(この例ではフィールドの値の出力)が完了したら、Close メソッドでレコードセットとデータベース接続を閉じ、最後にオブジェクトを解放します。

Find

Find メソッドは、特定の条件に一致するレコードを検索するために使用されます。このメソッドを使用すると、レコードセット内で指定した基準に合致する最初のレコードにカーソルを移動させることができます。以下に、Find メソッドを利用した基本的な VBA コードの例を示します。

この例では、データベースからレコードセットを取得し、特定の条件を満たすレコードを検索します。条件に一致するレコードが見つかった場合、そのレコードの特定のフィールドの値をデバッグウィンドウに出力します。

Sub FindRecord()
    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim criteria As String
    
    ' データベース接続文字列の設定
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open
    
    ' SQLクエリの定義 (適宜、あなたのテーブル名やフィールド名に置き換えてください)
    rs.Open "SELECT * FROM あなたのテーブル名", conn, adOpenStatic, adLockReadOnly
    
    ' 検索条件の設定 (例: フィールド名が 'あなたの条件フィールド名' でその値が '特定の値')
    criteria = "あなたの条件フィールド名 = '特定の値'"
    
    ' 条件に一致するレコードを検索
    rs.Find criteria
    
    If Not rs.EOF Then
        ' 条件に一致するレコードが見つかった場合
        Debug.Print "見つかったレコード: " & rs.Fields("あなたの条件フィールド名").Value
    Else
        ' 条件に一致するレコードが見つからなかった場合
        Debug.Print "条件に一致するレコードは見つかりませんでした。"
    End If
    
    ' レコードセットと接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub

 

このコードでは、まずデータベースに接続し、指定された SQL クエリでレコードセットを開きます。次に、Find メソッドを使用して特定の検索条件に一致するレコードを検索します。Find メソッドは、条件に一致する最初のレコードにカーソルを移動させます。条件に一致するレコードが見つかった場合(EOF プロパティが False)、そのレコードの情報を出力します。一致するレコードがなければ、適切なメッセージを出力します。

Find メソッドを使用することで、大量のデータが含まれるレコードセットから特定の条件を満たすレコードを効率的に探し出すことができます。これは、ユーザー入力に基づく検索や、データベース内の特定の情報を迅速に見つける必要がある場合などに特に便利です。

【特集】ADOのRecordset オブジェクトを極めよう
しらかば堂

ここで1つ疑問が湧きますね。
SQLには WHERE 句があり、その中でこの FIND と同様のことができます。
にもかかわらず、何故 FIND メソッドが必要なのでしょうか?

何故 FINDメソッドが必要なのか

この記事を読まれている読者の方なら
SQLのWHERE句を使用することで、データベースから特定の条件に一致するレコードを直接取得することが可能なことはご存じですね。

それにもかかわらず、ADOのFindメソッドが提供されている理由は、異なるシナリオや要件に基づいて、より柔軟なデータ操作を可能にするためです。

FindメソッドとSQLのWHERE句を使用する場合の違いには以下のようなものがあります。

SQLのWHERE句の利点と利用シーン

  • 直接データベースレベルでのフィルタリング: SQLのWHERE句は、データベースクエリの実行時にフィルタリングを行います。これにより、必要なデータのみがアプリケーションに返されるため、ネットワークを介して転送されるデータの量を減らすことができます。
  • パフォーマンス: 大量のデータを扱う場合、データベースサーバー側でのフィルタリングはアプリケーション側での処理よりも効率的であることが多いです。特に、インデックスが適切に設定されている場合、WHERE句を使った検索は非常に高速になります。
  • 利用シナリオ: 初めから特定の条件に一致するデータのみが必要な場合、SQLのWHERE句を使用します。

ADOのFindメソッドの利点と利用シーン

  • クライアントサイドフィルタリング: Findメソッドは、既にアプリケーションにロードされたレコードセット内での検索を行います。これにより、データベースへの追加的なクエリを発行することなく、動的にデータをフィルタリングすることができます。
  • 柔軟性: アプリケーションが複雑なユーザーインターフェイスを持ち、ユーザーの操作に基づいてデータを動的にフィルタリングする必要がある場合、Findメソッドを使用すると便利です。
  • 利用シナリオ: 既に取得したレコードセットの中から、ユーザーの入力やプログラムの状態に応じて特定のレコードを検索する場合に使用します。

ベストプラクティス

  • 初期データ取得: 可能であれば、WHERE句を使用してデータベースから初めから必要なデータのみを取得します。これにより、パフォーマンスと効率が向上します。
  • 動的フィルタリングの必要性: アプリケーション側で動的にデータをフィルタリングする必要がある場合(例えば、ユーザーの入力に応じて)は、Findメソッドを利用してレコードセット内を検索します。

結局のところ、FindメソッドとSQLのWHERE句のどちらを使用するかは、アプリケーションの要件、データの量、および求められるパフォーマンスによって異なります。適切なツールを状況に応じて選択することが重要です。

Clone

Clone メソッドを使用すると、既存のレコードセットの完全なコピーを作成できます。これにより、元のレコードセットを変更することなく、そのコピー上で独立した操作が可能になります。以下に、Clone メソッドを利用したVBAコードの例を示します。

この例では、まずデータベースからレコードセットを取得し、そのレコードセットをクローンして、元のレコードセットとクローンのレコードセットが独立していることを示します。

Sub UseCloneMethod()
    Dim conn As New ADODB.Connection
    Dim rsOriginal As ADODB.Recordset
    Dim rsClone As ADODB.Recordset
    
    ' データベース接続文字列の設定
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open
    
    ' 元のレコードセットを開く
    Set rsOriginal = New ADODB.Recordset
    rsOriginal.Open "SELECT * FROM あなたのテーブル名", conn, adOpenStatic, adLockReadOnly
    
    ' 元のレコードセットのクローンを作成
    Set rsClone = rsOriginal.Clone
    
    ' 元のレコードセットの最初のレコードに移動
    rsOriginal.MoveFirst
    Debug.Print "元のレコードセットの最初のレコード: " & rsOriginal.Fields("あなたのフィールド名").Value
    
    ' クローンのレコードセットの最後のレコードに移動
    rsClone.MoveLast
    Debug.Print "クローンのレコードセットの最後のレコード: " & rsClone.Fields("あなたのフィールド名").Value
    
    ' レコードセットと接続を閉じる
    rsOriginal.Close
    rsClone.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rsOriginal = Nothing
    Set rsClone = Nothing
    Set conn = Nothing
End Sub


このコードでは、最初にデータベースに接続し、SELECT クエリを使用して元のレコードセット (rsOriginal) を開いています。

その後、Clone メソッドを使用して元のレコードセットの完全なコピー (rsClone) を作成します。

ここで、元のレコードセットとクローンのレコードセットは互いに独立しており、一方を操作しても他方には影響しません。

この性質を利用して、元のレコードセットの最初のレコードとクローンの最後のレコードの値をデバッグウィンドウに出力して、両者が独立していることを確認しています。

Clone メソッドを使用することで、特定のレコードセットの状態を保存したり、複数の異なるビューや操作を同時に行いたい場合に便利です。また、元のデータに影響を与えることなく、データの分析や操作を行うことができます。

【特集】ADOのRecordset オブジェクトを極めよう
しらかば堂

具体的にどんなケースで Clone メソッド があると便利なのでしょうね?

Clone メソッドがあると便利なケースとは

Clone メソッドがあると便利なケースは、アプリケーションが複数の異なる操作や分析を同時に、または順序を追って同じデータセットに対して行いたい場合です。以下に、Clone メソッドの利用が特に有効なシナリオの例をいくつか挙げます。

データの同時ビュー

  • マスター詳細インターフェース: ユーザーがマスターリストからアイテムを選択し、その詳細情報を同時に別のビューで表示したい場合、クローンされたレコードセットを使用してマスターリストを操作しながら、選択されたアイテムの詳細を表示できます。

データ分析と比較

  • データの時点比較: ある時点のデータセットと別の時点のデータセットを比較分析したい場合、一方のデータセットをクローンし、それぞれに異なるフィルタやソートを適用して比較分析を行うことができます。

ユーザー操作によるデータの変更

  • 元のデータの保持: ユーザーによるデータの編集や操作が可能なアプリケーションで、変更を加える前の元のデータセットの状態を保持しておきたい場合、元のレコードセットをクローンしておくことで、ユーザーが加えた変更を破棄し元の状態に戻す操作を簡単に実装できます。

複数の異なるクエリ結果の操作

  • 複数のクエリ結果の同時操作: 一つの大きなデータセットから抽出された複数の異なるクエリ結果に対して、それぞれ異なる操作(ソート、フィルタリング等)を行いたい場合、元のデータセットをクローンし、それぞれに対して独立して操作を適用できます。

複雑なデータ処理

  • 途中経過の保存: データ処理の各段階での中間結果を保持しながら、最終的な結果を導き出したい複雑なデータ分析を行う場合、各段階でレコードセットをクローンしておくことで、各処理ステップの結果を簡単に戻ったり確認したりすることができます。

AddNew / Update

AddNew メソッドと Update メソッドを使って、データベースに新しいレコードを追加し、そのレコードを更新するVBAのコード例を示します。

この例では、まず AddNew メソッドを使用して新しいレコードをレコードセットに追加し、次に Update メソッドを使用して変更をデータベースに保存します。

Sub AddAndUpdateRecord()
    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim connectionString As String
    Dim sql As String
    
    ' データベース接続文字列の設定
    connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open connectionString
    
    ' レコードセットを開く(編集可能なキーセットカーソルを使用)
    sql = "SELECT * FROM あなたのテーブル名"
    rs.Open sql, conn, adOpenKeyset, adLockOptimistic
    
    ' AddNew メソッドを使用して新しいレコードを開始
    rs.AddNew
    rs.Fields("あなたのフィールド名1").Value = "新しい値1"
    rs.Fields("あなたのフィールド名2").Value = "新しい値2"
    ' 他のフィールドにも値を設定する場合は、同様に設定します。
    
    ' Update メソッドを使用して新しいレコードをデータベースに保存
    rs.Update
    
    ' オプション: 更新したデータを確認
    rs.MoveLast ' 最新のレコードに移動
    Debug.Print rs.Fields("あなたのフィールド名1").Value
    Debug.Print rs.Fields("あなたのフィールド名2").Value
    
    ' レコードセットと接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub


このコードは、データベースに新しいレコードを追加し、そのレコードにフィールド値を設定して、データベースに保存するプロセスを示しています。AddNew メソッドを呼び出すことで新しいレコードの追加が開始され、Update メソッドで変更がデータベースに保存されます。

この例では、レコードセットを開く際に adOpenKeyset カーソルタイプと adLockOptimistic ロックタイプを使用しています。これにより、レコードセットが更新可能となり、データの追加や更新が可能になります。

AddNew Update メソッドを使用することで、VBAからデータベースに対して直接的にデータの挿入や更新を行うことができます。これは、フォームからのユーザー入力をデータベースに保存する場合など、様々なアプリケーションで役立ちます。

Delete

Delete メソッドを使用すると、レコードセットから現在のレコードを削除することができます。以下に、Delete メソッドを利用したVBAコードの例を示します。

この例では、特定の条件に一致するレコードを検索し、見つかった場合にそのレコードを削除します。

Sub DeleteRecord()
    Dim conn As New ADODB.Connection
    Dim rs As New ADODB.Recordset
    Dim connectionString As String
    Dim sql As String
    
    ' データベース接続文字列の設定
    connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\to\your\database.accdb;"
    conn.Open connectionString
    
    ' レコードセットを開く(編集可能なキーセットカーソルを使用)
    sql = "SELECT * FROM あなたのテーブル名 WHERE 条件"
    rs.Open sql, conn, adOpenKeyset, adLockOptimistic
    
    ' 条件に一致するレコードがあるか確認
    If Not rs.EOF Then
        ' 条件に一致するレコードを削除
        rs.Delete
        ' 削除を確定するために Update を呼び出す
        rs.Update
    Else
        Debug.Print "削除するレコードが見つかりませんでした。"
    End If
    
    ' レコードセットと接続を閉じる
    rs.Close
    conn.Close
    
    ' オブジェクトの解放
    Set rs = Nothing
    Set conn = Nothing
End Sub

 

このコードは、データベースから条件に一致するレコードを検索し、そのレコードが存在する場合に Delete メソッドを使って削除します。Delete メソッドは現在のレコード(rs オブジェクトが指しているレコード)を削除しますので、事前に条件に一致するレコードをレコードセットでアクティブにしておく必要があります。この例では、レコードセットを開く際に adOpenKeyset カーソルタイプと adLockOptimistic ロックタイプを使用しており、これによりレコードセットが更新可能になっています。

Delete メソッドを使用することで、アプリケーションから直接データベースのレコードを削除する操作が可能になります。この操作は、ユーザーがデータを管理するアプリケーションや、不要になったデータをクリーンアップするスクリプトなどで役立ちます。ただし、データを削除する操作は取り返しがつかない場合が多いので、実行前には慎重に確認することが重要です。

おわりに

この記事では、初級者から中級者の方々がAccess VBAエキスパート試験勉強、あるいは日々の開発作業に役立てることを目的としてADOを用いたデータベース操作の基礎から応用まで、実践的なコード例とともに解説しました。

あなたも ADO Recordsetオブジェクトのプロパティとメソッドを極め、さらなる高みへ昇りませんか。