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
| Aspekt | DAO | ADO |
|---|---|---|
| Heimat | Access/Jet, native | provider-neutral (OLE DB) |
| Ideal für | lokale ACCDB-Tabellen | Server-DBs, andere Datenquellen |
| Cursor/Sperren | wenige, einfache Optionen | fein einstellbar |
| Geschwindigkeit lokal | meist schneller | oft 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 explizitADODB.Recordsetbzw.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:
| CursorType | Bedeutung |
|---|---|
adOpenForwardOnly | nur vorwärts, schnell, Standard – nur zum Lesen |
adOpenKeyset | vor/zurück, sieht Änderungen anderer an Werten |
adOpenStatic | statische Kopie, ideal zum reinen Auswerten |
| LockType | Bedeutung |
|---|---|
adLockReadOnly | nur lesen (Standard) |
adLockOptimistic | sperrt erst beim Update – gut zum Schreiben |
adLockPessimistic | sperrt sofort beim Edit |
Zum reinen Zählen oder Blättern brauchst du
RecordCount. Das liefertadOpenForwardOnlyals-1. Willst du eine echte Anzahl, öffne mitadOpenKeysetoderadOpenStatic.
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.Recordsetdeklarieren, um Verwechslung mit DAO zu vermeiden. CurrentProject.Connectionliefert die fertige Verbindung zur aktuellen DB; extern baust du den Connection-String selbst und rufstcn.Open.rs.Open SQL, cn, CursorType, LockType—adOpenKeyset/adLockOptimisticzum Blättern und Schreiben; Felder perrs!Feld, ändern mitAddNew/Update.ADODB.Commandmit?-Parametern (Reihenfolge = Position) ist sicherer als zusammengebaute SQL-Strings.