Elegantere Parameter-Abfragen in Access

Parameter-Abfragen mit VBA benutzerfreundlicher gestalten

Von: Lorenz Hölscher
Stand: 3. Juli 2012
4.375
(8)
Beitrag bewerten
Kommentar schreiben

Über den Autor:

bild80517

Lorenz Hölscher ist freiberuflicher Dozent, Berater und Programmierer mit Schwerpunkt Anwendungs-Programmierung. Vorrangig widmet er sich Access, Word und Excel sowie begleitenden grafischen Arbeiten ...

Newsletter abonnieren

Parameter-Abfragen dienen dazu, in Access-Datenbanken wechselnde Filter zu ermöglichen. Das ist technisch in Ordnung, aber oft nicht besonders komfortabel für die Benutzer. Daher können Sie auf die Inhalte von Formularen verweisen, anstatt jedes Mal erneut die Werte im automatisch erzeugten Standarddialog eingeben zu müssen. Lorenz Hölscher zeigt, wie Sie das mit ein paar Zeilen VBA-Code sehr elegant lösen.

Anhand einer einfachen Datenbank möchte ich Ihnen zeigen, wie Sie aus einer langweiligen Parameter-Abfrage mit Nerv-Potential einen sehr benutzerfreundlichen Zugriff auf Daten machen können.

Was sind Parameter-Abfragen?

Wenn Sie sich mit Parameter-Abfragen noch nicht auskennen, hilft Ihnen der Beitrag "Komfortables Abfragen: Parameterabfragen" weiter, der die Technik ausführlich erläutert.

Als Ausgangsdaten dienen zwei Tabellen aus der Nordwind-Datenbank (eine Beispiel-Datenbank von Microsoft aus früheren Access-Versionen) mit Bestellungen und den zugehörigen Kunden, die über eine Kundenkennung verbunden sind. Die Tabelle tblKunden sieht so aus:

Bild vergrößernBild vergrößernTabelle tblKunden

Dazu kommt eine Tabelle tblBestellungen mit den Bestellungen, wobei hier nur deren Stammdaten enthalten sind, da die Bestelldetails in einer weiteren 1:n-verknüpften Tabelle gespeichert werden müssen. Für die Daten der Bestellungen-Tabelle ist nur wichtig, dass die Kundenkennungen zu tblKunden passen, wie der Ausschnitt hier zeigt:

Bild vergrößernBild vergrößernTabelle Bestellungen

Mit einer "normalen" Parameter-Abfrage könnten Sie nun beispielsweise alle Bestellungen für einen bestimmten Kunden herausfinden. Dazu geben Sie die gewünschten Felder (oder wie hier das "*" für alle Felder) im Abfrage-Entwurf an und das Feld bstKndKennungRef mit dem Kriterium [Welcher Kunde?]:

Parameterabfrage für wechselnde Kunden

Wahlweise können Sie das auch als SQL-Statement eingeben:

SELECT tblBestellungen.*
FROM tblBestellungen
WHERE (((tblBestellungen.bstKndKennungRef)=[Welcher Kunde?]));

oder kürzer ohne die mehrfache explizite Nennung des Tabellennamens:

SELECT *
FROM tblBestellungen
WHERE bstKndKennungRef=[Welcher Kunde?];

Wichtig ist dabei, dass im Kriterium die eckigen Klammern vorhanden sind und deren Inhalt den Regeln für Feldnamen folgt (beispielsweise keine Punkte oder Ausrufezeichen). Sobald Sie diese Abfrage starten, wird sie automatisch den folgenden Dialog anzeigen und die (hier schon erfolgte) Eingabe einer Kundenkennung erwarten:

Eingabedialog zur Parameterabfrage

Der Feldname (also der Text innerhalb der eckigen Klammern) erscheint hier im Dialog, daher wähle ich die Frageform und einen lesbaren Text mit Leerzeichen. Nach Bestätigung des Dialogs erscheint das Ergebnis der Abfrage mit diesem Filter:

Bild vergrößernBild vergrößernErgebnis der Parameterabfrage für 'ALFKI'

So weit ist das die übliche technische Prozedur für Parameter-Abfragen in Access. Das ließe sich noch bedeutend benutzerfreundlicher gestalten, wenn auch Jokerzeichen wie "*" und "?" erlaubt wären. Ergänzen Sie dazu den Entwurf um das Schlüsselwort Wie:

Verbesserter Entwurf der Parameterabfrage

Sie können das auch in der SQL-Ansicht machen, indem Sie das Gleichheitszeichen durch das Schlüsselwort LIKE ersetzen:

SELECT *
FROM tblBestellungen
WHERE bstKndKennungRef LIKE [Welcher Kunde?];

Damit ist auch die Eingabe von "A*" oder sogar nur "*" als Kundenkennung möglich:

Jetzt sind auch Jokerzeichen als Parameter möglich.

Trotz allem bleibt es jedoch lästig, dass keine vorhandenen Kundenkennungen in einer Ausklappliste angeboten werden. Das möchte ich nun verbessern.

Formular statt Parameter-Dialog

