Eine normale Parameter-Abfrage, basierend auf der Nordwind-Datenbank, sähe aus wie in Listing 1 und würde bei jedem Aufruf den Dialog aus Bild 1 zeigen.
SELECT Bestellungen.*
FROM Bestellungen
WHERE (((Bestellungen.[Kunden-Code])=[Bitte Kunden-Code eingeben]));
Das lässt sich noch bedeutend benutzerfreundlicher gestalten, wenn auch Jokerzeichen wie der Stern * und das Fragezeichen ? erlaubt sind. Ändern Sie dazu das SQL-Statement wie in Listing 2, indem Sie das Gleichheitszeichen durch das Schlüsselwort LIKE ersetzen. Damit ist auch die Eingabe von „A*“ oder sogar nur „*“ als Kunden-Code möglich. Trotz allem bleibt jedoch das Ärgernis, dass keine vorhandenen Kunden-Codes, etwa in einer Combobox, angeboten werden.
SELECT Bestellungen.*
FROM Bestellungen
WHERE (((Bestellungen.[Kunden-Code]) Like [Bitte Kunden-Code eingeben]));
Verweis auf Formular
Dazu benötigen Sie zuerst ein Formular, welches hier frmPopUp heißt. Auf diesem sollen die gruppierten Kunden-Codes in einer Combobox angezeigt werden, wie Listing 3 als Datensatzherkunft.
SELECT [Kunden-Code]
FROM Bestellungen
GROUP BY [Kunden-Code];
Im Formular selbst wird am besten die PopUp-Eigenschaft auf Ja gestellt, damit es immer im Vordergrund bleibt, auch wenn es nicht den Fokus hat. Das SQL-Statement für die Abfrage verändert sich dann wie in Listing 4.
SELECT Bestellungen.*
FROM Bestellungen
WHERE (((Bestellungen.[Kunden-Code])=
[Formulare]![frmPopUp]![cmbKundenCode]));
Nun lässt sich in der Combobox sehr bequem ein Eintrag auswählen, dessen Daten dann beim nächsten Aufruf der Abfrage als Filter benutzt werden.
Abfrage-Start ohne Formular
Das funktioniert alles so lange einwandfrei, wie das benötigte Formular offen ist. Wenn Sie die Abfrage aber starten, ohne dass frmPopUp geöffnet ist, erhalten Sie die Fehlermeldung aus Bild 2. Access kann auf die Inhalte eines geschlossenen Formulars nicht zugreifen. Es könnte im Übrigen ja auch noch ganz ohne Daten sein.
Daher sollten Sie diesen Datenzugriff kapseln, damit Sie das notfalls abfangen können. Anstatt also in SQL direkt auf ein Formularfeld zu verweisen, geschieht dies innerhalb einer Funktion. Listing 5 zeigt den hierzu notwendigen VBACode.
Function HoleKundenCode() As String
HoleKundenCode = Forms("frmPopUp").cmbKundenCode.Value
End Function
Das SQL-Statement verändert sich wie in Listing 6, damit das Funktionsergebnis als Filter benutzt wird.
SELECT Bestellungen.*
FROM Bestellungen
WHERE (((Bestellungen.[Kunden-Code])=HoleKundenCode()));
Fehlerbehandlung innerhalb von VBA
Natürlich verändert sich mit diesem minimalen Code bestenfalls die erscheinende Fehlermeldung, wenn das Formular nicht geöffnet ist. Aber Sie haben nun alle Möglichkeiten der Fehlerbehandlung innerhalb von VBA, wie in Listing 7 gezeigt.
Function HoleKundenCode() As String
On Error Resume Next
HoleKundenCode = Forms("frmPopUp").cmbKundenCode.Value
If HoleKundenCode = "" Then
HoleKundenCode = DLookup("[Kunden-Code]", "Bestellungen")
End If
If Err.Number <> 0 Then
MsgBox "Fehler Nr. " & Err.Number & ": " & _
Err.Description & vbCrLf & vbCrLf & _
"Zufälliger erster Kunden-Code '" & HoleKundenCode & _
"' wird eingesetzt!", vbCritical
End If
End Function
Sie bemerken also rechtzeitig den Fehler, der auftritt, wenn das Formular nicht geöffnet ist, oder in der Combobox keine Auswahl getroffen wurde. Dann können Sie wahlweise den ersten Kunden-Code mit DLookUp() nachladen, damit überhaupt ein Ergebnis angezeigt werden kann.
Oder Sie stoppen die gesamte Ausführung der Abfrage mit dem End-Befehl (Listing 8). Leider ist es nicht möglich, in dieser Funktion das offensichtlich nur fehlende Formular noch schnell zu öffnen. Access scheint das beim gleichzeitig stattfindenden Öffnen einer Abfrage nicht zuzulassen.
Function HoleKundenCode() As String
' ...wie bisher
If Err.Number <> 0 Then
MsgBox "Fehler Nr. " & Err.Number & ": " & _
Err.Description & vbCrLf & vbCrLf & _
"Abfrage wird nicht ausgeführt!", vbCritical
End
End If
End Function