Lektionen/Datenzugriff

ADO-Grundlagen

Fortgeschritten11 Min. Lesezeit

DAO ist die native Zugriffsschicht von Access und für lokale Access-Tabellen erste Wahl. Doch sobald du gegen einen SQL Server, eine andere Datenbank oder allgemein über OLE DB/ODBC arbeitest, kommt ADO (ActiveX Data Objects) ins Spiel. Diese Lektion zeigt dir die Grundlagen, die dich von DAO aus schnell produktiv machen.

ADO vs. DAO — kurz eingeordnet

AspektDAOADO
HeimatAccess/Jet, nativeprovider-neutral (OLE DB)
Ideal fürlokale ACCDB-TabellenServer-DBs, andere Datenquellen
Cursor/Sperrenwenige, einfache Optionenfein einstellbar
Geschwindigkeit lokalmeist schnelleroft langsamer

Faustregel: Für die eigene Access-Datenbank bleibst du bei DAO. Für externe Server und heterogene Umgebungen greifst du zu ADO.

Verweis setzen

ADO ist eine eigene Bibliothek. In neueren Access-Versionen ist der Verweis oft schon gesetzt; falls nicht, aktivierst du ihn im VBA-Editor unter Extras → Verweise → Microsoft ActiveX Data Objects x.x Library (nimm die höchste 6.x-Version).

Weil Access DAO und ADO gleichzeitig kennt und beide ein Recordset-Objekt haben, deklariere immer explizit ADODB.Recordset bzw. DAO.Recordset. Sonst entscheidet die Reihenfolge der Verweise, welches gemeint ist — eine fiese Fehlerquelle.

Die Verbindung: CurrentProject.Connection

Für die aktuell geöffnete Access-Datenbank musst du keine Verbindungszeichenfolge zusammenbauen — CurrentProject.Connection liefert dir eine fertige ADO-Verbindung:

Dim cn As ADODB.Connection
Set cn = CurrentProject.Connection

Für eine externe Datenbank baust du die Verbindung selbst mit einem Connection- String auf, z. B. gegen SQL Server:

Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.ConnectionString = _
    "Provider=MSOLEDBSQL;Server=SQL01;Database=Vertrieb;" & _
    "Trusted_Connection=yes;"
cn.Open

Ein Recordset öffnen

Ein ADODB.Recordset öffnest du mit Open. Wichtig sind der CursorType und der LockType — sie entscheiden, ob du vorwärts/rückwärts blättern und schreiben kannst:

Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset

rs.Open "SELECT * FROM Kunden WHERE Ort = 'Berlin'", cn, _
        adOpenKeyset, adLockOptimistic

Do Until rs.EOF
    Debug.Print rs!KundenID, rs!Nachname
    rs.MoveNext
Loop

rs.Close
Set rs = Nothing

Die wichtigsten Konstanten:

CursorTypeBedeutung
adOpenForwardOnlynur vorwärts, schnell, Standard – nur zum Lesen
adOpenKeysetvor/zurück, sieht Änderungen anderer an Werten
adOpenStaticstatische Kopie, ideal zum reinen Auswerten
LockTypeBedeutung
adLockReadOnlynur lesen (Standard)
adLockOptimisticsperrt erst beim Update – gut zum Schreiben
adLockPessimisticsperrt sofort beim Edit

Zum reinen Zählen oder Blättern brauchst du RecordCount. Das liefert adOpenForwardOnly als -1. Willst du eine echte Anzahl, öffne mit adOpenKeyset oder adOpenStatic.

Felder lesen und schreiben

Der Feldzugriff funktioniert wie bei DAO — per Ausrufezeichen oder Fields():

Debug.Print rs!Nachname
Debug.Print rs.Fields("Nachname").Value
Debug.Print Nz(rs!Telefon, "(keine)")     ' Null abfangen

Zum Ändern eines Datensatzes weist du bei adLockOptimistic direkt zu und rufst Update auf — ein separates Edit wie in DAO gibt es bei ADO nicht:

rs!Ort = "Hamburg"
rs.Update

Einen neuen Datensatz legst du mit AddNew an und schließt mit Update ab:

rs.AddNew
rs!Vorname = "Anna"
rs!Nachname = "Berger"
rs!Ort = "Hamburg"
rs.Update

ADODB.Command mit Parametern

Verkettest du Werte direkt in SQL-Strings, riskierst du Quoting-Fehler und SQL-Injection. Ein ADODB.Command mit Parametern ist sauberer und sicherer:

Public Sub KundeAktualisieren(id As Long, neuerOrt As String)
    Dim cn As ADODB.Connection
    Dim cmd As ADODB.Command

    Set cn = CurrentProject.Connection
    Set cmd = New ADODB.Command

    cmd.ActiveConnection = cn
    cmd.CommandText = "UPDATE Kunden SET Ort = ? WHERE KundenID = ?"

    ' Parameter in der Reihenfolge der Fragezeichen anlegen:
    cmd.Parameters.Append cmd.CreateParameter("Ort", adVarWChar, adParamInput, 50, neuerOrt)
    cmd.Parameters.Append cmd.CreateParameter("ID", adInteger, adParamInput, , id)

    cmd.Execute            ' UPDATE ausführen, kein Recordset nötig
End Sub

Liefert das Command Daten zurück (ein SELECT), fängst du das Ergebnis als Recordset auf:

Dim rs As ADODB.Recordset
cmd.CommandText = "SELECT * FROM Kunden WHERE Ort = ?"
cmd.Parameters.Append cmd.CreateParameter("Ort", adVarWChar, adParamInput, 50, "Berlin")
Set rs = cmd.Execute

Die Reihenfolge der Append-Aufrufe muss der Reihenfolge der ?-Platzhalter entsprechen. Die Namen der Parameter sind bei positionsbasierten Providern nur Beschriftung — es zählt die Position.

Wann ADO statt DAO?

  • externe Server wie SQL Server, Oracle, MySQL über OLE DB/ODBC,
  • verschiedene Datenquellen unter einem gemeinsamen Objektmodell,
  • wenn du feine Cursor- und Sperrsteuerung oder getrennte („disconnected") Recordsets brauchst.

Für reine, lokale Access-Tabellen bleibt DAO meist die schnellere und einfachere Wahl — mische die Modelle nur bewusst.

Zusammengefasst

  • ADO ist provider-neutral und dein Werkzeug für Server- und Fremd-Datenbanken; für lokale ACCDB-Tabellen ist DAO oft schneller.
  • Verweis „Microsoft ActiveX Data Objects" setzen und immer explizit ADODB.Recordset deklarieren, um Verwechslung mit DAO zu vermeiden.
  • CurrentProject.Connection liefert die fertige Verbindung zur aktuellen DB; extern baust du den Connection-String selbst und rufst cn.Open.
  • rs.Open SQL, cn, CursorType, LockTypeadOpenKeyset/adLockOptimistic zum Blättern und Schreiben; Felder per rs!Feld, ändern mit AddNew/Update.
  • ADODB.Command mit ?-Parametern (Reihenfolge = Position) ist sicherer als zusammengebaute SQL-Strings.
Nächste Lektion
Transaktionen: BeginTrans & CommitTrans