Arbeiten mit Recordsets

Das Objekt Recordset verfügt über integrierte Features, mit denen Sie die Reihenfolge der Daten im Resultset neu ändern, nach einem bestimmten Datensatz basierend auf den von Ihnen bereitgestellten Kriterien suchen und diese Suchvorgänge sogar mithilfe von Indizes optimieren können. Ob diese Features zur Verwendung bereitstehen, hängt vom Anbieter und in einigen Fällen – z. B. bei der Index-Eigenschaft – von der Struktur der Datenquelle selbst ab.

Anordnen von Daten

Häufig ist der effizienteste Weg, die Daten in Ihrem Recordset anzuordnen, die Angabe einer ORDER BY-Klausel im SQL-Befehl, mit der Ergebnisse an sie zurückgegeben werden. Möglicherweise müssen Sie jedoch die Reihenfolge der Daten in einem Recordset ändern, das bereits erstellt wurde. Sie können die Sort-Eigenschaft verwenden, um die Reihenfolge festzulegen, in der Zeilen eines Recordset durchlaufen werden. Darüber hinaus wird mit der Filter-Eigenschaft festgelegt, auf welche Zeilen beim Durchlaufen von Zeilen zugegriffen werden kann.

Mit der Sort-Eigenschaft wird ein Zeichenfolgenwert festgelegt oder zurückgegeben, mit dem die Feldnamen im Recordset angegeben werden, nach denen sortiert werden soll. Jeder Name wird durch ein Komma getrennt und es müssen ihm ein Leerzeichen und das Schlüsselwort ASC (mit dem das Feld in aufsteigender Reihenfolge sortiert wird) oder DESC (mit dem das Feld in absteigender Reihenfolge sortiert wird) folgen. Wenn kein Schlüsselwort angegeben wird, wird das Feld standardmäßig in aufsteigender Reihenfolge sortiert.

Der Sortiervorgang ist effizient, da Daten nicht physisch neu angeordnet werden, sondern in der Reihenfolge aufgerufen werden, die durch einen Index angegeben wird.

Damit die Sort-Eigenschaft funktioniert, muss die Eigenschaft CursorLocation auf adUseClient festgelegt werden. Ein temporärer Index wird für jedes Feld erstellt, das in der Sort-Eigenschaft angegeben ist, wenn noch kein Index vorhanden ist.

Wenn die Sort-Eigenschaft auf eine leere Zeichenfolge festgelegt wird, werden die Zeilen auf ihre ursprüngliche Reihenfolge zurückgesetzt und temporäre Indizes werden gelöscht. Vorhandene Indizes werden nicht gelöscht.

Nehmen wir einmal an, ein Recordset enthält drei Felder mit den Namen firstName, middleInitial und lastName. Legen Sie die Sort-Eigenschaft auf die Zeichenfolge „lastName DESC, firstName ASC“ fest, durch die das Recordset nach dem Nachnamen in absteigender Reihenfolge und dann nach dem Vornamen in aufsteigender Reihenfolge sortiert wird. Die mittlere Initiale wird ignoriert.

Kein Feld in einer Sortierkriterienzeichenfolge darf mit „ASC“ oder „DESC“ bezeichnet werden, da diese Namen mit den Schlüsselwörtern ASC und DESC in Konflikt stehen. Geben Sie zu einem Feld mit einem Namen, der mit einem Schlüsselwort in Konflikt steht, einen Alias an, indem Sie das Schlüsselwort AS in der Abfrage verwenden, die das Recordset zurückgibt.

Weitere Informationen zum Filtern von Recordsets finden Sie weiter unten in diesem Thema unter „Filtern der Ergebnisse“.

Suchen eines bestimmten Datensatzes

ADO beinhaltet die Methoden Find und Seek, mit denen nach einem bestimmten Datensatz in einem Recordset gesucht werden kann. Die Methode Find wird von verschiedenen Anbietern unterstützt, ist jedoch auf ein einzelnes Suchkriterium beschränkt. Die Methode Seek unterstützt die Suche nach mehreren Kriterien, wird jedoch nicht von vielen Anbietern unterstützt.

