ADODB: Datenzugriff mit Recordsets

Möchtest Du den gesamten Artikel lesen? Und vielleicht sogar den Artikel im PDF-Format und die Beispieldateien herunterladen? Dann hole Dir den Artikel gleich hier - völlig kostenlos!

Recordsets sind zentrale Bestandteile beim Zugriff auf Daten mit ADODB. Sie bieten umfangreiche Funktionen zur Navigation, Bearbeitung, Filterung und Analyse von Daten. In diesem Artikel zeigen wir eine vollständige Übersicht aller Eigenschaften und Methoden des Recordset-Objekts und erläutern diese jeweils ausführlich mit praktischen Beispielen. Besonderes Augenmerk legen wir auf die Ereignisse eines Recordsetes. Im Gegensatz zum DAO-Recordset bietet das ADODB-Recordset nämlich die Möglichkeit, auf verschiedene Ereignisse zu reagieren – beispielsweise auf Änderungen im Datensatz.

Beispieldatenbank

Die Beispiele dieses Artikels findest Du in der Beispieldatenbank ADODB_Recordset_AlleEigenschaften.accdb.

Übersicht: Eigenschaften und Methoden

Im Folgenden geben wir eine Kurzbeschreibung aller verfügbaren Eigenschaften und Methoden des Recordset-Objekts, bevor wir diese im Einzelnen detailliert erläutern:

  • AbsolutePage: Liefert oder setzt die aktuelle Seite bei Seitennavigation.
  • AbsolutePosition: Position des aktuellen Datensatzes im Recordset.
  • ActiveCommand: Liefert das zugehörige Command-Objekt.
  • ActiveConnection: Verbindung, mit der das Recordset verknüpft ist.
  • AddNew/Update/CancelUpdate: Neue Datensätze hinzufügen und speichern.
  • BOF/EOF: Gibt an, ob sich der Datensatzmarkierer vor dem ersten oder nach dem letzten Datensatz befindet.
  • Bookmark/CompareBookmarks: Zum Speichern und Vergleichen von Positionen.
  • CacheSize: Anzahl Datensätze, die lokal zwischengespeichert werden.
  • Cancel/CancelBatch: Bricht aktuelle Operationen ab.
  • Clone: Erstellt eine Kopie des Recordsets.
  • Close/Open: Öffnet oder schließt das referenzierte Recordset.
  • CursorLocation/CursorType: Steuerung der Navigation und Server-/Clientverarbeitung.
  • Delete: Entfernt den aktuellen Datensatz.
  • EditMode: Zeigt an, ob und wie ein Datensatz bearbeitet wird.
  • Filter/Find/Seek: Filtert Datensätze oder sucht bestimmte Inhalte.
  • Fields: Auflistung aller Felder eines Datensatzes.
  • GetRows/GetString: Exportiert Daten als Array oder String.
  • LockType: Steuerung der Sperrmechanismen bei Bearbeitung.
  • MoveFirst: Navigiert zum ersten Datensatz im Recordset.
  • MoveLast: Navigiert zum letzten Datensatz im Recordset.
  • MoveNext: Navigiert zum nächsten Datensatz.
  • MovePrevious: Navigiert zum vorherigen Datensatz.
  • Move: Navigiert um eine bestimmte Anzahl Recordsets vor oder zurück.
  • NextRecordset: Weiteres Recordset aus einem Stapel.
  • PageCount/PageSize: Paginierung großer Datenmengen.
  • Properties: Auflistung aller Eigenschaften.
  • RecordCount: Anzahl der Datensätze.
  • Requery/Resync: Aktualisiert das Recordset mit aktuellen Daten.
  • Save: Speichert das Recordset als Datei.
  • Sort: Sortiert die Datensätze.
  • Source/State/Status: Informationsfelder zum Recordset.
  • StayInSync/Supports: Steuerung von Synchronisierung und unterstützten Features.
  • UpdateBatch: Speichert mehrere Änderungen gesammelt.

