次の方法で共有


レコードセットの操作

Recordset オブジェクトには組み込みの機能があり、結果セット内のデータの順序を並べ替えたり、指定した条件に基づいて特定のレコードを検索したり、インデックスを使用して検索操作を最適化したりできます。 これらの機能を使用できるかどうかは、プロバイダーによって異なります。場合によっては、Index プロパティの場合など、データ ソース自体の構造が異なります。

データの配置

レコードセット内のデータを並べ替える最も効率的な方法は、結果を返すために使用される SQL コマンドで ORDER BY 句を指定することです。 ただし、既に作成されているレコードセット内のデータの順序を変更する必要がある場合があります。 Sort プロパティを使用すると、レコードセットの行が走査される順序を設定できます。 さらに、Filter プロパティは、行を走査するときにアクセスできる行を決定します。

Sort プロパティは、並べ替えるレコードセット内のフィールド名を示す文字列値を設定または返します。 各名前はコンマで区切られ、必要に応じてスペースとキーワード ASC (フィールドを昇順で並べ替える) または DESC (フィールドを降順で並べ替える) が続きます。 既定では、キーワードが指定されていない場合、フィールドは昇順で並べ替えられます。

データは物理的に再配置されず、インデックスで指定された順序でアクセスされるため、並べ替え操作は効率的です。

Sort プロパティを使用するには、CursorLocation プロパティを adUseClient に設定する必要があります。 インデックスがまだ存在しない場合は、Sort プロパティで指定されたフィールドごとに一時インデックスが作成されます。

Sort プロパティを空の文字列に設定すると、行が元の順序にリセットされ、一時インデックスが削除されます。 既存のインデックスは削除されません。

レコードセットfirstNamemiddleInitiallastName という名前の 3 つのフィールドが含まれているとします。 Sort プロパティを文字列 "lastName DESC, firstName ASC" に設定します。これにより、レコードセットは姓で降順に並べ替えられ、次に名で昇順に並べ替えられます。 中央のイニシャルは無視されます。

並べ替え条件文字列で参照されるフィールドは、"ASC" または "DESC" という名前にすることはできません。これらの名前は、キーワード ASC および DESC と競合するためです。 競合する名前を持つフィールドに、レコードセットを返すクエリで AS キーワードを使用してエイリアスを指定します。

レコードセットのフィルター処理の詳細については、このトピックで後述する「結果のフィルター処理」を参照してください。

特定のレコードを検索する

ADO には、レコードセット内の特定のレコードを検索するための Find メソッドと Seek メソッドが用意されています。 Find メソッドはさまざまなプロバイダーでサポートされていますが、1 つの検索条件に制限されています。 Seek メソッドは複数の条件での検索をサポートしていますが、多くのプロバイダーではサポートされていません。

フィールドのインデックスを使用すると、Recordset オブジェクトの Find メソッドおよび Sort プロパティと Filter プロパティのパフォーマンスを大幅に向上させることができます。 動的な Optimize プロパティを設定することで、Field オブジェクトの内部インデックスを作成できます。 CursorLocation プロパティを adUseClient に設定すると、この動的プロパティが Field オブジェクトの Properties コレクションに追加されます。 このインデックスは ADO の内部的なインデックスです。このインデックスにアクセスしたり、他の目的で使用したりすることはできません。 また、このインデックスは Recordset オブジェクトのIndex プロパティとは異なります。

Find メソッドは、レコードセットの列 (フィールド) 内の値をすばやく見つけます。 Optimize プロパティを使用してインデックスを作成することで、列の Find メソッドの速度を頻繁に向上させることができます。

Find メソッドでは、検索を 1 つのフィールドの内容に制限します。 Seek メソッドでは、インデックスが必要で、他の制限もあります。 インデックスの基礎ではない複数のフィールドで検索する必要がある場合、またはプロバイダーがインデックスをサポートしていない場合は、Recordset オブジェクトの Filter プロパティを使用して結果を制限できます。

Find

Find メソッドでは、レコードセットの指定した条件を満たす行を検索します。 必要に応じて、検索の方向、開始行、および開始行からのオフセットを指定できます。 条件が満たされている場合、現在の行位置は見つかったレコードに設定されます。それ以外の場合、位置は検索方向に応じてレコードセットの末尾 (または先頭) に設定されます。

条件に指定できるのは 1 列の名前だけです。 言い換えると、このメソッドは複数列の検索をサポートしていません。

条件の比較演算子には、">" (より大きい)、"<" (より小さい)、"=" (等しい)、">=" (以上)、"<=" (以下)、"<>" (等しくない)、"LIKE" (パターン マッチング) を指定できます。