Durch Indizes für Felder kann die Leistung der Methode Find und der Eigenschaften Sort und Filter des Objekts Recordset erheblich verbessert werden. Sie können einen internen Index für ein Field-Objekt erstellen, indem Sie die dynamische Optimize-Eigenschaft festlegen. Diese dynamische Eigenschaft wird der Eigenschaften-Sammlung des Objekts Field hinzugefügt, wenn Sie die Eigenschaft CursorLocation auf adUseClient festlegen. Denken Sie daran, dass dieser Index einer interner Bestandteil von ADO ist. Sie können keinen Zugriff darauf erhalten oder ihn für einen anderen Zweck verwenden. Außerdem unterscheidet sich dieser Index von der Eigenschaft Index des Objekts Recordset.

Mit der Methode Find kann ein Wert innerhalb einer Spalte (Feld) eines Recordsets schnell lokalisiert werden. Sie können die Geschwindigkeit der Methode Find in einer Spalte häufig verbessern, indem Sie mithilfe der Eigenschaft Optimize einen Index dazu erstellen.

Die Methode Find beschränkt die Suche auf den Inhalt eines Felds. Die Methode Seek sieht vor, dass Sie über einen Index verfügen. Zudem hat sie noch weitere Einschränkungen. Wenn Sie nach mehreren Feldern suchen müssen, die nicht die Basis eines Indexes sind, oder wenn Ihr Anbieter Indizes nicht unterstützt, können Sie Ihre Ergebnisse mithilfe der Eigenschaft Filter des Objekts Recordset einschränken.

Suchen

Mit der Methode Find wird ein Recordset nach der Zeile durchsucht, die ein bestimmtes Kriterium erfüllt. Optional können die Richtung der Suche, die Startzeile und der Offset von der Startzeile angegeben werden. Wenn das Kriterium erfüllt ist, wird die aktuelle Zeilenposition des gefundenen Datensatzes festgelegt; andernfalls wird die Position je nach Suchrichtung auf das Ende (oder den Anfang) des Recordset festgelegt.

Für das Kriterium kann nur ein Spaltenname angegeben werden. Mit anderen Worten unterstützt diese Methode keine mehrspaltigen Suchvorgänge.

Der Vergleichsoperator für das Kriterium kann „>“ (größer als), „<“ (kleiner als), „=“ (gleich), „>=“ (größer gleich), „<=“ (kleiner gleich), „<>“ (ungleich) oder „LIKE“ (Musterabgleich) sein.

Der Kriteriumwert kann eine Zeichenfolge, eine Gleitkommazahl oder ein Datum sein. Zeichenfolgenwerte werden durch einzelne Anführungszeichen oder „#“ (Nummernzeichen) getrennt (z. B. „state = ‚WA'“ oder „state = #WA#“). Datumswerte werden durch „#“ (Nummernzeichen) getrennt (z. B. „start_date > #7/22/97#“).

Wenn der Vergleichsoperator „like“ ist, kann der Zeichenfolgenwert ein Sternchen (*) enthalten, um nach einem oder mehreren Vorkommen eines Zeichens oder einer Teilzeichenfolge zu suchen. Beispielsweise „State like 'M*'“ entspricht Maine und Massachusetts. Sie können Sternchen auch voran- oder nachstellen, um nach einer Teilzeichenfolge zu suchen, die in den Werten enthalten ist. Beispielsweise entspricht „State like '*as*'“ Alaska, Arkansas und Massachusetts.

Sternchen können, wie oben beschrieben, nur am Ende einer Kriterienzeichenfolge oder gemeinsam sowohl am Anfang als auch am Ende einer Kriterienzeichenfolge verwendet werden. Sie können das Sternchen nicht als vorangestellte Wildcard („*str“) oder eingebettete Wildcard („s*r“) verwenden. Das führt zu einem Fehler.

Seek und Index

Verwenden Sie die Methode Seek zusammen mit der Eigenschaft Index, wenn der zugrunde liegende Anbieter Indizes zum Objekt Recordset unterstützt. Verwenden Sie die Methode Supports(adSeek), um zu ermitteln, ob der zugrunde liegende Anbieter Seek unterstützt, und die Methode Supports(adIndex), um zu ermitteln, ob der Anbieter Indizes unterstützt. (Beispielsweise unterstützt der OLE DB-Anbieter für Microsoft JetSeek und Index.)

Wenn die gewünschte Zeile mit Seek nicht gefunden wird, kommt es zu keinem Fehler, und die Zeile wird am Ende des Recordset positioniert. Legen Sie die Eigenschaft Index auf den gewünschten Index fest, bevor Sie diese Methode ausführen.

