Kontakt
DSVGO
In manchen Situationen ist es notwendig, das nächste Control in der Tab-Reihenfolge zu finden, z.B. wenn bei Druck auf Return auf das nächste Eingabefeld gesprungen werden soll. Oft wird in so einem Fall SendKeys benutzt, um ein Druck auf die Tabulator-Taste zu generieren, etwa so:
Private Sub txtEingabe_KeyPress(KeyAscii As Integer) If KeyAscii = vbKeyReturn Then SendKeys "{Tab}" End Sub
Dies hat jedoch einige Nachteile, z.B. wird u.U. der Status der Num-Taste geändert.
Mit den unten gezeigten Routinen ist es möglich, das Control zu bestimmen, welches als nächstes den Fokus erhalten soll. Dann reicht es im obigen Beispiel folgendes zu schreiben:
Private Sub txtEingabe_KeyPress(KeyAscii As Integer) If KeyAscii = vbKeyReturn Then JumpNextControl End Sub
Stört ein nervender Piepton oder soll der Tastendruck für das gesamte Formular gelten? Dann empfehle ich unbedingt folgenden Artikel: Bei Enter: Aktion statt Beep!
Die erste Funktion gibt für ein Control an, ob es überhaupt den Fokus via Tabulator erhalten kann. Dazu muss er u.a. sichtbar (Visible) und aktivierbar (Enabled) sein. Ausserdem darf er kein Container sein (wird via Error-Handler und ClipControls-Eigenschaft festgestellt):
Public Function IsFocusable( _ ByRef ctl As Control _ ) As Boolean On Error Resume Next 'Auf Fokussierbarkeit prüfen: If Not ctl.TabStop Then Exit Function If Not ctl.Visible Then Exit Function If Not ctl.Enabled Then Exit Function 'Nur nicht-Container berücksichtigen: If ctl.ClipControls <> ctl.ClipControls _ Then IsFocusable = True On Error GoTo 0 End Function
Die folgende Funktion benutzt IsFocusable, um das nächste Control in der Tab-Reihenfolge zu finden. Es wird dabei genau das Control auf dem Formular frm gesucht, dessen TabIndex größer als TabMin ist, aber kleiner als alle anderen:
Public Function FindNextControl( _ ByRef frm As Form, _ ByVal TabMin As Long _ ) As Control Dim ctl As Control Dim TabMax As Long TabMax = 32767 'Maximaler TabIndex For Each ctl In frm.Controls With ctl 'Control auf Eignung als Kandidat prüfen: If IsFocusable(ctl) Then 'TabIndex des Kandidaten checken: Select Case .TabIndex Case TabMin To TabMax 'Kandidat merken: Set FindNextControl = ctl TabMax = .TabIndex End Select End If 'IsFocusable(ctl) End With 'ctl Next ctl End Function
Die eigentliche Haupt-Routine kann mit einem optionalen Parameter aufgerufen werden, der entweder das Formular oder Steuerelement angibt, wo die Suche gestartet werden soll. Wird ActiveObject nicht angegeben, so wird automatisch das aktuelle Control des aktuellen Formulars verwendet.
Public Sub JumpNextControl( _ Optional ByRef ActiveObject As Object _ ) Dim frm As Form Dim ctl As Control Dim ctlFokus As Control 'Aktuelles Control bestimmen: If ActiveObject Is Nothing Then Set frm = Screen.ActiveForm Set ctl = frm.ActiveControl ElseIf TypeOf ActiveObject Is Form Then Set frm = ActiveObject Set ctl = frm.ActiveControl ElseIf TypeOf ActiveObject Is Control Then Set ctl = ActiveObject Set frm = ctl.Parent Else Err.Raise 5 'Invalid procedure call or argument End If 'Nächst größeren TabIndex suchen: Set ctlFokus = FindNextControl(frm, ctl.TabIndex + 1) 'Ggf. kleinsten TabIndex suchen: If ctlFokus Is Nothing _ Then Set ctlFokus = FindNextControl(frm, 0) 'Bei Erfolg Fokus setzen: If Not ctlFokus Is Nothing _ Then ctlFokus.SetFocus End Sub
Man beachte, dass erst nach dem Control mit dem nächst größeren TabIndex gesucht wird. Falls kein solches Control existiert, wird der kleinste gültige TabIndex berücksichtigt. Das entsprechende Control erhält dann ggf. den Fokus.
© Jost Schwider, 19.03.2001-19.03.2001 - http://vb-tec.de/ctltab.htm