Dieser Artikel ist Teil des Magazins 'Access im Unternehmen', Ausgabe 1.
Kombinationsfeld per Taste steuern
Kombinationsfelder enthalten viele Einträge, die Sie durch das Aufklappen des Kombinationsfeldes anzeigen und per Mausklick auswählen können. Wenn Sie mit der Tastatur arbeiten, müssen Sie das Kombinationsfeld erst mit der Taste F4 öffnen und dann mit der Nach oben- oder der Nach unten-Taste den gewünschten Eintrag auswählen, den Sie dann durch Verlassen des Steuerelements bestätigen. Das geht auch einfacher, nämlich mit den beiden Tasten »Nach oben« und »Nach unten«. Es bedarf allerdings einiger Zeilen VBA-Code, die wir in diesem Beitrag vorstellen.
Vorbereitung
Um ein Formular mit einem Beispielkombinationsfeld bereitzustellen, legen Sie zunächst ein neues Formular an. Dann legen wir die Tabelle tblArtikel aus der Beispieldatenbank Suedsturm als Datensatzquelle des Formulars fest. Aktivieren Sie dann die Feldliste und ziehen Sie alle Felder aus der Feldliste in den Detailbereich der Entwurfsansicht des Formulars. Die beiden Felder KategorieID und LieferantID werden dann direkt als Kombinationsfelder angelegt.
Für die beiden Kombinationsfelder legen wir die Namen cboLieferantID und cboKategorieID fest. Speichern Sie das Formular dann unter dem Namen frmKombinatoinsfeldMitTaste (siehe Bild 1).
Bild 1: Beispielformular mit zwei KombinationsfeldernWenn Sie in die Formularansicht wechseln, können Sie bei Tastaturbetrieb den Fokus mit der Tabulator-Taste auf eines der Kombinationsfelder verschieben. Dann öffnen Sie dieses mit der Taste F4 und können dann mit den Tasten Nach oben und Nach unten einen der Einträge auswählen (siehe Bild 2).
Bild 2: Beispielformular mit zwei Kombinationsfeldern in der Formularansicht
Dies wollen wir nun vereinfachen, indem wir das Blättern durch die Einträge ohne Öffnen des Kombinationsfeldes ermöglichen. Wie das gelingt, erfahren Sie in den folgenden Abschnitten.
Kombinationsfeldeintrag per Taste auswählen
Wir wollen das Verhalten nachbilden, das wir sehen, wenn wir uns bei aufgeklapptem Kombinationsfeld mit der Nach oben- und der Nach unten-Taste durch die Einträge bewegen. Hier stellen wir fest, dass jeweils der vorherige oder nächste Eintrag ausgewählt wird, sobald der Benutzer eine der beiden Tasten Nach oben oder Nach unten herunterdrückt.
Damit steht schon einmal das Ereignis fest, dass wir programmieren müssen, nämlich Bei Taste ab. Für dieses Ereignis legen wir nun eine Ereignisprozedur an. Diese sieht ohne eigene Anweisungen nun wie folgt aus:
Private Sub cboLieferantID_KeyDown(KeyCode As Integer, Shift As Integer)
End Sub
Mit dem Parameter KeyCode erhalten wie eine Zahl, welche die soeben gedrückte Taste repräsentiert, Shift liefert einen Zahlencode für die Tasten Umschalt, Strg und Alt.
Wir wollen zunächst herausfinden, welche Werte der Parameter KeyCode liefert, wenn wir im Kombinationsfeld eine der Tasten Nach oben oder Nach unten betätigen. Dazu fügen wir die folgende Debug.Print-Anweisung zur Ausgabe von KeyCode hinzu:
Private Sub cboLieferantID_KeyDown(KeyCode As Integer, Shift As Integer)
Debug.Print KeyCode
End Sub
Betätigen wir nun in der Formularansicht die Nach oben-Taste, wird der Wert 38 im Direktbereich ausgegeben, für die Nach unten-Taste der Wert 40.
Wir müssen also auf die beiden Werte 38 und 40 reagieren, was wir in einer Select Case-Bedingung erledigen.
Die Prozedur sieht danach wie in Listing 1 aus. Sie enthält genau genommen sogar zwei Select Case-Bedingungen. Die erste prüft, ob der Benutzer überhaupt eine der beiden Tasten Nach oben oder Nach unten betätigt hat. In diesem Fall ermitteln wir zunächst den aktuellen Indexwert des Kombinationsfeldes und speichern diesen in der Variablen lngIndex.
Private Sub cboLieferantID_KeyDown(KeyCode As Integer, Shift As Integer)
Dim lngIndex As Long
Select Case KeyCode
Case 38, 40
lngIndex = Me!cboLieferantID.ListIndex
Select Case KeyCode
Case 38
If lngIndex > 0 Then
Me!cboLieferantID.ListIndex = lngIndex - 1
End If
Case 40
If lngIndex < Me!cboLieferantID.ListCount - 1 Then
Me!cboLieferantID.ListIndex = lngIndex + 1
End If
End Select
KeyCode = 0
End Select
End Sub
Listing 1: Kombinationsfeldeinträge auswählen mit den Nach oben- und Nach unten-Tasten
Dann folgt die zweite Select Case-Bedingung, in der wir nach den Werten 38 (Nach oben) und 40 (Nach unten) unterscheiden.
Im Falle der Taste Nach oben prüfen wir, ob der aktuelle Index größer als 0 ist. Dazu der Hinweis, dass der Wert der Eigenschaft ListIndex bei noch nicht vorhandener Auswahl den Wert -1 hat und dass dieser 0-basiert ist.
Ist die Bedingung erfüllt, ziehen wir vom aktuellen Indexwert den Wert 1 ab und weisen das Ergebnis der Eigenschaft ListIndex des Kombinationsfeldes zu. Somit stellen wir den Index jeweils auf den vorherigen Wert ein und zeigen das jeweils darüber liegende Element an.
In die andere Richtung, also nach unten, sieht es ähnlich aus. Hier prüfen wir, ob der Wert von lngIndex noch kleiner ist als die Anzahl der Elemente, ermittelt mit der ListCount-Eigenschaft und um 1 vermindert. Ist das der Fall, erhöhen wir ListIndex einfach um den Wert 1 und wechseln damit zum nächsten Element.
Schließlich müssen wir noch den Wert des Parameters KeyCode auf 0 einstellen, damit das Betätigen der Tasten Nach oben und Nach unten tatsächlich nur auf das Wechseln der Einträge auswirkt.
Code wiederverwendbar machen
Nun wollen wir die gleiche Prozedur für das andere Kombinationsfeld cboKategorieID anlegen. Das würde allerdings bedeuten, dass wir den größten Teil der Anweisungen doppelt anlegen. Wenn wir dann später einmal eine Optimierung oder eine andere Änderung vornehmen wollen, müssen wir diese an allen betroffenen Stellen durchführen.
Also gliedern wir den Code aus, und zwar nicht einfach in eine eigene Prozedur, sondern gleich in eine Klasse. Diese sieht wie in Listing 2 aus.
Option Compare Database
Option Explicit
Private WithEvents m_ComboBox As ComboBox
Public Property Set ComboBox(cbo As ComboBox)
Set m_ComboBox = cbo
With m_ComboBox
.OnKeyDown = "[Event Procedure]"
End With
End Property
Private Sub m_ComboBox_KeyDown(KeyCode As Integer, Shift As Integer)
Dim lngIndex As Long
Select Case KeyCode
Case 38, 40
lngIndex = m_ComboBox.ListIndex
Select Case KeyCode
Case 38
If lngIndex > 0 Then
m_ComboBox.ListIndex = lngIndex - 1
End If
Case 40
If lngIndex < m_ComboBox.ListCount - 1 Then
m_ComboBox.ListIndex = lngIndex + 1
End If
End Select
KeyCode = 0
End Select
End Sub
Listing 2: Klasse mit den Funktionen zum Blättern in den Kombinationsfeld-Einträgen
Um die Klasse neu anzulegen, wählen Sie VBA-Editor den Menüeintrag Einfügen|Klassenmodul aus. Die so neu angelegte Klasse speichern Sie mit der Tastenkombination Strg + S, und zwar unter dem Namen clsKombinationsfeldPerTaste.
Dann fügen Sie zunächst eine Objektvariable hinzu, mit der Sie den Verweis auf das noch zu übergebende Kombinationsfeld speichern:
Private WithEvents m_ComboBox As ComboBox
Um dieses zu füllen, stellen wir im Klassenmodul die folgende öffentliche Property Set-Methode zur Verfügung:
Public Property Set ComboBox(cbo As ComboBox)
Set m_ComboBox = cbo
With m_ComboBox
.OnKeyDown = "[Event Procedure]"
End With
End Property
Diese Property Set-Methode kann in der erzeugenden Prozedur als Eigenschaft des Objekts auf Basis der Klasse verwendet werden. Das dabei zugewiesene Kombinationsfeld wird dann in der privaten Variablen m_ComboBox gespeichert.
Für dieses stellen wir dann noch die Eigenschaft OnKeyDown auf den Wert [Event Procedure] ein. Das ist gleichbedeutend mit dem Einstellen der Eigenschaft Bei Taste ab im Eigenschaftenfenster des Steuerelements auf den Wert [Ereignisprozedur].
Die Ereignisprozedur, die wir dafür implementieren, heißt m_ComboBox_KeyDown. Sie legen diese am einfachsten an, indem Sie im Codefenster des Klassenmoduls mit dem linken Kombinationsfeld den Wert m_ComboBox und mit dem rechten den Wert KeyDown auswählen.
Danach erscheint dann der Prozedurrahmen im Codefenster. Der Inhalt dieser Prozedur entspricht weitgehend dem der Prozedur cboLieferantID_KeyDown, die wir bereits weiter oben beschrieben haben. Der wesentliche Unterschied ist, dass wir dort nicht mit Me!cboLieferantID auf das Kombinationsfeld zugreifen, sondern über m_ComboBox.
Klasse für Kombinationsfeld implementieren
Wir zeigen am Beispiel des Kombinationsfeldes cboKategorieID, wie Sie die Funktion der Klasse für das Kombinationsfeld bereitstellen.
Dabei deklarieren wir zunächst eine Objektvariable für die Klasse clsKombinationsfeldPerTaste und nennen diese objKombinationsfeldPerTaste_cboKategorieID:
Dim objKombinationsfeldMitTaste_cboKategorieID As clsKombinationsfeldPerTaste
Diese Objektvariable müssen wir nun noch beim Laden des Formulars instanzieren und mit einem Verweis auf das mit der Funktion auszustattende Steuerelement versehen. Das erledigen wir in der Ereignisprozedur, die durch das Ereignis Beim Laden ausgelöst wird und sieht wie folgt aus:
Private Sub Form_Load()
Set objKombinationsfeldMitTaste_cboKategorieID = New clsKombinationsfeldPerTaste
With objKombinationsfeldMitTaste_cboKategorieID
Set .ComboBox = Me!cboKategorieID
End With
End Sub
Wir weisen der Variablen objKombinationsfeldMitTaste_cboKategorieID eine neue Instanz der Klasse clsKombinationsfeldPerTaste zu und weisen seiner Eigenschaft ComboBox dann einen Verweis auf das betroffene Steuerelement zu. Anschließend können Sie auch für dieses Kombinationsfeld die Änderung des aktuellen Eintrags mit den Nach oben- und Nach unten-Tasten nutzen.
Auf die gleiche Weise können Sie die Funktion noch weiteren Kombinationsfeldern hinzufügen. Sie benötigen nur jeweils eine Objektvariable und füllen diese dann in der Form_Load-Methode mit einem neuen Objekt der Klasse clsKombinationsfeldPerTaste und weisen seiner Eigenschaft ComboBox das betroffene Kombinationsfeld zu.