Mit Erstellen/Formulare/Formular-Entwurf bereiten Sie dazu ein eher kleines Formular vor, welches keine Datensatzquelle benötigt. Speichern Sie es als frmKundenAuswahl:

Ein kleines und noch leeres Formular im Entwurf

Erstellen Sie außerdem eine Abfrage qryKundenSortiert mit dem folgenden SQL-Statement:

SELECT kndKennung, [kndName] & " (" & [kndOrt] & ")" AS wer
FROM tblKunden
ORDER BY kndKennung;

Damit können Sie anschließend im Formular die auszuwählenden Kunden sortiert und übersichtlich anzeigen:

Die Kunden sind so sortiert.

Auf dem Formular-Entwurf fügen Sie nun ein Kombinationsfeld ein, beschriften es mit "Kunde:" und benennen es als cmbKunden. Als Datensatzherkunft erhält es die soeben vorbereitete Abfrage qryKundenSortiert:

Bild vergrößernBild vergrößernDas Kombinationsfeld cmbKunden mit seinen Eigenschaften

Standardwert für Kombinationsfeld

Damit das Kombinationsfeld auch direkt nach dem Öffnen des Formulars einen Wert ausgewählt hat, gibt es zwei Möglichkeiten: Entweder nennen Sie in der Eigenschaft Standardwert einen konkreten Inhalt (hier beispielsweise "ALFKI") oder Sie lassen per VBA den jeweils ersten Wert auswählen.

Die VBA-Variante ist sicherer, weil sie auch dann funktioniert, wenn ALFKI mal nicht mehr als Inhalt enthalten sein sollte. Dazu geben Sie im Formular-Modul diesen Code ein:

Private Sub Form_Current()
    Me.cmbKunden.Value = Me.cmbKunden.Column(0, 0)
End Sub

Das Kombinationsfeld wählt dadurch beim Anzeigen des Formulars den Eintrag der ersten Spalte in der ersten Zeile aus, die jeweils ab 0 gezählt werden.

Für die Formular-Eigenschaften selber könnten Sie noch diese Werte einstellen, damit es besser aussieht:

  • Datensatzmarkierer: Nein

  • Navigationsschaltflächen: Nein

  • Bildlaufleisten: Nein

  • MinMaxSchaltflächen: Min vorhanden

  • PopUp: Ja

Diese Einstellungen sind sinnvoll, weil dieses Formular selber ja keine Datensätze anzeigt oder bearbeitet, sondern lediglich Platz für ein Kombinationsfeld (mit darin enthaltenen Daten) bietet. Das fertige Formular sieht nun so aus:

Das fertige Formular mit Kombinationsfeld

Die PopUp-Eigenschaft des Formulars steht auf Ja, damit es immer im Vordergrund bleibt, selbst wenn es demnächst nicht den Fokus hat.

Schöneres Kombinationsfeld

Sie können die ausklappende Liste etwas schöner und lesefreundlicher gestalten, indem Sie die zweite Spalte mit den echten Namen anzeigen statt der Kürzel. Dazu wechseln Sie in die Entwurfsansicht des Formulars, markieren das Kombinationsfeld und ändern dessen Eigenschaften:

  • Spaltenanzahl: 2

  • Spaltenbreiten: 0cm;7cm

  • Listenbreite: 7cm

Die interne Auswahl geschieht weiterhin über die erste (nun aber unsichtbare) Spalte, obwohl das Kombinationsfeld jetzt die zweite Spalte anzeigt:Die erste Spalte ist versteckt.

Parameter aus Formular ermitteln

Jetzt geht es darum, dass die Parameter-Abfrage nicht mehr den Dialog anzeigt, sondern stattdessen die Auswahl im Formular benutzt. Dazu öffnen Sie die Entwurfs-Ansicht der Abfrage und klicken dort in das Kriterium mit den eckigen Klammern.

Mit dem Befehl Abfragetools Entwurf/Abfragesetup/Generator (das Symbol zeigt einen kleinen Zauberstab an) oder dem Tastenkürzel Strg+F2 können Sie anschließend im Ausdrucks-Generator direkt das Kombinationsfeld cmbKunden auswählen und per Doppelklick in das Textfeld oben übernehmen lassen:

Bild vergrößernBild vergrößernDa frmKundenAuswahl geladen ist, finden Sie es schnell im Ausdrucks-Generator

Die nach dem Doppelklick noch übrigbleibenden Reste des vorherigen Codes löschen Sie manuell und bestätigen den Ausdrucks-Generator mit OK. Damit steht statt der eckigen Klammern mit der Frage nun ein Verweis auf das Formular im Abfrage-Entwurf:

Bild vergrößernBild vergrößernDie geänderte Parameterabfrage

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:

Bild vergrößernBild vergrößernDie Abfrage kann mit 'Alle aktualisieren' aktualisiert werden.

Nach einer geänderten Kunden-Auswahl im Formular frmKundenAuswahl müssen Sie entweder die Abfrage neu öffnen oder deren Daten mit dem Befehl "Alle aktualisieren" aktualisieren.

Abfrage-Start ohne Formular?

