Manchmal brauchst du nur einen Wert aus einer Tabelle: den Preis eines Artikels, die Anzahl offener Bestellungen, die Summe aller Rechnungen eines Kunden. Dafür ein komplettes Recordset zu öffnen, ist umständlich. Die Domänenfunktionen erledigen das in einer einzigen Zeile — direkt im Code, in Formularen oder in Abfragen.
Der Aufbau: DLookup
DLookup holt einen einzelnen Feldwert aus einer „Domäne" (Tabelle oder Abfrage).
Die Signatur:
DLookup(Ausdruck, Domäne, [Kriterien])
- Ausdruck – das Feld (oder eine Berechnung), das du zurückbekommst, als String.
- Domäne – Name der Tabelle oder Abfrage, ebenfalls als String.
- Kriterien – optional, eine WHERE-Bedingung ohne das Wort
WHERE.
Dim preis As Variant
preis = DLookup("Preis", "Artikel", "ArtikelID = 42")
Debug.Print preis
Ohne Kriterium liefert DLookup den Wert des ersten gefundenen Datensatzes — bei
mehreren Treffern ist das nicht vorhersagbar, also grenze sinnvoll ein.
Kriterien richtig quoten
Der häufigste Fehler steckt in den Kriterien. Je nach Feldtyp musst du den Wert anders einfassen:
| Feldtyp | Schreibweise | Beispiel |
|---|---|---|
| Zahl | ohne Anführungszeichen | "ArtikelID = 42" |
| Text | in einfachen Hochkommas '…' | "Ort = 'Berlin'" |
| Datum | in Rauten, US-Format #mm/dd/yyyy# | "Datum = #07/01/2026#" |
Bei Textwerten aus Variablen verkettest du den Inhalt zwischen zwei Hochkommas:
Dim ort As String
ort = "Berlin"
preis = DLookup("Umsatz", "Kunden", "Ort = '" & ort & "'")
Bei Datumswerten musst du das US-Format mm/dd/yyyy erzwingen — sonst
interpretiert Access den 07.01. je nach Systemeinstellung falsch. Format hilft:
Dim datum As Date
datum = Date ' heute
Dim n As Long
n = DCount("*", "Bestellungen", _
"Bestelldatum = #" & Format(datum, "mm/dd/yyyy") & "#")
Enthält ein Textwert selbst ein Hochkomma (z. B.
O'Brien), bricht die'…'-Variante. Nutze dann doppelte Anführungszeichen perChr(34):"Name = " & Chr(34) & name & Chr(34).
Null behandeln mit Nz
Findet DLookup keinen Datensatz, gibt es Null zurück — nicht 0 und nicht
einen leeren String. Rechnest oder verkettest du direkt damit, kracht es oder das
Ergebnis wird selbst Null. Fange das mit Nz ab, das Null in einen Ersatzwert
wandelt:
Dim preis As Currency
preis = Nz(DLookup("Preis", "Artikel", "ArtikelID = 999"), 0)
' Kein Treffer -> preis = 0 statt Fehler
Willst du unterscheiden, ob wirklich kein Datensatz existiert, prüfe explizit:
Dim ergebnis As Variant
ergebnis = DLookup("Preis", "Artikel", "ArtikelID = 999")
If IsNull(ergebnis) Then
MsgBox "Artikel nicht gefunden."
Else
MsgBox "Preis: " & ergebnis
End If
Die ganze Familie: DCount, DSum, DMin, DMax, DAvg
Alle Domänenfunktionen haben denselben Aufbau Funktion(Ausdruck, Domäne, Kriterien).
Sie unterscheiden sich nur darin, was sie berechnen:
| Funktion | Ergebnis |
|---|---|
DCount | Anzahl der Datensätze |
DSum | Summe eines Feldes |
DMin | kleinster Wert |
DMax | größter Wert |
DAvg | Durchschnitt |
' Wie viele offene Bestellungen gibt es?
Debug.Print DCount("*", "Bestellungen", "Status = 'offen'")
' Gesamtumsatz eines Kunden
Debug.Print Nz(DSum("Betrag", "Rechnungen", "KundenID = 7"), 0)
' Höchste vergebene Belegnummer (für die nächste ID)
Dim naechste As Long
naechste = Nz(DMax("BelegNr", "Belege"), 0) + 1
' Durchschnittspreis der Kategorie
Debug.Print DAvg("Preis", "Artikel", "Kategorie = 'Werkzeug'")
Bei
DCountist"*"als Ausdruck am schnellsten — es zählt einfach Datensätze, ohne ein bestimmtes Feld auszuwerten. Ein Feldname würdeNull-Werte auslassen.
Bequemlichkeit vs. Geschwindigkeit
Domänenfunktionen sind praktisch, aber nicht kostenlos. Jeder Aufruf baut intern eine kleine Abfrage auf, öffnet sie und wertet sie aus. Für einen einzelnen Wert ist das völlig in Ordnung. In einer Schleife wird es teuer:
' LANGSAM: DLookup pro Durchlauf – öffnet jedes Mal neu
Dim i As Long
For i = 1 To 10000
Debug.Print DLookup("Name", "Artikel", "ArtikelID = " & i)
Next i
Läuft eine Domänenfunktion über eine Tabelle ohne Index auf dem Kriterienfeld, muss Access im schlimmsten Fall die ganze Tabelle durchsuchen — und das bei jedem Schleifendurchlauf. Öffne dann lieber einmal ein Recordset:
' SCHNELL: ein Recordset, einmal durchlaufen
Dim db As DAO.Database, rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT ArtikelID, Name FROM Artikel", dbOpenSnapshot)
Do Until rs.EOF
Debug.Print rs!ArtikelID, rs!Name
rs.MoveNext
Loop
rs.Close
Wann was?
- Domänenfunktion – für Einzelwerte, Steuerelement-Herkunft in Formularen, Berechnungen in Abfragen, gelegentliche Prüfungen. Kurz und lesbar.
- Recordset / SQL – sobald du viele Werte brauchst, in Schleifen arbeitest oder große Tabellen ohne passenden Index abfragst. Deutlich schneller.
Ein einzelner DCount-Aufruf ist übrigens fast immer schneller, als ein Recordset
nur zum Zählen zu öffnen und MoveLast aufzurufen. Der Nachteil zeigt sich erst bei
der Wiederholung.
Zusammengefasst
DLookup(Ausdruck, Domäne, Kriterien)holt einen Einzelwert;DCount,DSum,DMin,DMax,DAvgfolgen demselben Muster.- Kriterien richtig quoten: Zahlen ohne, Text mit
'…', Datum mit#mm/dd/yyyy#im US-Format (perFormat(datum, "mm/dd/yyyy")). - Kein Treffer bedeutet
Null— mitNz(..., Ersatzwert)abfangen oder mitIsNullexplizit prüfen. DCount("*", ...)ist zum Zählen am schnellsten; ein Feldname überspringtNull.- In Schleifen oder auf großen, nicht indizierten Tabellen sind Domänenfunktionen langsam — dann lieber ein Recordset einmal öffnen und durchlaufen.