Detaillierte Beschreibung aller Funktionen

Im folgenden Abschnitt erläutern wir jede dieser Methoden und Eigenschaften einzeln.

Wir geben Anwendungsbeispiele, zeigen Einsatzmöglichkeiten in VBA und gehen auf Spezialfälle ein.

Beispielumgebung

In diesem Artikel verwenden wir durchgängig die Tabelle tblKunden mit den Feldern KundenID, Nachname, Vorname und Ort. Die Datenbank enthält fünf Testdatensätze mit Namen und Orten.

Diese erstellen wir mit einer eigenen Prozedur (siehe Listing 1).

Public Sub TabelleKundenErstellenUndFüllen()
     Dim cnn As ADODB.Connection
     Dim strPfad As String
     Dim strSQL As String
     '' Verbindung zur aktuellen Access-Datenbank herstellen
     Set cnn = New ADODB.Connection
     strPfad = CurrentProject.FullName
     cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                            "Data Source=" & strPfad & ";" & _
                            "Persist Security Info=False;"
     cnn.Open
     '' Bestehende Tabelle löschen (falls vorhanden)
     On Error Resume Next
     cnn.Execute "DROP TABLE tblKunden"
     On Error GoTo 0
     '' Tabelle erstellen
     strSQL = "CREATE TABLE tblKunden (" & _
              "KundenID AUTOINCREMENT PRIMARY KEY, " & _
              "Nachname TEXT(50), " & _
              "Vorname TEXT(50), " & _
              "Ort TEXT(50))"
     cnn.Execute strSQL
     '' Beispieldatensätze einfügen
     cnn.Execute "INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Müller'', ''Anna'', ''Berlin'')"
     cnn.Execute "INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Schmidt'', ''Peter'', ''Hamburg'')"
     cnn.Execute "INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Lehmann'', ''Julia'', ''München'')"
     cnn.Execute "INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Weber'', ''Klaus'', ''Stuttgart'')"
     cnn.Execute "INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Klein'', ''Maria'', ''Düsseldorf'')"
     '' Verbindung schließen
     cnn.Close
     Set cnn = Nothing
     MsgBox "Tabelle ''tblKunden'' wurde erstellt und mit Daten gefüllt.", vbInformation
End Sub

Listing 1: Erstellen einer Tabelle mit Beispieldaten

Verbindung und Recordset öffnen

Alle folgenden Beispiele beginnen mit dem vollständigen Aufbau einer ADODB-Verbindung zu einer Access-Datenbank und dem Öffnen eines Recordsets auf Basis der Tabelle tblKunden.

Ein Beispiel hierzu sehen wir in Listing 2. Hier erstellen wir ein Connection-Objekt und füllen es mit einem Verweis auf die Connection der aktuellen Access-Datenbank (CurrentProject.Connection).

Public Sub KundenRecordsetOeffnen()
     Dim cnn As ADODB.Connection
     Dim rst As ADODB.Recordset
     Set cnn = CurrentProject.Connection
     Set rst = New ADODB.Recordset
     rst.Open "SELECT * FROM tblKunden", cnn, adOpenKeyset, adLockOptimistic
     Do Until rst.EOF
         Debug.Print rst!Vorname & " " & rst!Nachname
         rst.MoveNext
     Loop
     rst.Close
     Set rst = Nothing
     cnn.Close
     Set cnn = Nothing
End Sub

Listing 2: Prozedur zum Durchlaufen von Kundendatensätzen

Danach erstellen und öffnen wir ein Recordset auf Basis der Tabelle tblKunden. Die Details beschreiben wir später. Schließlich durchlaufen wir in einer Do While-Schleife alle Datensätze dieses Recordsets.

EOF und BOF

Die Eigenschaften EOF (End of File) und BOF (Beginning of File) zeigen an, ob sich der Datensatzzeiger am Ende oder vor dem Anfang des Recordsets befindet.

