Eine häufige Aufgabe ist es, den Fokus auf ein Steuerelement
zu setzen, welches sich in einem Unterformular befindet.
Nehmen wir mal an, unser Unterformular trägt den Name
subFormBestellungen. Innerhalb von diesem Unterformular möchten wir den Fokus
auf das Steuerelement mit den Namen cboArtikel setzen.
Die folgende Methode dazu ist zwar korrekt geschrieben, wird
jedoch einen Fehler liefern:
Me.subFormBestellungen.Form.cboArtikel.SetFocus
Warum? Weil der Fokus explizit vorher auf das Unterformular
gesetzt werden muss.
Daher benötigen wir immer diese 2 Anweisungen:
Me.subFormBestellungen.SetFocus Me.subFormBestellungen.Form.cboArtikel.SetFocus
Die Aufgabe ist soweit gelöst, nur müsen wir uns in der
Programmierung auf ein genaues Steuerelement festlegen, in unserem Fallbeispiel
cboArtikel.
Nun könnte es ja sein, dass dieses Steuerelement momentan
deaktiviert oder ausgeblendet oder aus anderen Gründen nicht verfügbar ist.
Dann sollte das nächste Steuerelement genommen werden. Ich benötige also eine
Funktion, die den Fokus auf das nächst mögliche Steuerelement setzt und dabei
die Aktivierreihenfolge der Steuerelemente berücksichtigt.
Der Verweis auf das erste Steuerelement in einem Formular
erfolgt mit Controls(0). Leider ist Controls(0) nicht das erste Steuerelement
aus der hinterlegten Aktivierreihenfolge, sondern es entspricht das erste
Steuerelement welches im Entwurfsmodus eingefügt wurde. Interessiert uns für
unsere Aufgabe aber herzlich wenig!
Um die Steuerelemente in der Reihenfolge aus der Aktivierreihenfolge
zu erhalten, müssen wir die Eigenschaft TabIndex (Reihenfolgeposition) auswerten:
Wir brauchen zu nächste eine Prozedur die uns eine Liste
aller Steuerelemente aus einem Formular in der aufsteigenden
Aktivierreihenfolge zusammenstellt. Dabei sollten wir die Steuerelemente die nicht
die Eigenschaft TabIndex haben, außenvorlassen. Und ggf. auch die nicht
berücksichtigen, bei denen die Eigenschaft TabStop auf Nein steht.
Fangen wir somit mit der Prozedur an, die uns die Information liefert, ob ein Objekt eine Eigenschaft besitzt:
Public Function ExistProperty(ByRef obj As Object, ByRef prpName As String, Optional ByRef prp As Property) As Boolean
For Each prp In obj.Properties
If prpName = prp.Name Then
ExistProperty = True
Exit For
End If
Next
End Function
Nun zur Prozedur die uns eine Liste
aller Steuerelemente aus einem Formular in der aufsteigenden
Aktivierreihenfolge zusammenstellt:
Public Function GetControlsInTabindexOrder(frm As Access.Form, ByRef ctlList() As Access.control _
, Optional OnlyWithTabStop As Boolean) As Boolean
'OnlyWithTabStop=True means just consider the controls where tabstop is true
'Function return True if at least one control was found
Dim ctl As Access.control, i As Long, ii As Long, z As Long
Do
For Each ctl In frm.Controls
If ctl.Parent.Name = frm.Name Then
If ExistProperty(ctl, "TabIndex") Then
If ctl.TabIndex = i Then
If ctl.TabStop Or Not OnlyWithTabStop Then
ReDim Preserve ctlList(ii)
Set ctlList(ii) = ctl
ii = ii + 1
GetControlsInTabindexOrder = True
Exit For
End If
i = i + 1
End If
End If
End If
Next
z = z + 1
Loop Until z >= frm.Controls.count
End Function
Zu guter letzt die Prozedur die versucht aus
der Steuerelement-Liste den Fokus solange auf einen Steuerelement nach dem anderen zu setzen, bis es
erfolgreich ist:
Public Function SetFocusFirstControl(frm As Access.Form _
, Optional OnlyWithTabStop As Boolean = True) As Boolean
Dim ctlList() As Access.control, i As Long
'Hole alle Controls in Reihenfolge laut Aktivierreihenfolge
If GetControlsInTabindexOrder(frm, ctlList(), OnlyWithTabStop) Then
On Error Resume Next
'Schleife durch alle mögliche Controls die den Fokus bekommen könnten
For i = 0 To UBound(ctlList)
ctlList(i).SetFocus 'Versuch den Fokus zu setzen (Könnte misslingen aus div. Gründen (Not Enabled, not Visisble usw...)
If Err.Number = 0 Then
SetFocusFirstControl = True
Exit For 'Fokus konnte erfolgreich gesetzt werden, also Schleife beenden, Job erfolgreich erledigt
End If
Err.Clear 'Fokus konnte nicht erfolgreich gesetzt werden, also Schleife fortführen
Next
End If
End Function
Anwendungsbeispiel: Bei Klick auf die Schaltfläche 'cmdEingabeBestelldaten' soll der Fokus im Unterformular 'SubForm' auf das erste mögliche Steuerelement gesetzt werden:
Private Sub cmdEingabeBestelldaten_Click()
Me.SubForm.SetFocus
SetFocusFirstControl Me.SubForm.Form
End Sub