条件値には、文字列、浮動小数点数、日付を指定できます。 文字列値は、単一引用符または "#" (番号記号) マーク ("state = 'WA'" や "state = #WA#" など) で区切られます。 日付の値は、"#" (番号記号) マーク ("start_date > #7/22/97#" など) で区切られます。

比較演算子が "like" の場合、文字列値にはアスタリスク (*) を含め、任意の文字または部分文字列の 1 つ以上の出現箇所を検索できます。 たとえば、""state like 'M*'" はメイン州とマサチューセッツ州に一致します。 先頭と末尾のアスタリスクを使用して、値に含まれる部分文字列を検索することもできます。 たとえば、"state like '*as*'" はメイン州とマサチューセッツ州に一致します。

アスタリスクは、前に示したように、条件文字列の末尾にのみ使用することも、条件文字列の先頭と末尾の両方で使用することもできます。 先頭のワイルドカード ('*str') または埋め込みワイルドカード ('s*r') としてアスタリスクを使用することはできません。 これにより、エラーが発生します。

シークとインデックス

基になるプロバイダーが Recordset オブジェクトのインデックスをサポートしている場合は、Seek メソッドを Index プロパティと共に使用します。 Supports(adSeek) メソッドを使用して、基になるプロバイダーが Seek をサポートしているかどうかを判断し、Supports(adIndex) メソッドを使用して、プロバイダーがインデックスをサポートしているかどうかを判断します。 (たとえば、OLE DB Provider for Microsoft JetSeekIndex をサポートしています)。

Seek で目的の行が見つからない場合、エラーは発生せず、行はレコードセットの末尾に配置されます。 このメソッドを実行する前に、Index プロパティを目的のインデックスに設定します。

このメソッドは、サーバー側カーソルでのみサポートされます。 Recordset オブジェクトの CursorLocation プロパティ値が adUseClient の場合、シークはサポートされません。

このメソッドは、Recordset オブジェクトが adCmdTableDirectCommandTypeEnum 値で開かれている場合にのみ使用できます。

結果のフィルター処理

Find メソッドでは、検索を 1 つのフィールドの内容に制限します。 Seek メソッドでは、インデックスが必要で、他の制限もあります。 インデックスの基礎ではない複数のフィールドで検索する必要がある場合、またはプロバイダーがインデックスをサポートしていない場合は、Recordset オブジェクトの Filter プロパティを使用して結果を制限できます。

Filter プロパティを使用して、Recordset オブジェクト内のレコードを選択的にスクリーン アウトします。 フィルター処理されたレコードセットが現在のカーソルになります。つまり、フィルター条件を満たしていないレコードは、フィルターが削除されるまでレコードセットで使用できません。 現在のカーソルに基づいて値を返すその他のプロパティ (AbsolutePositionAbsolutePageRecordCountPageCount など) が影響を受けます。 これは、Filter プロパティを特定の値に設定すると、現在のレコードが新しい値を満たす最初のレコードに移動するためです。

Filter プロパティは variant 引数を受け取ります。 この値は、Filter プロパティを使用する 3 つのメソッド (条件文字列、FilterGroupEnum 定数、ブックマークの配列) のいずれかを表します。 詳細については、このトピックで後述する「条件文字列を使用したフィルター処理」、「定数を使用したフィルター処理」、「ブックマークを使用したフィルター処理」を参照してください。

注意

選択するデータがわかっている場合は、通常、Filter プロパティに依存するのではなく、結果セットを効果的にフィルター処理する SQL ステートメントで Recordset を開く方が効率的です。

Recordset からフィルターを削除するには、adFilterNone 定数を使用します。 Filter プロパティを長さ 0 の文字列 ("") に設定すると、adFilterNone 定数を使用する場合と同じ効果があります。

条件文字列を使用したフィルター処理