Beide Eigenschaften sind vom Typ Boolean und spielen eine zentrale Rolle bei der sicheren Navigation durch Daten.

Insbesondere bei leeren Recordsets ist es wichtig, beide Eigenschaften zu prüfen: Ist EOF und BOF gleichzeitig True, enthält das Recordset keine Datensätze – weder vorne noch hinten

In Listing 3 erstellen wir ein Recordset, das keine Datensätze enthält, da das Kriterium (1=2) für keinen Datensatz erfüllt wird.

Public Sub KundenDurchlaufen()
     Dim cnn As ADODB.Connection
     Dim rst As ADODB.Recordset
     Set cnn = CurrentProject.Connection
     Set rst = New ADODB.Recordset
     rst.Open "SELECT * FROM tblKunden WHERE 1 = 2", cnn, adOpenKeyset, adLockOptimistic
     If rst.BOF And rst.EOF Then
         MsgBox "Keine Datensätze vorhanden."
     Else
         ''Operationen für vorhandene Datensätze
     End If
     rst.Close
     Set rst = Nothing
     cnn.Close
     Set cnn = Nothing
End Sub

Listing 3: Prüfen, ob sich der Datensatzzeiger vor oder hinter dem ersten oder letzten Datensatz befindet.

Hier prüfen wir, ob rst.EOF und rst.BOF gleichzeitig True liefern. In diesem Fall gibt es keine Datensätze.

In einem weiteren Beispiel nutzen wir rst.EOF bei einer Suche. Wir suchen mit der Find-Methode nach einem Datensatz mit einem bestimmten Kriterium. Nach der Suche prüfen wir, ob rst.EOF wahr ist. In diesem Fall wird die Suche als erfolglos gemeldet, anderenfalls wird der gefundene Datensatz ausgegeben:

...
rst.Find "Nachname = ''Meyer''"
    
If rst.EOF Then
     MsgBox "Kunde ''Meyer'' wurde nicht gefunden.", _
         vbInformation
Else
     MsgBox "Kunde gefunden: " & rst!Vorname & " " _
         & rst!Nachname
End If
...

Auf Felder zugreifen mit Fields

Über die Fields-Auflistung kannst Du auf einzelne Spalten eines Datensatzes zugreifen. Du kannst sowohl den Feldnamen als auch den Index (beginnend bei 0) verwenden.

Public Sub FeldZugriffBeispiel()
...
     rst.MoveFirst
     Debug.Print rst.Fields("Vorname").Value
     Debug.Print rst.Fields(2).Value
...
End Sub

EditMode

Mit EditMode lässt sich abfragen, ob das Recordset aktuell bearbeitet wird.

Diese Information ist besonders bei formulargebundenen oder interaktiv bearbeiteten Recordsets nützlich.

Public Sub BearbeitungsstatusPruefen()
     ...
     rst.Open "SELECT * FROM tblKunden", cnn, _
         adOpenKeyset, adLockOptimistic
     rst.MoveFirst
     rst!Ort = "Leipzig"
     If rst.EditMode = adEditInProgress Then
         Debug.Print "Bearbeitung aktiv."
     End If
     rst.Update
     ...    
End Sub

Datensätze hinzufügen mit AddNew/Update

Neue Datensätze lassen sich mit AddNew erstellen. Anschließend musst Du mit Update speichern. Hier ein vollständiges Beispiel:

Public Sub KundeHinzufuegen()
     ...
     rst.AddNew
     rst!Vorname = "Lisa"
     rst!Nachname = "Neumann"
     rst!Ort = "Hannover"
     rst.Update
     ...
End Sub

Datensätze löschen mit Delete

Um einen Datensatz zu löschen, positionierst Du das Recordset auf den gewünschten Eintrag und rufst Delete auf. Die Änderung wird sofort übernommen:

