{"id":55000471,"date":"2025-04-01T00:00:00","date_gmt":"2025-07-02T14:48:09","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=471"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"ADODB_Datenzugriff_mit_Recordsets","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/","title":{"rendered":"ADODB: Datenzugriff mit Recordsets"},"content":{"rendered":"<p><b>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&auml;ndige &Uuml;bersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl&auml;utern diese jeweils ausf&uuml;hrlich mit praktischen Beispielen. Besonderes Augenmerk legen wir auf die Ereignisse eines Recordsetes. Im Gegensatz zum DAO-Recordset bietet das ADODB-Recordset n&auml;mlich die M&ouml;glichkeit, auf verschiedene Ereignisse zu reagieren &#8211; beispielsweise auf &Auml;nderungen im Datensatz.<\/b><\/p>\n<h2>Beispieldatenbank<\/h2>\n<p>Die Beispiele dieses Artikels findest Du in der Beispieldatenbank <b>ADODB_Recordset_AlleEigenschaften.accdb<\/b>.<\/p>\n<h2>&Uuml;bersicht: Eigenschaften und Methoden<\/h2>\n<p>Im Folgenden geben wir eine Kurzbeschreibung aller verf&uuml;gbaren Eigenschaften und Methoden des <b>Recordset<\/b>-Objekts, bevor wir diese im Einzelnen detailliert erl&auml;utern:<\/p>\n<ul>\n<li><b>AbsolutePage<\/b>: Liefert oder setzt die aktuelle Seite bei Seitennavigation.<\/li>\n<li><b>AbsolutePosition<\/b>: Position des aktuellen Datensatzes im Recordset.<\/li>\n<li><b>ActiveCommand<\/b>: Liefert das zugeh&ouml;rige <b>Command<\/b>-Objekt.<\/li>\n<li><b>ActiveConnection<\/b>: Verbindung, mit der das Recordset verkn&uuml;pft ist.<\/li>\n<li><b>AddNew\/Update\/CancelUpdate<\/b>: Neue Datens&auml;tze hinzuf&uuml;gen und speichern.<\/li>\n<li><b>BOF\/EOF<\/b>: Gibt an, ob sich der Datensatzmarkierer vor dem ersten oder nach dem letzten Datensatz befindet.<\/li>\n<li><b>Bookmark\/CompareBookmarks<\/b>: Zum Speichern und Vergleichen von Positionen.<\/li>\n<li><b>CacheSize<\/b>: Anzahl Datens&auml;tze, die lokal zwischengespeichert werden.<\/li>\n<li><b>Cancel\/CancelBatch<\/b>: Bricht aktuelle Operationen ab.<\/li>\n<li><b>Clone<\/b>: Erstellt eine Kopie des Recordsets.<\/li>\n<li><b>Close\/Open<\/b>: &Ouml;ffnet oder schlie&szlig;t das referenzierte Recordset.<\/li>\n<li><b>CursorLocation\/CursorType<\/b>: Steuerung der Navigation und Server-\/Clientverarbeitung.<\/li>\n<li><b>Delete<\/b>: Entfernt den aktuellen Datensatz.<\/li>\n<li><b>EditMode<\/b>: Zeigt an, ob und wie ein Datensatz bearbeitet wird.<\/li>\n<li><b>Filter\/Find\/Seek<\/b>: Filtert Datens&auml;tze oder sucht bestimmte Inhalte.<\/li>\n<li><b>Fields<\/b>: Auflistung aller Felder eines Datensatzes.<\/li>\n<li><b>GetRows\/GetString<\/b>: Exportiert Daten als Array oder String.<\/li>\n<li><b>LockType<\/b>: Steuerung der Sperrmechanismen bei Bearbeitung.<\/li>\n<li><b>MoveFirst<\/b>: Navigiert zum ersten Datensatz im Recordset.<\/li>\n<li><b>MoveLast<\/b>: Navigiert zum letzten Datensatz im Recordset.<\/li>\n<li><b>MoveNext<\/b>: Navigiert zum n&auml;chsten Datensatz.<\/li>\n<li><b>MovePrevious<\/b>: Navigiert zum vorherigen Datensatz.<\/li>\n<li><b>Move: <\/b>Navigiert um eine bestimmte Anzahl Recordsets vor oder zur&uuml;ck.<\/li>\n<li><b>NextRecordset<\/b>: Weiteres Recordset aus einem Stapel.<\/li>\n<li><b>PageCount\/PageSize<\/b>: Paginierung gro&szlig;er Datenmengen.<\/li>\n<li><b>Properties<\/b>: Auflistung aller Eigenschaften.<\/li>\n<li><b>RecordCount<\/b>: Anzahl der Datens&auml;tze.<\/li>\n<li><b>Requery\/Resync<\/b>: Aktualisiert das Recordset mit aktuellen Daten.<\/li>\n<li><b>Save<\/b>: Speichert das Recordset als Datei.<\/li>\n<li><b>Sort<\/b>: Sortiert die Datens&auml;tze.<\/li>\n<li><b>Source\/State\/Status<\/b>: Informationsfelder zum Recordset.<\/li>\n<li><b>StayInSync\/Supports<\/b>: Steuerung von Synchronisierung und unterst&uuml;tzten Features.<\/li>\n<li><b>UpdateBatch<\/b>: Speichert mehrere &Auml;nderungen gesammelt.<\/li>\n<\/ul>\n<h2>Detaillierte Beschreibung aller Funktionen<\/h2>\n<p>Im folgenden Abschnitt erl&auml;utern wir jede dieser Methoden und Eigenschaften einzeln.<\/p>\n<p>Wir geben Anwendungsbeispiele, zeigen Einsatzm&ouml;glichkeiten in VBA und gehen auf Spezialf&auml;lle ein.<\/p>\n<h2>Beispielumgebung<\/h2>\n<p>In diesem Artikel verwenden wir durchg&auml;ngig die Tabelle <b>tblKunden<\/b> mit den Feldern <b>KundenID<\/b>, <b>Nachname<\/b>, <b>Vorname<\/b> und <b>Ort<\/b>. Die Datenbank enth&auml;lt f&uuml;nf Testdatens&auml;tze mit Namen und Orten.<\/p>\n<p>Diese erstellen wir mit einer eigenen Prozedur (siehe Listing 1).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TabelleKundenErstellenUndF&uuml;llen()\r\n     <span style=\"color:blue;\">Dim <\/span>cnn<span style=\"color:blue;\"> As <\/span>ADODB.Connection\r\n     <span style=\"color:blue;\">Dim <\/span>strPfad<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strSQL<span style=\"color:blue;\"> As String<\/span>\r\n     '' Verbindung zur aktuellen Access-Datenbank herstellen\r\n     <span style=\"color:blue;\">Set<\/span> cnn = <span style=\"color:blue;\">New<\/span> ADODB.Connection\r\n     strPfad = CurrentProject.FullName\r\n     cnn.ConnectionString = \"Provider=Microsoft.ACE.OLEDB.12.0;\" & _\r\n                            \"Data Source=\" & strPfad & \";\" & _\r\n                            \"Persist Security Info=False;\"\r\n     cnn.Open\r\n     '' Bestehende Tabelle l&ouml;schen (falls vorhanden)\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     cnn.Execute \"DROP TABLE tblKunden\"\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     '' Tabelle erstellen\r\n     strSQL = \"CREATE TABLE tblKunden (\" & _\r\n              \"KundenID AUTOINCREMENT PRIMARY KEY, \" & _\r\n              \"Nachname TEXT(50), \" & _\r\n              \"Vorname TEXT(50), \" & _\r\n              \"Ort TEXT(50))\"\r\n     cnn.Execute strSQL\r\n     '' Beispieldatens&auml;tze einf&uuml;gen\r\n     cnn.Execute \"INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''M&uuml;ller'', ''Anna'', ''Berlin'')\"\r\n     cnn.Execute \"INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Schmidt'', ''Peter'', ''Hamburg'')\"\r\n     cnn.Execute \"INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Lehmann'', ''Julia'', ''M&uuml;nchen'')\"\r\n     cnn.Execute \"INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Weber'', ''Klaus'', ''Stuttgart'')\"\r\n     cnn.Execute \"INSERT INTO tblKunden (Nachname, Vorname, Ort) VALUES (''Klein'', ''Maria'', ''D&uuml;sseldorf'')\"\r\n     '' Verbindung schlie&szlig;en\r\n     cnn.Close\r\n     <span style=\"color:blue;\">Set<\/span> cnn = Nothing\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Tabelle ''tblKunden'' wurde erstellt und mit Daten gef&uuml;llt.\", vbInformation\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Erstellen einer Tabelle mit Beispieldaten<\/span><\/b><\/p>\n<h2>Verbindung und Recordset &ouml;ffnen<\/h2>\n<p>Alle folgenden Beispiele beginnen mit dem vollst&auml;ndigen Aufbau einer ADODB-Verbindung zu einer Access-Datenbank und dem &Ouml;ffnen eines Recordsets auf Basis der Tabelle <b>tblKunden<\/b>.<\/p>\n<p>Ein Beispiel hierzu sehen wir in Listing 2. Hier erstellen wir ein <b>Connection<\/b>-Objekt und f&uuml;llen es mit einem Verweis auf die Connection der aktuellen Access-Datenbank (<b>CurrentProject.Connection<\/b>).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenRecordsetOeffnen()\r\n     <span style=\"color:blue;\">Dim <\/span>cnn<span style=\"color:blue;\"> As <\/span>ADODB.Connection\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> cnn = CurrentProject.Connection\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, adOpenKeyset, adLockOptimistic\r\n     Do Until rst.EOF\r\n         <span style=\"color:blue;\">Debug.Print<\/span> rst!Vorname & \" \" & rst!Nachname\r\n         rst.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     rst.Close\r\n     <span style=\"color:blue;\">Set<\/span> rst = Nothing\r\n     cnn.Close\r\n     <span style=\"color:blue;\">Set<\/span> cnn = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Prozedur zum Durchlaufen von Kundendatens&auml;tzen<\/span><\/b><\/p>\n<p>Danach erstellen und &ouml;ffnen wir ein Recordset auf Basis der Tabelle <b>tblKunden<\/b>. Die Details beschreiben wir sp&auml;ter. Schlie&szlig;lich durchlaufen wir in einer <b>Do While<\/b>-Schleife alle Datens&auml;tze dieses Recordsets.<\/p>\n<h2>EOF und BOF<\/h2>\n<p>Die Eigenschaften <b>EOF<\/b> (End of File) und <b>BOF<\/b> (Beginning of File) zeigen an, ob sich der Datensatzzeiger am Ende oder vor dem Anfang des Recordsets befindet.<\/p>\n<p>Beide Eigenschaften sind vom Typ <b>Boolean<\/b> und spielen eine zentrale Rolle bei der sicheren Navigation durch Daten.<\/p>\n<p>Insbesondere bei leeren Recordsets ist es wichtig, beide Eigenschaften zu pr&uuml;fen: Ist <b>EOF<\/b> und <b>BOF<\/b> gleichzeitig <b>True<\/b>, enth&auml;lt das Recordset keine Datens&auml;tze &#8211; weder vorne noch hinten<\/p>\n<p>In Listing 3 erstellen wir ein Recordset, das keine Datens&auml;tze enth&auml;lt, da das Kriterium (1=2) f&uuml;r keinen Datensatz erf&uuml;llt wird.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenDurchlaufen()\r\n     <span style=\"color:blue;\">Dim <\/span>cnn<span style=\"color:blue;\"> As <\/span>ADODB.Connection\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> cnn = CurrentProject.Connection\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     rst.Open \"SELECT * FROM tblKunden WHERE 1 = 2\", cnn, adOpenKeyset, adLockOptimistic\r\n     <span style=\"color:blue;\">If <\/span>rst.BOF And rst.EOF<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Keine Datens&auml;tze vorhanden.\"\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         ''Operationen f&uuml;r vorhandene Datens&auml;tze\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     rst.Close\r\n     <span style=\"color:blue;\">Set<\/span> rst = Nothing\r\n     cnn.Close\r\n     <span style=\"color:blue;\">Set<\/span> cnn = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Pr&uuml;fen, ob sich der Datensatzzeiger vor oder hinter dem ersten oder letzten Datensatz befindet.<\/span><\/b><\/p>\n<p>Hier pr&uuml;fen wir, ob <b>rst.EOF <\/b>und <b>rst.BOF <\/b>gleichzeitig <b>True <\/b>liefern. In diesem Fall gibt es keine Datens&auml;tze.<\/p>\n<p>In einem weiteren Beispiel nutzen wir <b>rst.EOF <\/b>bei einer Suche. Wir suchen mit der <b>Find<\/b>-Methode nach einem Datensatz mit einem bestimmten Kriterium. Nach der Suche pr&uuml;fen wir, ob <b>rst.EOF <\/b>wahr ist. In diesem Fall wird die Suche als erfolglos gemeldet, anderenfalls wird der gefundene Datensatz ausgegeben:<\/p>\n<pre>...\r\nrst.Find \"Nachname = ''Meyer''\"\r\n    \r\n<span style=\"color:blue;\">If <\/span>rst.EOF<span style=\"color:blue;\"> Then<\/span>\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Kunde ''Meyer'' wurde nicht gefunden.\", _\r\n         vbInformation\r\n<span style=\"color:blue;\">Else<\/span>\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Kunde gefunden: \" & rst!Vorname & \" \" _\r\n         & rst!Nachname\r\n<span style=\"color:blue;\">End If<\/span>\r\n...<\/pre>\n<h2>Auf Felder zugreifen mit Fields<\/h2>\n<p>&Uuml;ber die <b>Fields<\/b>-Auflistung kannst Du auf einzelne Spalten eines Datensatzes zugreifen. Du kannst sowohl den Feldnamen als auch den Index (beginnend bei <b>0<\/b>) verwenden.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>FeldZugriffBeispiel()\r\n...\r\n     rst.MoveFirst\r\n     <span style=\"color:blue;\">Debug.Print<\/span> rst.Fields(\"Vorname\").Value\r\n     <span style=\"color:blue;\">Debug.Print<\/span> rst.Fields(2).Value\r\n...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>EditMode<\/h2>\n<p>Mit <b>EditMode<\/b> l&auml;sst sich abfragen, ob das Recordset aktuell bearbeitet wird.<\/p>\n<p>Diese Information ist besonders bei formulargebundenen oder interaktiv bearbeiteten Recordsets n&uuml;tzlich.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>BearbeitungsstatusPruefen()\r\n     ...\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, _\r\n         adOpenKeyset, adLockOptimistic\r\n     rst.MoveFirst\r\n     rst!Ort = \"Leipzig\"\r\n     <span style=\"color:blue;\">If <\/span>rst.EditMode = adEditInProgress<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Debug.Print<\/span> \"Bearbeitung aktiv.\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     rst.Update\r\n     ...    \r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Datens&auml;tze hinzuf&uuml;gen mit AddNew\/Update<\/h2>\n<p>Neue Datens&auml;tze lassen sich mit <b>AddNew<\/b> erstellen. Anschlie&szlig;end musst Du mit <b>Update<\/b> speichern. Hier ein vollst&auml;ndiges Beispiel:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundeHinzufuegen()\r\n     ...\r\n     rst.Add<span style=\"color:blue;\">New<\/span>\r\n     rst!Vorname = \"Lisa\"\r\n     rst!Nachname = \"Neumann\"\r\n     rst!Ort = \"Hannover\"\r\n     rst.Update\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Datens&auml;tze l&ouml;schen mit Delete<\/h2>\n<p>Um einen Datensatz zu l&ouml;schen, positionierst Du das Recordset auf den gew&uuml;nschten Eintrag und rufst <b>Delete<\/b> auf. Die &Auml;nderung wird sofort &uuml;bernommen:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundeLoeschen()\r\n     ...\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     rst.Open \"SELECT * FROM tblKunden WHERE Nachname = \" _\r\n         \"''Neumann''\", cnn, adOpenKeyset, adLockOptimistic\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rst.EOF<span style=\"color:blue;\"> Then<\/span>\r\n         rst.Delete\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Recordset filtern mit Filter<\/h2>\n<p>Mit der Eigenschaft <b>Filter<\/b> kannst Du ein ge&ouml;ffnetes Recordset einschr&auml;nken. Der Filter wirkt sich auf die Navigation und Methoden wie <b>MoveNext<\/b> aus.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenInBerlin()\r\n     ...\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, _\r\n         adOpenKeyset, adLockOptimistic\r\n     \r\n     rst.Filter = \"Ort = ''Leipzig''\"\r\n     Do Until rst.EOF\r\n         <span style=\"color:blue;\">Debug.Print<\/span> rst!Vorname & \" \" & rst!Nachname\r\n         rst.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Datensatz suchen mit Find<\/h2>\n<p>Mit <b>Find<\/b> l&auml;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&uuml;r die <b>WHERE<\/b>-Condition:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundeFinden()\r\n     ...\r\n     rst.Find \"Nachname = ''Schmidt''\"\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rst.EOF<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Debug.Print<\/span> \"Gefunden: \" & rst!Vorname\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Datens&auml;tze sortieren mit Sort<\/h2>\n<p>Mit <b>Sort<\/b> kannst Du die aktuelle Reihenfolge der Datens&auml;tze im Recordset &auml;ndern &#8211; ohne erneute Datenbankabfrage. Hier ist es allerdings erforderlich, dass wir explizit die Eigenschaft <b>CursorLocation <\/b>auf <b>adUseClient <\/b>einstellen. Bisher haben wir diese Einstellung nicht vorgenommen, weil dies nicht notwendig war. Mehr zu dieser Einstellung weiter unten.<\/p>\n<p>Im Beispiel rufen wir die <b>Sort<\/b>-Methode mit dem Parameter <b>Nachname DESC <\/b>auf. Dadurch sortieren wir absteigend nach den Nachnamen:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenSortieren()\r\n     ...\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     rst.CursorLocation = adUseClient\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, adOpenKeyset, adLockOptimistic\r\n     \r\n     rst.Sort = \"Nachname DESC\"\r\n     rst.MoveFirst\r\n     Do Until rst.EOF\r\n         <span style=\"color:blue;\">Debug.Print<\/span> rst!Nachname\r\n         rst.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     ---\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Wenn wir nicht nur nach einem Feld sortieren wollen, geben wir die Sortierkriterien durch Kommata getrennt an &#8211; genau wie in der <b>ORDER BY<\/b>-Klausel von SQL:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenSortierenMehrereKriterien()\r\n     ...    \r\n     rst.Sort = \"Nachname DESC, Vorname ASC\"\r\n     rst.MoveFirst\r\n     Do Until rst.EOF\r\n         <span style=\"color:blue;\">Debug.Print<\/span> rst!Nachname, rst!Vorname\r\n         rst.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>GetRows<\/h2>\n<p>Mit <b>GetRows<\/b> lassen sich Datens&auml;tze blockweise als Array auslesen &#8211; effizient f&uuml;r Auswertungen oder &Uuml;bergabe an andere Routinen.<\/p>\n<p>Im folgenden Beispiel f&uuml;llen wir ein Array auf Basis der <b>GetRows<\/b>-Funktion des ADODB-Recordsets. Danach durchlaufen wir alle Zeilen und Spalten und geben diese im Direktbereich von Access aus:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenAlsArray()\r\n     <span style=\"color:blue;\">Dim <\/span>arr<span style=\"color:blue;\"> As Variant<\/span>\r\n     ...\r\n     arr = rst.GetRows\r\n     For j = <span style=\"color:blue;\">LBound<\/span>(arr, 2) To <span style=\"color:blue;\">UBound<\/span>(arr, 2) ''Datens&auml;tze\r\n         For i = <span style=\"color:blue;\">LBound<\/span>(arr, 1) To <span style=\"color:blue;\">UBound<\/span>(arr, 1) ''Felder\r\n             <span style=\"color:blue;\">Debug.Print<\/span> arr(i, j);\r\n             <span style=\"color:blue;\">If <\/span>i &lt; <span style=\"color:blue;\">UBound<\/span>(arr, 1)<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Debug.Print<\/span> \" | \";\r\n         <span style=\"color:blue;\">Next<\/span> i\r\n         <span style=\"color:blue;\">Debug.Print<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> j\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Dies gibt die Daten wie folgt aus:<\/p>\n<pre>1  | M&uuml;ller | Anna | Leipzig\r\n  2  | Schmidt | Peter | Hamburg\r\n  3  | Lehmann | Julia | M&uuml;nchen\r\n  4  | Weber | Klaus | Stuttgart\r\n  5  | Klein | Maria | D&uuml;sseldorf\r\n  7  | Klein | Nina | D&uuml;sseldorf\r\n  8  | Klein | Andrea | D&uuml;sseldorf<\/pre>\n<h2>Navigieren mit MoveFirst, MoveLast, MoveNext und MovePrevious<\/h2>\n<p>Diese Methoden erm&ouml;glichen die Navigation im Recordset. <b>MoveFirst<\/b> springt zum ersten Datensatz, <b>MoveLast<\/b> zum letzten. <b>MoveNext<\/b> und <b>MovePrevious<\/b> bewegen den Zeiger jeweils vorw&auml;rts oder r&uuml;ckw&auml;rts.<\/p>\n<p>Das folgende Beispiel zeigt die verschiedenen Aufrufe:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>NavigationKunden()\r\n...\r\nrst.Open \"SELECT * FROM tblKunden\", cnn, _\r\n     adOpenStatic,  adLockReadOnly\r\nrst.MoveLast\r\n<span style=\"color:blue;\">Debug.Print<\/span> \"Letzter Kunde: \" & rst!Nachname\r\nrst.MoveFirst\r\n<span style=\"color:blue;\">Debug.Print<\/span> \"Erster Kunde: \" & rst!Nachname\r\nrst.Move<span style=\"color:blue;\">Next<\/span>\r\n<span style=\"color:blue;\">Debug.Print<\/span> \"Zweiter Kunde: \" & rst!Nachname\r\n...<\/pre>\n<h2>Datensatzzeiger beliebig verschieben mit Move<\/h2>\n<p>Die Methode <b>Move<\/b> erm&ouml;glicht es Dir, den Datensatzzeiger um eine beliebige Anzahl von Positionen vorw&auml;rts oder r&uuml;ckw&auml;rts zu verschieben. Der erste Parameter gibt an, wie viele Datens&auml;tze der Zeiger verschoben werden soll. Positive Zahlen bewegen den Zeiger vorw&auml;rts, negative r&uuml;ckw&auml;rts. Ein zweiter, optionaler Parameter gibt an, von welcher Startposition aus die Bewegung erfolgen soll, meistens wird dieser aber nicht verwendet.<\/p>\n<p>Beispiel:<\/p>\n<pre>rst.Move 3 \" Springt drei Datens&auml;tze vor\r\nrst.Move -1 \" Springt einen Datensatz zur&uuml;ck<\/pre>\n<h2>Properties<\/h2>\n<p>Das <b>Properties<\/b>-Objekt enth&auml;lt zus&auml;tzliche Informationen zum Recordset &#8211; etwa Provider-spezifische Einstellungen.<\/p>\n<p>Hier durchlaufen wir alle <b>Property<\/b>-Elemente in einer <b>Do While<\/b>-Schleife und geben jeweils den <b>Property<\/b>-Namen und den Wert im Direktbereich des VBA-Editors aus:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>EigenschaftenAuflisten()\r\n     ...\r\n     <span style=\"color:blue;\">Dim <\/span>prp<span style=\"color:blue;\"> As <\/span>ADODB.Property\r\n     For Each prp In rst.Properties\r\n         <span style=\"color:blue;\">Debug.Print<\/span> prp.Name & \": \" & prp.Value\r\n     <span style=\"color:blue;\">Next<\/span> prp\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>RecordCount<\/h2>\n<p><b>RecordCount<\/b> liefert die Anzahl der Datens&auml;tze. Achtung: Bei Verwendung des Wertes <b>adOpenForwardOnly<\/b> f&uuml;r den dritten Parameter der <b>Open<\/b>-Methode ist diese Information erst nach vollst&auml;ndigem Durchlauf verf&uuml;gbar.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenZaehlen()\r\n     ...    \r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Kundenanzahl: \" & rst.RecordCount\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Requery<\/h2>\n<p><b>Requery<\/b> l&auml;dt die Daten im Recordset neu &#8211; ideal nach &Auml;nderungen in der Datenquelle an anderer Stelle:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenNeuLaden()\r\n     ...\r\n     rst.Requery\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Neu geladen: \" & rst.RecordCount _\r\n         & \" Datens&auml;tze\"\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Resync<\/h2>\n<p>Mit der Methode <b>Resync<\/b> kannst Du den Inhalt eines Recordsets aktualisieren &#8211; entweder vollst&auml;ndig oder selektiv.<\/p>\n<p>Das ist besonders n&uuml;tzlich, wenn sich die zugrunde liegenden Daten au&szlig;erhalb des Recordsets ge&auml;ndert haben, zum Beispiel durch parallele Bearbeitung oder nach einem Abgleich mit dem Server.<\/p>\n<p>Die Methode kann entweder f&uuml;r den aktuellen Datensatz oder das gesamte Recordset ausgef&uuml;hrt werden &#8211; je nach Parameterwahl:<\/p>\n<ul>\n<li><b>adAffectCurrent<\/b>: nur aktueller Datensatz<\/li>\n<li><b>adAffectGroup<\/b>: alle Datens&auml;tze mit gleichem Filter<\/li>\n<li><b>adAffectAll<\/b>: gesamtes Recordset<\/li>\n<\/ul>\n<p>Im folgenden Beispiel aktualisieren wir gezielt den aktuellen Datensatz, um &Auml;nderungen von au&szlig;en zu &uuml;bernehmen (zum Beispiel durch andere Benutzer):<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>AktuellenKundenResyncen()\r\n     ...\r\n     rst.CursorLocation = adUseClient\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, _\r\n         adOpenKeyset, adLockOptimistic\r\n     rst.MoveFirst\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Vor Resync: \" & rst!Ort\r\n     rst.Resync adAffectCurrent\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Nach Resync: \" & rst!Ort\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Um alle Daten im Recordset auf den aktuellen Stand zu bringen, etwa nach &Auml;nderungen in der Tabelle durch andere Prozesse, verwendest Du:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>GesamtesRecordsetResyncen()\r\n     ...\r\n     rst.Resync adAffectAll\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Synchronisierung abgeschlossen.\"\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>&Auml;nderungen auf einen Rutsch mit UpdateBatch<\/h2>\n<p>Die Methode <b>UpdateBatch<\/b> dient dazu, mehrere &Auml;nderungen im Recordset auf einmal an die zugrunde liegende Datenquelle zu &uuml;bergeben. Diese Technik ist besonders n&uuml;tzlich, wenn Du im Hintergrund mehrere <b>AddNew<\/b>-, <b>Update<\/b>&#8211; oder <b>Delete<\/b>-Operationen ausf&uuml;hrst und erst sp&auml;ter gesammelt speichern willst.<\/p>\n<p>Damit <b>UpdateBatch<\/b> verwendet werden kann, muss das Recordset im <b>BatchUpdate<\/b>-Modus ge&ouml;ffnet sein. Daf&uuml;r sind zwei Voraussetzungen notwendig:<\/p>\n<ul>\n<li><b>CursorLocation<\/b> = <b>adUseClient<\/b><\/li>\n<li><b>LockType<\/b> = <b>adLockBatchOptimistic<\/b><\/li>\n<\/ul>\n<p>Ein Typisches Einsatzszenario ist, dass Du ein Recordset vollst&auml;ndig in den Speicher l&auml;dst, &Auml;nderungen an mehreren Zeilen vornimmst und sie erst nach der Validierung gesammelt an die Datenbank &uuml;bergibst.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenBatchSpeichern()\r\n     ...\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, _\r\n         adOpenStatic, adLockBatchOptimistic\r\n     rst.Add<span style=\"color:blue;\">New<\/span>\r\n     rst!Vorname = \"Anja\"\r\n     rst!Nachname = \"Kaiser\"\r\n     rst!Ort = \"Mainz\"\r\n     rst.Update\r\n     rst.Add<span style=\"color:blue;\">New<\/span>\r\n     rst!Vorname = \"Leon\"\r\n     rst!Nachname = \"Brandt\"\r\n     rst!Ort = \"Trier\"\r\n     rst.Update\r\n     rst.UpdateBatch\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Der Vorteil von <b>UpdateBatch<\/b> liegt bei:<\/p>\n<ul>\n<li>Validierung von &Auml;nderungen vor dem Speichern<\/li>\n<li>M&ouml;glichst wenige Schreibzugriffe bei Netzwerkverbindungen<\/li>\n<li>Aktualisierung mehrerer logisch zusammenh&auml;ngender Datens&auml;tze<\/li>\n<\/ul>\n<p>Nach dem Aufruf von <b>UpdateBatch<\/b> kannst Du den <b>Status<\/b> jedes Datensatzes auswerten und gezielt Konflikte oder Fehler behandeln.<\/p>\n<h2>Speichern von Recordsets in eine Datei mit Save<\/h2>\n<p><b>Save<\/b> speichert ein Recordset in eine Datei, zum Beispiel als XML-Datei. Dies ist praktisch f&uuml;r Offline-Verarbeitung oder Datensicherung:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>KundenExportieren()\r\n...\r\n     rst.Save CurrentProject.Path & \"\\kunden.xml\", _\r\n         adPersistXML\r\n...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>NextRecordset<\/h2>\n<p>Mit der Methode <b>NextRecordset<\/b> kannst Du innerhalb eines Recordsets zum n&auml;chsten Teilergebnis springen, also zum Beispiel, wenn ein SQL-Befehl mehrere <b>SELECT<\/b>-Anweisungen enth&auml;lt oder eine gespeicherte Prozedur mehrere Resultsets zur&uuml;ckgibt.<\/p>\n<p>Typische Einsatzszenarien:<\/p>\n<ul>\n<li>Mehrere <b>SELECT<\/b>-Anweisungen in einem einzigen SQL-Text<\/li>\n<li>R&uuml;ckgabe mehrerer Ergebnismengen aus einer gespeicherten Prozedur (SQL Server)<\/li>\n<li>Analyse von Systemabfragen oder kombinierten Reports<\/li>\n<\/ul>\n<p>Der erste <b>Open<\/b>-Aufruf liefert das erste Resultset. Danach wechselst Du mit <b>NextRecordset<\/b> auf das n&auml;chste &#8211; bis die Methode <b>Nothing<\/b> zur&uuml;ckgibt.<\/p>\n<p>Beispiel: Zwei <b>SELECT<\/b>-Anweisungen in einem Befehl lassen sich wie folgt verarbeiten.<\/p>\n<p>Voraussetzung daf&uuml;r ist allerdings, dass wir die Daten aus einem Provider beziehen, der mehrere Resultsets unterst&uuml;tzt. Bei Access ist das nicht der Fall, aber zum Beispiel bei SQL Server. Dann k&ouml;nnen wir eine solche Abfrage &ouml;ffnen und die Recordsets mit <b>NextRecordset <\/b>durchlaufen:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>MehrereRecordsets()\r\n     <span style=\"color:blue;\">Set<\/span> cnn = <span style=\"color:blue;\">New<\/span> ADODB.Connection\r\n     cnn.ConnectionString = \"...SQL Server-Connection...\"\r\n     cnn.Open    \r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     rst.Open \"SELECT * FROM tblKunden;\"_\r\n         \"SELECT * FROM tblKunden WHERE Ort = \"K&ouml;ln''\", _\r\n         cnn, adOpenStatic, adLockReadOnly\r\n     \r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Erstes Recordset: \" & rst.RecordCount\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> rs2 = rst.NextRecordset\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rs2 Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">Debug.Print<\/span> \"Zweites Recordset: \" _\r\n             & rs2.RecordCount\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     \r\n     rst.Close\r\n     rs2.Close\r\n     <span style=\"color:blue;\">Set<\/span> rst = Nothing\r\n     <span style=\"color:blue;\">Set<\/span> rs2 = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Supports<\/h2>\n<p>Mit <b>Supports<\/b> pr&uuml;fst Du, ob ein bestimmtes Feature vom Recordset unterst&uuml;tzt wird.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>PruefeBatchUnterstuetzung()\r\n...\r\n     <span style=\"color:blue;\">If <\/span>rst.Supports(adUpdateBatch)<span style=\"color:blue;\"> Then<\/span>\r\n         <span style=\"color:blue;\">MsgBox<\/span> \"Batch Update wird unterst&uuml;tzt.\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Abgefragt werden k&ouml;nnen unter anderem folgende Konstanten:<\/p>\n<ul>\n<li><b>adAddNew<\/b>: Gibt an, ob das Recordset das Hinzuf&uuml;gen neuer Datens&auml;tze &uuml;ber <b>AddNew<\/b>: unterst&uuml;tzt.<\/li>\n<li><b>adDelete<\/b>: Gibt an, ob Datens&auml;tze mit <b>Delete <\/b>entfernt werden k&ouml;nnen.<\/li>\n<li><b>adUpdate<\/b>: Zeigt an, ob &Auml;nderungen an Feldern mit <b>Update<\/b> gespeichert werden k&ouml;nnen.<\/li>\n<li><b>adBookmark<\/b>: Erm&ouml;glicht den Einsatz von Bookmarks zur Navigation und Speicherung von Positionen im Recordset.<\/li>\n<li><b>adSeek<\/b>: Gibt an, ob mit <b>Seek<\/b> ein Direktzugriff &uuml;ber indizierte Felder m&ouml;glich ist (nur mit bestimmten Providern wie Jet).<\/li>\n<li><b>adUpdateBatch<\/b>: Gibt an, ob Batch-&Auml;nderungen unterst&uuml;tzt werden &#8211; das hei&szlig;t, mehrere &Auml;nderungen werden gesammelt und gemeinsam &uuml;ber <b>UpdateBatch<\/b> gespeichert.<\/li>\n<\/ul>\n<h2>StayInSync<\/h2>\n<p><b>StayInSync<\/b> ist nur bei hierarchischen Recordsets relevant &#8211; zum Beispiel bei DataShape-Providern. In Access spielt es keine praktische Rolle.<\/p>\n<h2>State<\/h2>\n<p>Die Eigenschaft <b>State<\/b> gibt den aktuellen Verbindungs- oder Objektstatus eines ADODB-Objekts zur&uuml;ck. Dabei handelt es sich um eine Bitmaske (Integerwert), der je nach Objekt verschiedene Status anzeigt. Bei Recordsets und Verbindungen wird so zum Beispiel unterschieden, ob das Objekt ge&ouml;ffnet ist oder nicht.<\/p>\n<p>F&uuml;r Recordsets liefert <b>State<\/b> typischerweise einen der folgenden Werte:<\/p>\n<ul>\n<li><b>adStateClosed<\/b> (0): Das Recordset ist geschlossen.<\/li>\n<li><b>adStateOpen<\/b> (1): Das Recordset ist ge&ouml;ffnet.<\/li>\n<li><b>adStateConnecting<\/b> (2): Wird verwendet bei Verbindungen &#8211; das Objekt stellt gerade eine Verbindung her.<\/li>\n<li><b>adStateExecuting<\/b> (4): Es wird gerade ein Befehl ausgef&uuml;hrt.<\/li>\n<li><b>adStateFetching<\/b> (8): Daten werden gerade abgerufen.<\/li>\n<\/ul>\n<p>Da es sich um eine Bitmaske handelt, k&ouml;nnen mehrere Zust&auml;nde gleichzeitig zutreffen &#8211; zum Beispiel <b>adStateOpen + adStateFetching<\/b>.<\/p>\n<p>Das folgende Beispiel gibt den <b>State<\/b>-Wert f&uuml;r verschiedene Zust&auml;nde des Recordsets zur&uuml;ck:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>RecordsetStatusTest()\r\n     ...\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     \r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Nach Initialisierung: \" & rst.State\r\n     \r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, _\r\n         adOpenStatic, adLockReadOnly\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Nach &Ouml;ffnen: \" & rst.State\r\n     \r\n     rst.Close\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Nach Schlie&szlig;en: \" & rst.State\r\n     ...\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Status<\/h2>\n<p>Die Eigenschaft <b>Status<\/b> liefert f&uuml;r jeden Datensatz eines Recordsets Informationen dar&uuml;ber, ob &Auml;nderungen erfolgt sind, Konflikte vorliegen oder der Datensatz gel&ouml;scht wurde. Diese Eigenschaft ist besonders im Zusammenhang mit <b>Batch-Updates<\/b> wichtig.<\/p>\n<p>Die m&ouml;glichen Werte sind Bitmasken und lassen sich daher auch kombinieren:<\/p>\n<ul>\n<li><b>adRecOK<\/b> (<b>0<\/b>): Kein Fehler, Datensatz ist g&uuml;ltig.<\/li>\n<li><b>adRecNew<\/b> (<b>1<\/b>): Datensatz wurde hinzugef&uuml;gt.<\/li>\n<li><b>adRecModified<\/b> (<b>2<\/b>): Datensatz wurde ge&auml;ndert.<\/li>\n<li><b>adRecDeleted<\/b> (<b>4<\/b>): Datensatz wurde gel&ouml;scht.<\/li>\n<li><b>adRecUnmodified<\/b> (<b>8<\/b>): Keine &Auml;nderungen.<\/li>\n<li><b>adRecInvalid<\/b> <b>(16<\/b>): Ung&uuml;ltiger Datensatz (z. B. nach Fehler).<\/li>\n<li><b>adRecMultipleChanges<\/b> (<b>64<\/b>): Mehrere &Auml;nderungen (z. B. Konflikt).<\/li>\n<li><b>adRecPendingChanges<\/b> (<b>128<\/b>): &Auml;nderungen stehen noch aus.<\/li>\n<li><b>adRecCanceled<\/b> (<b>256<\/b>): &Auml;nderung wurde verworfen.<\/li>\n<li><b>adRecCantRelease<\/b> (<b>1024<\/b>): Kann nicht freigegeben werden.<\/li>\n<li><b>adRecConcurrencyViolation<\/b> (<b>2048<\/b>): Zeitgleich bearbeitet.<\/li>\n<li><b>adRecIntegrityViolation<\/b> (<b>4096<\/b>): Versto&szlig; gegen Integrit&auml;t.<\/li>\n<li><b>adRecSchemaViolation<\/b> (<b>8192<\/b>): Schemafehler.<\/li>\n<li><b>adRecDBDeleted<\/b> (262144): Datensatz wurde in DB gel&ouml;scht.<\/li>\n<\/ul>\n<p>Im folgenden Beispiel werden mehrere &Auml;nderungen vorgenommen und anschlie&szlig;end alle Statuswerte der betroffenen Datens&auml;tze analysiert:<\/p>\n<p>Das folgende Beispiel demonstriert, wie neue, ge&auml;nderte und gel&ouml;schte Datens&auml;tze im Recordset erkannt und ausgegeben werden k&ouml;nnen. Voraussetzung ist die Verwendung eines clientseitigen Cursors in Verbindung mit <b>adLockBatchOptimistic<\/b>.<\/p>\n<p>Im Beispiel wird ein Kunde neu angelegt, ein anderer aktualisiert und ein dritter gel&ouml;scht. Einen vierten belassen wir unver&auml;ndert. Nach jeder Aktion wird der aktuelle Status ausgeben:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>GezielteStatusAuswertung()\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     rst.CursorLocation = adUseClient\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, _\r\n         adOpenStatic, adLockBatchOptimistic\r\n     ''Neuen Datensatz hinzuf&uuml;gen\r\n     rst.Add<span style=\"color:blue;\">New<\/span>\r\n     rst!Vorname = \"Tom\"\r\n     rst!Nachname = \"Mustermann\"\r\n     rst!Ort = \"Berlin\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> rst.Status\r\n     rst.Update\r\n     ''Einen bestehenden Datensatz &auml;ndern\r\n     rst.MoveFirst\r\n     rst!Ort = \"Hamburg\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> rst.Status\r\n     rst.Update\r\n     ''Einen anderen Datensatz l&ouml;schen\r\n     rst.Move<span style=\"color:blue;\">Next<\/span>\r\n     rst.Delete\r\n     <span style=\"color:blue;\">Debug.Print<\/span> rst.Status\r\n     ''Den n&auml;chsten Datensatz unver&auml;ndert lassen\r\n     rst.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Debug.Print<\/span> rst.Status\r\n     rst.Close\r\n     <span style=\"color:blue;\">Set<\/span> rst = Nothing\r\n     cnn.Close\r\n     <span style=\"color:blue;\">Set<\/span> cnn = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>StayInSync<\/h2>\n<p><b>StayInSync<\/b> ist nur bei hierarchischen Recordsets relevant &#8211; zum Beispiel bei DataShape-Providern. In Access spielt es keine praktische Rolle.<\/p>\n<h2>Supports<\/h2>\n<p>Mit der Methode <b>Supports<\/b> kannst Du pr&uuml;fen, ob ein bestimmtes Feature im aktuellen Recordset unterst&uuml;tzt wird. Dies ist besonders wichtig, um zur Laufzeit dynamisch auf unterschiedliche Cursor- oder Lock-Typen reagieren zu k&ouml;nnen &#8211; zum Beispiel, ob <b>Seek<\/b> oder <b>UpdateBatch<\/b> verf&uuml;gbar ist.<\/p>\n<p>Die m&ouml;glichen Konstanten lauten:<\/p>\n<ul>\n<li><b>adAddNew<\/b>: K&ouml;nnen neue Datens&auml;tze hinzugef&uuml;gt werden (zum Beispiel mit <b>AddNew<\/b>)?<\/li>\n<li><b>adDelete<\/b>: K&ouml;nnen Datens&auml;tze gel&ouml;scht werden?<\/li>\n<li><b>adUpdate<\/b>: Werden &Auml;nderungen an bestehenden Datens&auml;tzen werden unterst&uuml;tzt?<\/li>\n<li><b>adBookmark<\/b>: K&ouml;nnen Datens&auml;tze mit <b>Bookmark<\/b> referenziert werden?<\/li>\n<li><b>adSeek<\/b>: Ist die <b>Seek<\/b>-Methode ist verf&uuml;gbar? Hier ist ein Index erforderlich.<\/li>\n<li><b>adUpdateBatch<\/b>: Liegt Unterst&uuml;tzung f&uuml;r <b>Batch-Updates<\/b> (zum Beispiel bei clientseitigen Recordsets) vor?<\/li>\n<\/ul>\n<p>In Listing 4 ist ein Beispiel, um die verschiedenen Funktionen abzufragen.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>RecordsetFaehigkeitenTesten()\r\n     <span style=\"color:blue;\">Dim <\/span>cnn<span style=\"color:blue;\"> As <\/span>ADODB.Connection\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> cnn = CurrentProject.Connection\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, adOpenKeyset, adLockOptimistic\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Unterst&uuml;tzt AddNew: \" & rst.Supports(adAdd<span style=\"color:blue;\">New<\/span>)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Unterst&uuml;tzt Delete: \" & rst.Supports(adDelete)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Unterst&uuml;tzt Update: \" & rst.Supports(adUpdate)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Unterst&uuml;tzt UpdateBatch: \" & rst.Supports(adUpdateBatch)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Unterst&uuml;tzt Bookmark: \" & rst.Supports(adBookmark)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Unterst&uuml;tzt Seek: \" & rst.Supports(adSeek)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Verschiedene Funktionen des Recordsets pr&uuml;fen<\/span><\/b><\/p>\n<p>Hinweis: Viele dieser Funktionen stehen nur bei bestimmten Kombinationen aus <b>CursorType<\/b>, <b>LockType<\/b> und <b>CursorLocation<\/b> zur Verf&uuml;gung. So funktioniert <b>Seek<\/b> zum Beispiel nur bei <b>adOpenKeyset<\/b> mit <b>Index<\/b> und <b>adUseServer<\/b>.<\/p>\n<h2>Recordset-Ereignisse<\/h2>\n<p>ADO bietet eine Reihe von Ereignissen, mit denen Du die Vorg&auml;nge innerhalb eines Recordsets &uuml;berwachen kannst. Diese Ereignisse sind vor allem dann hilfreich, wenn Du umfangreiche Datenmanipulationen durchf&uuml;hrst oder auf bestimmte &Auml;nderungen im Recordset reagieren willst &#8211; etwa bevor ein Datensatz ge&auml;ndert oder gel&ouml;scht wird.<\/p>\n<p>Um Recordset-Ereignisse in VBA nutzen zu k&ouml;nnen, musst Du das Recordset-Objekt mit <b>WithEvents<\/b> deklarieren. Dies ist nur in einem Klassenmodul m&ouml;glich. Es gibt die folgenden Ereignisse f&uuml;r ein <b>Recordset<\/b>-Objekt:<\/p>\n<ul>\n<li><b>WillChangeField<\/b>: Vor der &Auml;nderung eines Feldes<\/li>\n<li><b>FieldChangeComplete<\/b>: Nach der &Auml;nderung eines Feldes<\/li>\n<li><b>WillChangeRecord<\/b>: Vor der &Auml;nderung eines ganzen Datensatzes<\/li>\n<li><b>RecordChangeComplete<\/b>: Nach der &Auml;nderung eines Datensatzes<\/li>\n<li><b>WillChangeRecordset<\/b>: Vor grundlegenden Recordset-Aktionen (zum Beispiel zum &Ouml;ffnen oder Schlie&szlig;en)<\/li>\n<li><b>RecordsetChangeComplete<\/b>: Nach grundlegenden Recordset-Aktionen<\/li>\n<li><b>MoveComplete<\/b>: Nach dem Positionswechsel im Recordset<\/li>\n<li><b>EndOfRecordset<\/b>: Beim Erreichen des Endes<\/li>\n<li><b>FetchProgress<\/b>: W&auml;hrend des Abrufs von Daten (bei asynchronen Recordsets)<\/li>\n<li><b>FetchComplete<\/b>: Nach Abschluss des Abrufs<\/li>\n<\/ul>\n<h2>Beispiel: Alle Ereignisse beobachten<\/h2>\n<p>Das folgende Beispiel zeigt ein Klassenmodul mit dem Namen <b>clsRecordsetEvents<\/b>, in dem alle Ereignisse eines Recordsets ausgegeben werden. Das Hauptmodul instanziert dieses Objekt und l&ouml;st typische Aktionen aus.<\/p>\n<p>Als Erstes erstellen legen wir ein neues Klassenmodul namens <b>clsRecordsetEvents <\/b>an. In diesem f&uuml;gen wir die Variable f&uuml;r das Recordset hinzu. Au&szlig;erdem legen wir eine <b>Property Set<\/b>-Prozedur f&uuml;r diese Variable an, mit der die Klasse einen Verweis auf das zu beobachtende Recordset entgegennehmen kann:<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>WithEvents rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset\r\n<span style=\"color:blue;\">Public Property <span style=\"color:blue;\">Set<\/span> <\/span>rst(rstInput<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Set<\/span> rst = rstInput\r\n<span style=\"color:blue;\">End Property<\/span><\/pre>\n<p>Danach f&uuml;gen wir alle Ereignisse f&uuml;r diese Objektvariable hinzu. Damit das m&ouml;glich ist, haben wir die Variable mit dem Schl&uuml;sselwort <b>WithEvents <\/b>deklariert. Wir k&ouml;nnen nun im VBA-Editor im linken Kombinationsfeld den Eintrag <b>rst<\/b> ausw&auml;hlen und finden dann im rechten Kombinationsfeld alle verf&uuml;gbaren Ereignisse vor (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_02\/pic_471_002.png\" alt=\"Hinzuf&uuml;gen eines Ereignisses f&uuml;r die Variable rst\" width=\"649,627\" height=\"287,3187\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Hinzuf&uuml;gen eines Ereignisses f&uuml;r die Variable rst<\/span><\/b><\/p>\n<p>Diese legen wir nun nacheinander an. Dann f&uuml;llen wir sie mit jeweils einer <b>Debug.Print<\/b>-Anweisung, mit der wir den Namen des Ereignisses und die Parameter ausgeben, die das jeweilige Ereignis zur Verf&uuml;gung stellt. Insgesamt sieht dies wie in Listing 5 aus.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>rst_EndOfRecordset(fMoreData<span style=\"color:blue;\"> As Boolean<\/span>, adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, ByVal pRecordset<span style=\"color:blue;\"> As <\/span>_\r\n        ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"EndOfRecordset | fMoreData: \" & fMoreData & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_FetchComplete(ByVal pError<span style=\"color:blue;\"> As <\/span>ADODB.Error, adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, ByVal pRecordset _\r\n        <span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"FetchComplete | Fehler: \" & IIf(pError Is Nothing, \"keiner\", pError.Description) & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_FetchProgress(ByVal Progress<span style=\"color:blue;\"> As Long<\/span>, ByVal MaxProgress<span style=\"color:blue;\"> As Long<\/span>, adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, _\r\n         ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"FetchProgress | Fortschritt: \" & Progress & \" \/ \" & MaxProgress & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_FieldChangeComplete(ByVal cFields<span style=\"color:blue;\"> As Long<\/span>, ByVal Fields<span style=\"color:blue;\"> As Variant<\/span>, ByVal pError<span style=\"color:blue;\"> As <\/span>ADODB.Error, _\r\n         adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"FieldChangeComplete | Felder: \" & cFields & \" | Fehler: \" & GetError(pError) & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_MoveComplete(ByVal adReason<span style=\"color:blue;\"> As <\/span>ADODB.EventReasonEnum, ByVal pError<span style=\"color:blue;\"> As <\/span>ADODB.Error, adStatus<span style=\"color:blue;\"> As <\/span>_\r\n         ADODB.EventStatusEnum, ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"MoveComplete | Reason: \" & adReason & \" | Fehler: \" & GetError(pError) & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_RecordChangeComplete(ByVal adReason<span style=\"color:blue;\"> As <\/span>ADODB.EventReasonEnum, ByVal cRecords<span style=\"color:blue;\"> As Long<\/span>, ByVal pError _\r\n        <span style=\"color:blue;\"> As <\/span>ADODB.Error, adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"RecordChangeComplete | Reason: \" & adReason & \" | Records: \" & cRecords & \" | Fehler: \" _\r\n         & GetError(pError) & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_RecordsetChangeComplete(ByVal adReason<span style=\"color:blue;\"> As <\/span>ADODB.EventReasonEnum, ByVal pError<span style=\"color:blue;\"> As <\/span>ADODB.Error, _\r\n         adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"RecordsetChangeComplete | Reason: \" & adReason & \" | Fehler: \" & GetError(pError) & \" | Status: \" _\r\n         & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_WillChangeField(ByVal cFields<span style=\"color:blue;\"> As Long<\/span>, ByVal Fields<span style=\"color:blue;\"> As Variant<\/span>, adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, _\r\n         ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"WillChangeField | Felder: \" & cFields & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_WillChangeRecord(ByVal adReason<span style=\"color:blue;\"> As <\/span>ADODB.EventReasonEnum, ByVal cRecords<span style=\"color:blue;\"> As Long<\/span>, adStatus<span style=\"color:blue;\"> As <\/span>_\r\n         ADODB.EventStatusEnum, ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"WillChangeRecord | Reason: \" & adReason & \" | Records: \" & cRecords & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Erster Teil des Klassenmoduls zur Ausgabe der Ereignisse und ihrer Parameter<\/span><\/b><\/p>\n<p>Im zweiten Teil der Klasse aus Listing 6 sehen wir au&szlig;erdem noch die Hilfsfunktion <b>GetError<\/b>. Diese nimmt das Fehlerobjekt entgegen und pr&uuml;ft, ob es &uuml;berhaupt vorhanden ist. Wenn kein Fehler aufgetreten ist, wird das Objekt n&auml;mlich gar nicht erst mit dem Parameter <b>pError <\/b>mitgegeben. Deshalb pr&uuml;fen wir in der Funktion, ob <b>err<\/b> &uuml;berhaupt vorhanden ist (<b>Is Nothing<\/b>). Falls nicht, geben wir den Wert <b>Keiner <\/b>zur&uuml;ck. Dies dient nur der Ausgabe, im Praxiseinsatz w&uuml;rden wir hier einen <b>Boolean<\/b>-Wert nutzen. Falls das Objekt &uuml;bergeben wurde, lesen wir mit der Eigenschaft <b>Description <\/b>die Fehlermeldung aus und geben diese zur&uuml;ck.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>rst_WillChangeRecordset(ByVal adReason<span style=\"color:blue;\"> As <\/span>ADODB.EventReasonEnum, adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, _\r\n         ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"WillChangeRecordset | Reason: \" & adReason & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Sub <\/span>rst_WillMove(ByVal adReason<span style=\"color:blue;\"> As <\/span>ADODB.EventReasonEnum, adStatus<span style=\"color:blue;\"> As <\/span>ADODB.EventStatusEnum, _\r\n         ByVal pRecordset<span style=\"color:blue;\"> As <\/span>ADODB.Recordset)\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"WillMove | Reason: \" & adReason & \" | Status: \" & adStatus\r\n<span style=\"color:blue;\">End Sub<\/span>\r\n<span style=\"color:blue;\">Private Function <\/span>GetError(err<span style=\"color:blue;\"> As <\/span>Error)\r\n     <span style=\"color:blue;\">Dim <\/span>strError<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span>err Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         strError = \"Keiner\"\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         strError = err.Description\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     GetError = strError\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Zweiter Teil des Klassenmoduls zur Ausgabe der Ereignisse und ihrer Parameter<\/span><\/b><\/p>\n<p>Nun ben&ouml;tigen wir noch ein Beispiel f&uuml;r die Nutzung dieser Klasse, damit wir sehen, wann welches Ereignis ausgel&ouml;st wird. Dieses legen wir wie in Listing 7 an.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>StarteRecordsetMitEvents()\r\n     <span style=\"color:blue;\">Dim <\/span>cnn<span style=\"color:blue;\"> As <\/span>ADODB.Connection\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>ADODB.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>objRecordsetEvents<span style=\"color:blue;\"> As <\/span>clsRecordsetEvents\r\n     <span style=\"color:blue;\">Set<\/span> cnn = CurrentProject.Connection\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> objRecordsetEvents = <span style=\"color:blue;\">New<\/span> clsRecordsetEvents\r\n     <span style=\"color:blue;\">Set<\/span> rst = <span style=\"color:blue;\">New<\/span> ADODB.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> objRecordsetEvents.Recordset = rst\r\n     rst.Open \"SELECT * FROM tblKunden\", cnn, adOpenKeyset, adLockOptimistic\r\n     \r\n     '' Aktion: Datensatz &auml;ndern\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"MoveFirst\"\r\n     rst.MoveFirst\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Ort setzen\"\r\n     rst!Ort = \"Koblenz\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Update\"\r\n     rst.Update\r\n     \r\n     '' Aktion: Datensatz hinzuf&uuml;gen\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"AddNew\"\r\n     rst.Add<span style=\"color:blue;\">New<\/span>\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Vorname setzen\"\r\n     rst!Vorname = \"Lea\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Nachname setzen\"\r\n     rst!Nachname = \"Schwarz\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Ort setzen\"\r\n     rst!Ort = \"Heidelberg\"\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Update\"\r\n     rst.Update\r\n     '' Aktion: Datensatz l&ouml;schen\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"MoveLast\"\r\n     rst.MoveLast\r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Delete\"\r\n     rst.Delete\r\n     \r\n     <span style=\"color:blue;\">Debug.Print<\/span> \"Close\"\r\n     rst.Close\r\n     <span style=\"color:blue;\">Set<\/span> objRecordsetEvents = Nothing\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: Aufruf der Klasse zur Ausgabe der ausgel&ouml;sten Ereignisse<\/span><\/b><\/p>\n<p>Es deklariert wie in den vorherigen Beispielen das <b>Connection<\/b>&#8211; und das <b>Recordset<\/b>-Objekt und initialisiert zun&auml;chst die Connection. Au&szlig;erdem initialisieren wir auch ein neues Objekt auf Basis der Klasse <b>clsRecordsetEvents <\/b>und weisen es der Variablen <b>objRecordsetEvents <\/b>zu.<\/p>\n<p>Danach initialisieren wir unser <b>Recordset<\/b>-Objekt in <b>rst <\/b>und f&uuml;gen es im n&auml;chsten Schritt &uuml;ber die Eigenschaft <b>Recordset <\/b>der Klasse <b>clsRecordsetEvents <\/b>hinzu. Anschlie&szlig;end &ouml;ffnen wir das Recordset auf Basis der Tabelle <b>tblKunden<\/b>. Danach beginnt die Bearbeitung der Daten dieses Recordsets, den Du am besten im Einzelschrittmodus durchl&auml;ufst:<\/p>\n<ul>\n<li>Bereits der <b>Open<\/b>-Befehl l&ouml;st die beiden Ereignisse <b>WillMove <\/b>und <b>MoveComplete <\/b>aus.<\/li>\n<li>Das gleiche geschieht bei <b>MoveFirst<\/b>.<\/li>\n<li>Das Setzen des Feldes <b>Ort<\/b> und das Setzen der weiteren Felder l&ouml;st die Ereignisse <b>WillChangeRecord<\/b>, <b>WillChangeField<\/b>, <b>FieldChangeComplete <\/b>und <b>RecordChangeComplete <\/b>aus.<\/li>\n<li>Die <b>Update<\/b>-Methode l&ouml;st die Ereignisse <b>WillChangeRecord <\/b>und <b>RecordChangeComplete <\/b>aus.<\/li>\n<li>Die <b>AddNew<\/b>-Methode l&ouml;st die Ereignisse <b>WillMove<\/b>, <b>WillChangeRecord<\/b>, <b>RecordChangeComplete <\/b>und <b>MoveComplete <\/b>aus.<\/li>\n<li>Die <b>Delete<\/b>-Methode l&ouml;st das Ereignis <b>RecordChangeComplete <\/b>aus.<\/li>\n<li>Schlie&szlig;lich l&ouml;st die <b>Close<\/b>-Methode das Ereignis <b>RecordsetChangeComplete <\/b>aus.<\/li>\n<\/ul>\n<p>Die Ereignisse bieten einige praktische Anwendungszwecke, die wir hier nicht mehr im Detail abhandeln k&ouml;nnen.<\/p>\n<p>Dazu geh&ouml;ren zum Beispiel:<\/p>\n<ul>\n<li>Validierung vor &Auml;nderungen (<b>WillChangeField<\/b>, <b>WillChangeRecord<\/b>): Zum Beispiel zum Pr&uuml;fen von Feldern, bevor der Benutzer einen Wert speichert oder ob eine E-Mail-Adresse ein korrektes Format hat oder ob Pflichtfelder ausgef&uuml;llt sind. Hier kann abgebrochen werden, indem wir den Parameter <b>adStatus <\/b>auf <b>adStatusCancel <\/b>setzt.<\/li>\n<li>Automatisches Protokollieren (<b>FieldChangeComplete<\/b>, <b>RecordChangeComplete<\/b>): Zum Beispiel zum Festhalten von &Auml;nderungen in einem Audit-Trail  (Beispiel: Jeder &Auml;nderungsversuch wird in eine Log-Tabelle geschrieben &#8211; wer hat wann was ge&auml;ndert)<\/li>\n<li>Verhindern von L&ouml;schvorg&auml;ngen (<b>WillChangeRecord<\/b>): Wir k&ouml;nnen vor dem L&ouml;schen pr&uuml;fen, ob der Datensatz noch referenziert wird.Beispiel: Ein Kunde soll nicht gel&ouml;scht werden, wenn es noch offene Bestellungen gibt.<\/li>\n<li>Automatische Anpassungen\/Zusatzlogik (<b>RecordChangeComplete<\/b>): Wir k&ouml;nnen automatisch Felder nachf&uuml;llen oder abh&auml;ngige Werte anpassen. Beispiel: Nach &Auml;nderung des Landes automatisch den Standardwert f&uuml;r das Versandkostenfeld setzen.<\/li>\n<li>Navigation kontrollieren (<b>WillMove<\/b>, <b>MoveComplete<\/b>): Damit k&ouml;nnen wir die Navigation einschr&auml;nken oder verhindern. Beispiel: Warnung, wenn der Benutzer versucht, den Datensatz mit ungespeicherten &Auml;nderungen zu verlassen.<\/li>\n<li>Benutzerinteraktion (zum Beispiel f&uuml;r visuelles Feedback: Hier k&ouml;nnen wir Ereignisse nutzen, um Buttons zu aktivieren\/deaktivieren. So lie&szlig;e sich ein <b>Speichern<\/b>-Button erst aktivieren, wenn wirklich &Auml;nderungen vorliegen.<\/li>\n<li>Asynchrone Datenabrufe &uuml;berwachen (<b>FetchProgress<\/b>, <b>FetchComplete<\/b>): Geeignet zum Anzeigen des Fortschritts anzeigen bei sehr gro&szlig;en Abfragen. Beispiel: Fortschrittsbalken anzeigen, w&auml;hrend das Recordset viele Datens&auml;tze l&auml;dt (nur bei asynchronem Abruf relevant).<\/li>\n<\/ul>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Das Recordset-Objekt von ADODB bietet einige M&ouml;glichkeiten mehr als das der DAO-Bibliothek. Die Events sind das Sahneh&auml;ubchen. Wir werden in einem sp&auml;teren Artikel Beispiele vorstellen, wie sich diese praktisch nutzen lassen.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>ADODB_DatenzugriffPerRecordset.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/7264AED5-2228-4950-B48D-242EAABC12BF\/vbe_471.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&auml;ndige &Uuml;bersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl&auml;utern diese jeweils ausf&uuml;hrlich mit praktischen Beispielen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66022025,662025,44000008],"tags":[],"yst_prominent_words":[],"class_list":["post-55000471","post","type-post","status-publish","format-standard","hentry","category-66022025","category-662025","category-Datenzugriffstechnik"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.8 - aioseo.com -->\n\t<meta name=\"description\" content=\"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\u00e4ndige \u00dcbersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl\u00e4utern diese jeweils ausf\u00fchrlich mit praktischen Beispielen.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Andr\u00e9 Minhorst\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.8\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Visual Basic Entwickler - Das Magazin f\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler\" \/>\n\t\t<meta property=\"og:description\" content=\"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\u00e4ndige \u00dcbersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl\u00e4utern diese jeweils ausf\u00fchrlich mit praktischen Beispielen.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2025-07-02T14:48:09+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"-001-11-30T00:00:00+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler\" \/>\n\t\t<meta name=\"twitter:description\" content=\"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\u00e4ndige \u00dcbersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl\u00e4utern diese jeweils ausf\u00fchrlich mit praktischen Beispielen.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#blogposting\",\"name\":\"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler\",\"headline\":\"ADODB: Datenzugriff mit Recordsets\",\"author\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"..\\\/fileadmin\\\/_temp_\\\/2025_02\\\/pic_471_002.png\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#articleImage\"},\"datePublished\":\"2025-04-01T00:00:00+00:00\",\"dateModified\":\"-0001-11-30T00:00:00+00:00\",\"inLanguage\":\"de-DE\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#webpage\"},\"articleSection\":\"2\\\/2025, 2025, Datenzugriffstechnik\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/vbentwickler.de\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/#listItem\",\"name\":\"2025\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/#listItem\",\"position\":2,\"name\":\"2025\",\"item\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/2\\\/2025\\\/#listItem\",\"name\":\"2\\\/2025\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/2\\\/2025\\\/#listItem\",\"position\":3,\"name\":\"2\\\/2025\",\"item\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/2\\\/2025\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#listItem\",\"name\":\"ADODB: Datenzugriff mit Recordsets\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/#listItem\",\"name\":\"2025\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#listItem\",\"position\":4,\"name\":\"ADODB: Datenzugriff mit Recordsets\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/category\\\/2025\\\/2\\\/2025\\\/#listItem\",\"name\":\"2\\\/2025\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#organization\",\"name\":\"Datenbankentwickler\",\"description\":\"Das Magazin f\\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/cropped-header_vbe-1.png\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#organizationLogo\",\"width\":664,\"height\":225},\"image\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#organizationLogo\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/#author\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/\",\"name\":\"Andr\\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Andr\\u00e9 Minhorst\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#webpage\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/\",\"name\":\"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler\",\"description\":\"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\\u00e4ndige \\u00dcbersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl\\u00e4utern diese jeweils ausf\\u00fchrlich mit praktischen Beispielen.\",\"inLanguage\":\"de-DE\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/ADODB_Datenzugriff_mit_Recordsets\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/author\\\/andreminhorst-com\\\/#author\"},\"datePublished\":\"2025-04-01T00:00:00+00:00\",\"dateModified\":\"-0001-11-30T00:00:00+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#website\",\"url\":\"https:\\\/\\\/vbentwickler.de\\\/\",\"name\":\"Datenbankentwickler\",\"description\":\"Das Magazin f\\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.\",\"inLanguage\":\"de-DE\",\"publisher\":{\"@id\":\"https:\\\/\\\/vbentwickler.de\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler","description":"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\u00e4ndige \u00dcbersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl\u00e4utern diese jeweils ausf\u00fchrlich mit praktischen Beispielen.","canonical_url":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#blogposting","name":"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler","headline":"ADODB: Datenzugriff mit Recordsets","author":{"@id":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/#author"},"publisher":{"@id":"https:\/\/vbentwickler.de\/#organization"},"image":{"@type":"ImageObject","url":"..\/fileadmin\/_temp_\/2025_02\/pic_471_002.png","@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#articleImage"},"datePublished":"2025-04-01T00:00:00+00:00","dateModified":"-0001-11-30T00:00:00+00:00","inLanguage":"de-DE","mainEntityOfPage":{"@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#webpage"},"isPartOf":{"@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#webpage"},"articleSection":"2\/2025, 2025, Datenzugriffstechnik"},{"@type":"BreadcrumbList","@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/vbentwickler.de#listItem","position":1,"name":"Home","item":"https:\/\/vbentwickler.de","nextItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/#listItem","name":"2025"}},{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/#listItem","position":2,"name":"2025","item":"https:\/\/vbentwickler.de\/category\/2025\/","nextItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/2\/2025\/#listItem","name":"2\/2025"},"previousItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/2\/2025\/#listItem","position":3,"name":"2\/2025","item":"https:\/\/vbentwickler.de\/category\/2025\/2\/2025\/","nextItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#listItem","name":"ADODB: Datenzugriff mit Recordsets"},"previousItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/#listItem","name":"2025"}},{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#listItem","position":4,"name":"ADODB: Datenzugriff mit Recordsets","previousItem":{"@type":"ListItem","@id":"https:\/\/vbentwickler.de\/category\/2025\/2\/2025\/#listItem","name":"2\/2025"}}]},{"@type":"Organization","@id":"https:\/\/vbentwickler.de\/#organization","name":"Datenbankentwickler","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.","url":"https:\/\/vbentwickler.de\/","logo":{"@type":"ImageObject","url":"https:\/\/vbentwickler.de\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png","@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#organizationLogo","width":664,"height":225},"image":{"@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#organizationLogo"}},{"@type":"Person","@id":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/#author","url":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","width":96,"height":96,"caption":"Andr\u00e9 Minhorst"}},{"@type":"WebPage","@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#webpage","url":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/","name":"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler","description":"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\u00e4ndige \u00dcbersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl\u00e4utern diese jeweils ausf\u00fchrlich mit praktischen Beispielen.","inLanguage":"de-DE","isPartOf":{"@id":"https:\/\/vbentwickler.de\/#website"},"breadcrumb":{"@id":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/#breadcrumblist"},"author":{"@id":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/#author"},"creator":{"@id":"https:\/\/vbentwickler.de\/author\/andreminhorst-com\/#author"},"datePublished":"2025-04-01T00:00:00+00:00","dateModified":"-0001-11-30T00:00:00+00:00"},{"@type":"WebSite","@id":"https:\/\/vbentwickler.de\/#website","url":"https:\/\/vbentwickler.de\/","name":"Datenbankentwickler","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.","inLanguage":"de-DE","publisher":{"@id":"https:\/\/vbentwickler.de\/#organization"}}]},"og:locale":"de_DE","og:site_name":"Visual Basic Entwickler - Das Magazin f\u00fcr Datenbankentwickler auf Basis von Visual Studio und Co.","og:type":"article","og:title":"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler","og:description":"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\u00e4ndige \u00dcbersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl\u00e4utern diese jeweils ausf\u00fchrlich mit praktischen Beispielen.","og:url":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/","og:image":"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png","og:image:secure_url":"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png","article:published_time":"2025-07-02T14:48:09+00:00","article:modified_time":"-001-11-30T00:00:00+00:00","twitter:card":"summary_large_image","twitter:title":"ADODB: Datenzugriff mit Recordsets - Visual Basic Entwickler","twitter:description":"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\u00e4ndige \u00dcbersicht aller Eigenschaften und Methoden des Recordset-Objekts und erl\u00e4utern diese jeweils ausf\u00fchrlich mit praktischen Beispielen.","twitter:image":"https:\/\/datenbankentwickler.net\/wp-content\/uploads\/2022\/08\/cropped-header_vbe-1.png"},"aioseo_meta_data":{"post_id":"55000471","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"created":"2025-07-02 10:44:05","updated":"2026-05-16 09:18:43","ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/vbentwickler.de\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/vbentwickler.de\/category\/2025\/\" title=\"2025\">2025<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/vbentwickler.de\/category\/2025\/2\/2025\/\" title=\"2\/2025\">2\/2025<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tADODB: Datenzugriff mit Recordsets\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/vbentwickler.de"},{"label":"2025","link":"https:\/\/vbentwickler.de\/category\/2025\/"},{"label":"2\/2025","link":"https:\/\/vbentwickler.de\/category\/2025\/2\/2025\/"},{"label":"ADODB: Datenzugriff mit Recordsets","link":"https:\/\/vbentwickler.de\/ADODB_Datenzugriff_mit_Recordsets\/"}],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000471","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000471"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000471\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000471"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000471"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000471"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000471"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}