Diese Methode wird nur mit serverseitigen Cursorn unterstützt. Seek wird nicht unterstützt, wenn der Eigenschaftswert CursorLocation des Objekts RecordsetadUseClient ist.

Diese Methode kann nur verwendet werden, wenn das Objekt Recordset mit einem CommandTypeEnum Wert von adCmdTableDirect geöffnet wurde.

Filtern der Ergebnisse

Die Methode Find beschränkt die Suche auf den Inhalt eines Felds. Die Methode Seek sieht vor, dass Sie über einen Index verfügen. Zudem hat sie noch weitere Einschränkungen. Wenn Sie nach mehreren Feldern suchen müssen, die nicht die Basis eines Indexes sind, oder wenn Ihr Anbieter Indizes nicht unterstützt, können Sie Ihre Ergebnisse mithilfe der Eigenschaft Filter des Objekts Recordset einschränken.

Verwenden Sie die Eigenschaft Filter, um Datensätze aus einem Recordset-Objekt selektiv herauszufiltern. Das herausgefilterte Recordset wird zum aktuellen Cursor, was bedeutet, dass Datensätze, die die Filterkriterien nicht erfüllen, erst im Recordset verfügbar sind, wenn der Filter entfernt wird. Andere Eigenschaften, die Werte basierend auf dem aktuellen Cursor zurückgeben, sind betroffen; dies sind z. B. AbsolutePosition, AbsolutePage, RecordCount und PageCount. Dies liegt daran, dass der aktuelle Datensatz durch das Festlegen der Eigenschaft Filter auf einen bestimmten Wert zum ersten Datensatz verschoben wird, der den neuen Wert erfüllt.

Die Eigenschaft Filter verwendet ein Variant-Argument. Dieser Wert stellt eine von drei Methoden zur Verwendung der Eigenschaft Filter dar: eine Kriterienzeichenfolge, eine FilterGroupEnum-Konstante oder ein Array von Textmarken. Weitere Informationen finden Sie unter „Filtern mit einer Kriterienzeichenfolge“, „Filtern mit einer Konstante“ und „Filtern mit Textmarken“ weiter unten in diesem Thema.

Hinweis

Wenn Sie die Daten kennen, die Sie auswählen möchten, ist es in der Regel effizienter, ein Recordset mit einer SQL-Anweisung zu öffnen, die das Resultset effektiv filtert, anstatt auf die Filter-Eigenschaft zu vertrauen.

Um einen Filter aus einem Recordset zu entfernen, verwenden Sie die Konstante adFilterNone. Wenn Sie die Eigenschaft Filter auf eine leere Zeichenfolge („“) festlegen, hat dies denselben Effekt wie die Konstante adFilterNone.

Filtern mit einer Kriterienzeichenfolge