Public Sub KundeLoeschen()
     ...
     Set rst = New ADODB.Recordset
     rst.Open "SELECT * FROM tblKunden WHERE Nachname = " _
         "''Neumann''", cnn, adOpenKeyset, adLockOptimistic
     If Not rst.EOF Then
         rst.Delete
     End If
     ...
End Sub

Recordset filtern mit Filter

Mit der Eigenschaft Filter kannst Du ein geöffnetes Recordset einschränken. Der Filter wirkt sich auf die Navigation und Methoden wie MoveNext aus.

Public Sub KundenInBerlin()
     ...
     rst.Open "SELECT * FROM tblKunden", cnn, _
         adOpenKeyset, adLockOptimistic
     
     rst.Filter = "Ort = ''Leipzig''"
     Do Until rst.EOF
         Debug.Print rst!Vorname & " " & rst!Nachname
         rst.MoveNext
     Loop
     ...
End Sub

Datensatz suchen mit Find

Mit Find lässt sich der erste passende Datensatz ermitteln. Die Suche erfolgt relativ zur aktuellen Position. Als Parameter geben wir ein Filterkriterium an, das genauso aussieht wie das für die WHERE-Condition:

Public Sub KundeFinden()
     ...
     rst.Find "Nachname = ''Schmidt''"
     If Not rst.EOF Then
         Debug.Print "Gefunden: " & rst!Vorname
     End If
     ...
End Sub

Datensätze sortieren mit Sort

Mit Sort kannst Du die aktuelle Reihenfolge der Datensätze im Recordset ändern – ohne erneute Datenbankabfrage. Hier ist es allerdings erforderlich, dass wir explizit die Eigenschaft CursorLocation auf adUseClient einstellen. Bisher haben wir diese Einstellung nicht vorgenommen, weil dies nicht notwendig war. Mehr zu dieser Einstellung weiter unten.

Im Beispiel rufen wir die Sort-Methode mit dem Parameter Nachname DESC auf. Dadurch sortieren wir absteigend nach den Nachnamen:

Public Sub KundenSortieren()
     ...
     Set rst = New ADODB.Recordset
     rst.CursorLocation = adUseClient
     rst.Open "SELECT * FROM tblKunden", cnn, adOpenKeyset, adLockOptimistic
     
     rst.Sort = "Nachname DESC"
     rst.MoveFirst
     Do Until rst.EOF
         Debug.Print rst!Nachname
         rst.MoveNext
     Loop
     ---
End Sub

Wenn wir nicht nur nach einem Feld sortieren wollen, geben wir die Sortierkriterien durch Kommata getrennt an – genau wie in der ORDER BY-Klausel von SQL:

Public Sub KundenSortierenMehrereKriterien()
     ...    
     rst.Sort = "Nachname DESC, Vorname ASC"
     rst.MoveFirst
     Do Until rst.EOF
         Debug.Print rst!Nachname, rst!Vorname
         rst.MoveNext
     Loop
     ...
End Sub

GetRows

Mit GetRows lassen sich Datensätze blockweise als Array auslesen – effizient für Auswertungen oder Übergabe an andere Routinen.

Im folgenden Beispiel füllen wir ein Array auf Basis der GetRows-Funktion des ADODB-Recordsets. Danach durchlaufen wir alle Zeilen und Spalten und geben diese im Direktbereich von Access aus:

Public Sub KundenAlsArray()
     Dim arr As Variant
     ...
     arr = rst.GetRows
     For j = LBound(arr, 2) To UBound(arr, 2) ''Datensätze
         For i = LBound(arr, 1) To UBound(arr, 1) ''Felder
             Debug.Print arr(i, j);
             If i < UBound(arr, 1) Then Debug.Print " | ";
         Next i
         Debug.Print
     Next j
     ...
End Sub

Dies gibt die Daten wie folgt aus:

