Gepolsterte Parameter

15.01.2007
In Parameter-Abfragen können Sie auf die Inhalte von Formularen verweisen, anstatt jedes Mal aufs Neue die Werte im automatisch erzeugten Dialog einzugeben. Das ist natürlich viel praktischer, wird aber lästig, wenn das Formular einmal nicht geöffnet ist.

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]));

Bild 1: Standarddialog für Parameter-Abfragen.

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.

Bild 2: Fehlermeldung ohne geöffnetes Popup-Formular.

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