Das funktioniert alles so lange einwandfrei, wie das Formular frmKundenAuswahl offen ist. Wenn Sie die Abfrage aber starten, ohne dass es geöffnet ist, erhalten Sie diese Fehlermeldung:

Fehlermeldung ohne geöffnetes PopUp-Formular

Access kann auf die Inhalte eines geschlossenen Formulars nicht zugreifen. Daher sollten Sie diesen Datenzugriff mit VBA kapseln, damit Sie das notfalls abfangen können. Anstatt also im SQL-Statement direkt auf ein Formular-Feld zu verweisen, geschieht dies innerhalb einer Funktion.

Dazu brauchen Sie erst einmal eine VBA-Funktion, die hier HoleKundenKennung heißt und auf das Formular zugreift:

Function HoleKundenKennung() As String
    HoleKundenKennung = Forms("frmKundenAuswahl").cmbKunden.Value
End Function

Diese Funktion können Sie in einem beliebigen Modul dieser Datenbank erstellen:

Bild vergrößernBild vergrößernEigene VBA-Funktion

Das SQL-Statement in der Abfrage verändert sich entsprechend, damit das Funktionsergebnis als Filter benutzt wird. Sie können auch hier mit Strg+F2 den Ausdrucks-Generator aufrufen oder den Namen der Funktion mit folgendem Klammerpaar direkt schreiben:

Bild vergrößernBild vergrößernAbfrage-Entwurf mit eigener VBA-Funktion und Ausdrucks-Generator

Natürlich verändert sich mit diesem kurzen VBA-Code im Moment bestenfalls die erscheinende Fehlermeldung, wenn das Formular mal nicht geöffnet ist. Aber Sie haben nun alle Möglichkeiten der Fehlerbehandlung innerhalb von VBA:

Function HoleKundenKennung() As String
    On Error Resume Next
    HoleKundenKennung = Forms("frmKundenAuswahl").cmbKunden.Value
    
    If Err.Number <> 0 Then
        'HoleKundenKennung = "ALFKI"
        MsgBox "Fehler Nr. " & Err.Number & ":" & vbCrLf & Err.Description, vbCritical
    End If
End Function

Wie im obigen VBA-Code als Kommentar (mit Hochkomma davor) schon zu sehen ist, können Sie alternativ auch einfach einen festen Wert zurückgeben oder mit "*" alle Datensätze anzeigen. Dann weiß der Benutzer allerdings noch nicht, dass ein Fehler aufgetreten ist.

Fehler in VBA behandeln

Der Umgang mit Laufzeitfehlern in Access-VBA ist nicht Thema dieses Beitrags, weil das bereits in "Syntax-Fehler, logische Fehler, Laufzeitfehler, Datentyp-Probleme" behandelt wird.

Wenn das Formular nicht geöffnet war, tritt direkt ein Fehler auf. In dem Fall erscheint eine Fehlermeldung mit erläuterndem Text:

Neue Fehlermeldung ohne geöffnetes PopUp-Formular

Sie können natürlich auch beides kombinieren, die vorherige Chance auf Eingabe der Kundenkennung und die jetzige bessere Fehlermeldung:

Function HoleKundenKennung() As String
    On Error Resume Next
    HoleKundenKennung = Forms("frmKundenAuswahl").cmbKunden.Value
    
    If Err.Number <> 0 Then
        HoleKundenKennung = InputBox("Kundenkennung?" & vbCrLf & Err.Description, , "ALFKI")
        If HoleKundenKennung = "" Then
            End
        End If
    End If
End Function

Die InputBox()-Funktion erlaubt die einfache Eingabe eines Textes, der hier direkt mit dem Wert ALFKI vorbesetzt wurde. Da diese Funktion beim Abbruch zudem einen Leerstring zurückgibt, lässt sich damit direkt der ganze Aufruf der Abfrage abbrechen. Die Meldung sieht nun so aus:

Verbesserte Fehlermeldung mit Eingabemöglichkeit

Leider ist es nicht möglich, in dieser Funktion das offensichtlich nur fehlende Formular noch schnell zu öffnen. Access lässt das beim gleichzeitig stattfindenden Öffnen einer Abfrage nicht zu.

Fazit

Mit wenigen Zeilen VBA-Code können Sie aus der eher spröden Technik der Parameter-Abfragen eine benutzerfreundliche Bedienung zaubern. Dabei lassen sich auch eventuell auftretende Fehler elegant umgehen und verständlich beheben.

Beitrag bewerten

Ihre Wertung:

 

Vielen Dank, das sit sehr gut

Vielen Dank, das sit sehr gut und genau das was ich wissen möchte in kompakter Form dargestellt! Bravo!

DANKE!!!

... genau das, was ich gebraucht habe.

Mitglied werden, Vorteile nutzen!

  • Sie können alles lesen und herunterladen: Beiträge, PDF-Dateien und Zusatzdateien (Checklisten, Vorlagen, Musterbriefe, Excel-Rechner u.v.a.m.)
  • Unsere Autoren beantworten Ihre Fragen
  • Sie bekommen erhebliche Rabatte auf unsere von Experten geleitete Online-Workshops