Die Kriterienzeichenfolge besteht aus Klauseln im Formular FieldName-Operator-Value (z. B "LastName = 'Smith'"). Sie können zusammengesetzte Klauseln erstellen, indem Sie einzelne Klauseln mit AND (z. B. "LastName = 'Smith' AND FirstName = 'John'") und OR (z. B. "LastName = 'Smith' OR LastName = 'Jones'") verketten. Verwenden Sie für Kriterienzeichenfolgen die folgenden Richtlinien:

  • FieldName muss ein gültiger Feldname aus dem Recordset sein. Wenn der Feldname Leerzeichen enthält, müssen Sie den Namen in eckige Klammern setzen.

  • Operator muss einer der folgenden sein: <, >, <=, >=, <>, = oder LIKE.

  • Wert ist der Wert, mit dem Sie die Feldwerte vergleichen (z. B. 'Smith', #8/24/95#, 12.345 oder $50.00). Verwenden Sie einzelne Anführungszeichen (') bei Zeichenfolgen und Nummernzeichen (#) mit Datumsangaben. Bei Zahlen können Sie Dezimalpunkte, Dollarzeichen und die wissenschaftliche Schreibweise verwenden. Wenn der OperatorLIKE ist, können im Wert Wildcardzeichen verwendet werden. Als Wildcardzeichen sind nur das Sternchen (*) und das Prozentzeichen (%) zulässig. Sie müssen das letzte Zeichen in der Zeichenfolge sein. Wert darf nicht Null sein.

    Hinweis

    Um einzelne Anführungszeichen (') in den Filterwert einzuschließen, verwenden Sie zwei einfache Anführungszeichen, um eins darzustellen. Um z. B. nach O'Malley zu filtern, muss die Kriterienzeichenfolge "col1 = 'O''Malley'" sein. Um einzelne Anführungszeichen sowohl am Anfang als auch am Ende des Filterwerts zu verwenden, schließen Sie die Zeichenfolge in Nummernzeichen (#) ein. Um z. B. nach ‚1‘ zu filtern, muss die Kriterienzeichenfolge "col1 = #'1'#" sein.

Es gibt keinen Vorrang zwischen AND und OR. Klauseln können innerhalb von Klammern gruppiert werden. Sie können jedoch keine Klauseln gruppieren, die durch ein OR verbunden sind, und dann die Gruppe mit einer anderen Klausel mit einem AND verbinden.

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

Stattdessen erstellen Sie diesen Filter wie folgt.

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

In einer LIKE-Klausel können Sie am Anfang und Ende des Musters (z. B. LastName Like '*mit*') oder nur am Ende des Musters (z. B. LastName Like 'Smit*' ) eine Wildcard verwenden.

Filtern mit einer Konstante

Die folgenden Konstanten stehen zum Filtern von Recordsets zur Verfügung.

Konstante Beschreibung
adFilterAffectedRecords Filter, mit denen nur Datensätze angezeigt werden, die von dem letzten Delete-, Resync-, UpdateBatch- oder CancelBatch-Aufruf betroffen sind.
adFilterConflictingRecords Filter zum Anzeigen der Datensätze, bei denen das letzte Batchupdate fehlgeschlagen ist.
adFilterFetchedRecords Filter zum Anzeigen der Datensätze im aktuellen Cache – also die Ergebnisse des letzten Aufrufs zum Abrufen von Datensätzen aus der Datenbank.
adFilterNone Entfernt den aktuellen Filter und stellt alle Datensätze zum Anzeigen wieder her.
adFilterPendingRecords Filter zum Anzeigen nur von Datensätzen, die geändert, aber noch nicht an den Server gesendet wurden. Gilt nur für den Batchupdatemodus.

Die Filterkonstanten vereinfachen die Lösung einzelner Datensatzkonflikte während des Batchupdate-Modus, indem sie es Ihnen beispielsweise nur erlauben, die Datensätze anzuzeigen, die während des letzten Aufrufs der Methode UpdateBatch betroffen waren, wie im folgenden Beispiel gezeigt.

Attribute VB_Name = "modExaminingData"

Filtern mit Textmarken

Schließlich können Sie ein Variant-Array von Textmarken an die Eigenschaft Filter übergeben. Der daraus resultierende Cursor enthält nur die Datensätze, deren Textmarke an die Eigenschaft übergeben wurde. Im folgenden Codebeispiel wird ein Array von Textmarken aus den Datensätzen in einem Recordset erstellt, die über ein „B“ im Feld ProductName verfügen. Anschließend wird das Array an die Eigenschaft Filter übergeben, und es werden Informationen zum resultierenden gefilterten Recordset angezeigt.

'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  

Erstellen eines Klons eines Recordsets

Verwenden Sie die Methode Clone, um mehrere, doppelte Recordset-Objekte zu erstellen, insbesondere, wenn Sie mehr als einen aktuellen Datensatz in einer bestimmten Gruppe von Datensätzen verwalten möchten. Die Methode Clone ist effizienter, als wenn Sie ein neues Recordset-Objekt mit derselben Definition wie im Original erstellen und öffnen.

Der aktuelle Datensatz eines neu erstellten Klons wird ursprünglich auf den ersten Datensatz festgelegt. Der aktuelle Datensatzzeiger in einem geklonten Recordset wird nicht mit dem Original synchronisiert oder umgekehrt. Sie können in jedem Recordset unabhängig navigieren.

Änderungen, die Sie an einem Recordset-Objekt vornehmen, sind unabhängig vom Cursortyp in allen Klonen sichtbar. Nachdem Sie jedoch Requery am Original-Recordset ausgeführt haben, werden die Klone nicht mehr mit dem Original synchronisiert.

Wenn das Original-Recordset geschlossen wird, werden seine Kopien nicht gleichzeitig geschlossen, und wenn eine Kopie geschlossen wird, führt das nicht zum Schließen des Originals oder anderer Kopien.

Sie können ein Recordset-Objekt nur klonen, wenn es Textmarken unterstützt. Textmarkenwerte sind austauschbar, d. h. ein Textmarkenverweis von einem Recordset-Objekt bezieht sich in jedem seiner Klone auf denselben Datensatz.