条件文字列は、FieldName 演算子値 (たとえば "LastName = 'Smith'") の形式の句で構成されます。 複合句は、AND (たとえば "LastName = 'Smith' AND FirstName = 'John'") と OR (たとえば "LastName = 'Smith' OR LastName = 'Jones'") を使用して個々の句を連結することで作成できます。 条件文字列については次のガイドラインに従ってください。

  • FieldName は、レコードセットの有効なフィールド名である必要があります。 フィールド名にスペースが含まれる場合は、名前を角かっこで囲む必要があります。

  • 演算子は、<><=>=<>=LIKE のいずれかである必要があります。

  • は、フィールド値 (たとえば、'Smith'#8/24/95#12.345$50.00) を比較する値です。 文字列には単一引用符 (') を、日付にはシャープ記号 (#) を使用します。 数値には、小数点、ドル記号、科学的表記を使用できます。 演算子LIKE の場合、にはワイルドカード文字を使用できます。 アスタリスク (*) とパーセント記号 (%) のワイルドカード文字のみを使用でき、文字列の最後の文字にする必要があります。 を null 値にすることはできません。

    注意

    フィルターに単一引用符 (') を含めるには、2 つの単一引用符を使用して 1 つを表します。 たとえば、O'Malley でフィルター処理するには、条件文字列を "col1 = 'O''Malley'" にする必要があります。 フィルター値の先頭と末尾の両方に単一引用符を含めるには、文字列をシャープ記号 (#)で囲みます。 たとえば、'1' でフィルター処理するには、条件文字列を "col1 = #'1'#" にする必要があります。

ANDOR の間に優先順位はありません。 句はかっこ内でグループ化できます。 ただし、次のように、OR で結合された句をグループ化し、AND を使用して別の句にグループを結合することはできません。

(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'  

代わりに、次のようにこのフィルターを構築します。

(LastName = 'Smith' AND FirstName = 'John') OR (LastName = 'Jones' AND FirstName = 'John')  

LIKE 句では、パターンの先頭と末尾 (たとえば LastName Like '*mit*')、またはパターンの末尾 (たとえば LastName Like 'Smit*') にのみワイルドカードを使用できます。

定数によるフィルター処理

レコードセットのフィルター処理には、次の定数を使用できます。

常時 説明
adFilterAffectedRecords 最後の DeleteResyncUpdateBatch、または CancelBatch 呼び出しの影響を受けたレコードのみを表示するフィルター。
adFilterConflictingRecords 最後のバッチ更新に失敗したレコードを表示するためのフィルター。
adFilterFetchedRecords 現在のキャッシュ内のレコードを表示するためのフィルター。つまり、データベースからレコードを取得するための最後の呼び出しの結果。
adFilterNone 現在のフィルターを削除し、すべてのレコードを復元し表示します。
adFilterPendingRecords 変更されたが、まだサーバーに送信されていないレコードのみを表示するフィルター。 バッチ更新モードにのみ適用されます。

フィルター定数を使用すると、次の例に示すように、最後の UpdateBatch メソッド呼び出し中に影響を受けたレコードのみを表示できるため、バッチ更新モード中の個々のレコードの競合を簡単に解決できます。

Attribute VB_Name = "modExaminingData"

ブックマークを使用したフィルター処理

最後に、ブックマークのバリアント配列を Filter プロパティに渡すことができます。 結果のカーソルには、ブックマークがプロパティに渡されたレコードのみが含まれます。 次のコード例では、ProductName フィールドに "B" が含まれるレコードセット内のレコードからブックマークの配列を作成します。 次に、配列を Filter プロパティに渡し、結果としてフィルター処理されたレコードセットに関する情報を表示します。

'BeginFilterBkmk  
Dim vBkmkArray() As Variant  
Dim i As Integer  
  
'Recordset created using "SELECT * FROM Products" as command.  
'So, we will check to see if ProductName has a capital B, and  
'if so, add to the array.  
i = 0  
Do While Not objRs.EOF  
    If InStr(1, objRs("ProductName"), "B") Then  
        ReDim Preserve vBkmkArray(i)  
        vBkmkArray(i) = objRs.Bookmark  
        i = i + 1  
        Debug.Print objRs("ProductName")  
    End If  
    objRs.MoveNext  
Loop  
  
'Filter using the array of bookmarks.  
objRs.Filter = vBkmkArray  
  
objRs.MoveFirst  
Do While Not objRs.EOF  
    Debug.Print objRs("ProductName")  
    objRs.MoveNext  
Loop  
'EndFilterBkmk  

レコードセットの複製の作成

特に、特定のレコードのセットに複数の現在のレコードを保持する場合、Clone メソッドを使用して、複数の重複する Recordset オブジェクトを作成します。 Clone メソッドを使用する方が、元のオブジェクトと同じ定義で新しい Recordset オブジェクトを作成して開くよりも効率的です。

新しく作成された複製の現在のレコードは、当初最初のレコードに設定されます。 複製されたレコード セット内の現在のレコード ポインターは、元のレコードと同期されません。また、その逆も同様です。 各レコードセット内を個別に移動できます。

1 つの Recordset オブジェクトに対して行った変更は、カーソルの種類に関係なく、すべての複製に表示されます。 ただし、元の Recordset に対して Requery を実行すると、複製は元の Recordset と同期されなくなります。

元のレコードセットを閉じても、そのコピーは閉じられません。また、コピーを閉じても、元のコピーや他のコピーは閉じられません。

Recordset オブジェクトは、ブックマークをサポートしている場合にのみ複製できます。 ブックマーク値は交換可能です。つまり、1 つの Recordset オブジェクトからのブックマーク参照は、すべての複製内の同じレコードを参照します。