1  | Müller | Anna | Leipzig
  2  | Schmidt | Peter | Hamburg
  3  | Lehmann | Julia | München
  4  | Weber | Klaus | Stuttgart
  5  | Klein | Maria | Düsseldorf
  7  | Klein | Nina | Düsseldorf
  8  | Klein | Andrea | Düsseldorf

Navigieren mit MoveFirst, MoveLast, MoveNext und MovePrevious

Diese Methoden ermöglichen die Navigation im Recordset. MoveFirst springt zum ersten Datensatz, MoveLast zum letzten. MoveNext und MovePrevious bewegen den Zeiger jeweils vorwärts oder rückwärts.

Das folgende Beispiel zeigt die verschiedenen Aufrufe:

Public Sub NavigationKunden()
...
rst.Open "SELECT * FROM tblKunden", cnn, _
     adOpenStatic,  adLockReadOnly
rst.MoveLast
Debug.Print "Letzter Kunde: " & rst!Nachname
rst.MoveFirst
Debug.Print "Erster Kunde: " & rst!Nachname
rst.MoveNext
Debug.Print "Zweiter Kunde: " & rst!Nachname
...

Datensatzzeiger beliebig verschieben mit Move

Die Methode Move ermöglicht es Dir, den Datensatzzeiger um eine beliebige Anzahl von Positionen vorwärts oder rückwärts zu verschieben. Der erste Parameter gibt an, wie viele Datensätze der Zeiger verschoben werden soll. Positive Zahlen bewegen den Zeiger vorwärts, negative rückwärts. Ein zweiter, optionaler Parameter gibt an, von welcher Startposition aus die Bewegung erfolgen soll, meistens wird dieser aber nicht verwendet.

Beispiel:

rst.Move 3 " Springt drei Datensätze vor
rst.Move -1 " Springt einen Datensatz zurück

Properties

Das Properties-Objekt enthält zusätzliche Informationen zum Recordset – etwa Provider-spezifische Einstellungen.

Hier durchlaufen wir alle Property-Elemente in einer Do While-Schleife und geben jeweils den Property-Namen und den Wert im Direktbereich des VBA-Editors aus:

Public Sub EigenschaftenAuflisten()
     ...
     Dim prp As ADODB.Property
     For Each prp In rst.Properties
         Debug.Print prp.Name & ": " & prp.Value
     Next prp
     ...
End Sub

RecordCount

RecordCount liefert die Anzahl der Datensätze. Achtung: Bei Verwendung des Wertes adOpenForwardOnly für den dritten Parameter der Open-Methode ist diese Information erst nach vollständigem Durchlauf verfügbar.

Public Sub KundenZaehlen()
     ...    
     Debug.Print "Kundenanzahl: " & rst.RecordCount
     ...
End Sub

Requery

Requery lädt die Daten im Recordset neu – ideal nach Änderungen in der Datenquelle an anderer Stelle:

Public Sub KundenNeuLaden()
     ...
     rst.Requery
     Debug.Print "Neu geladen: " & rst.RecordCount _
         & " Datensätze"
     ...
End Sub

Resync

Mit der Methode Resync kannst Du den Inhalt eines Recordsets aktualisieren – entweder vollständig oder selektiv.

Das ist besonders nützlich, wenn sich die zugrunde liegenden Daten außerhalb des Recordsets geändert haben, zum Beispiel durch parallele Bearbeitung oder nach einem Abgleich mit dem Server.

Die Methode kann entweder für den aktuellen Datensatz oder das gesamte Recordset ausgeführt werden – je nach Parameterwahl:

  • adAffectCurrent: nur aktueller Datensatz
  • adAffectGroup: alle Datensätze mit gleichem Filter
  • adAffectAll: gesamtes Recordset

Im folgenden Beispiel aktualisieren wir gezielt den aktuellen Datensatz, um Änderungen von außen zu übernehmen (zum Beispiel durch andere Benutzer):

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar