Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Fokus, aber nicht Fokus

Begonnen von Stele4, April 29, 2026, 08:28:55

⏪ vorheriges - nächstes ⏩

Stele4

Hallo!
In einem Formular werden Text- und ComboBoxes fuer die Eingabe einer Filterbedingung verwendet.
Tritt das Ereignis 'Change' ein, wird das Formular neu gefiltert.
Das Formular wird also bei der Eingabe permanent mitgefiltert.

Problem: Wird ein Wert eingegeben, der nicht im Feld vorhanden ist, wird das Formular korrekt gefiltert (keine Datensaetze angezeigt), aber es kommt auch zu einem Fehler: "Eigenschaft kann nicht gesetzt werden, solange das Steuerlement nicht den Fokus hat (Fehler 2185)."

Laut Meldung triit der Fehler beim Versuch auf, den Cursor im Suchfeld zu setzen.
Den sollte es aber haben. Es wurde eben beschrieben, der Code setzt den Fokus extra noch einmal und im Debugging ist der Name des korrekten Elements zu lesen.

620         If Not oActCntl Is Nothing Then
630             oActCntl.SetFocus
640             oActCntl.SelStart = iActTxtSelPos
650             oActCntl.SelLength = 0
660         End If

Ich wuerde mich vorerst mit 'On Error Resume Next' behelfen.
Aber das ist nicht fein und ich wuesste gern den Grund fuer das Verhalten.

Gruss Stele

Knobbi38

Hallo Stele,

der von dir gezeigte Code läßt leider nicht erkennen, wo der Fehler liegen könnte. Im Übrigen ist das Debuggen von Code mit Fokushandling oft nicht möglich, weil dieses durch das Debuggen beeinflusst wird.

Knobbi38

Stele4

Hallo Knobbi!
Zeile 640.
SelStart soll geschrieben werden, loest aber einen Fehler aus, weil das Element nicht den Fokus hat.
Dieser Fehler taucht nur auf, wenn der Filter eine 'leere Tabelle' zurueck gibt.
Ansonsten wird der Code problemlos durchlaufen.
Was das Eine mit dem Anderen zu tun hat, erschliesst sich mir nicht.

Gruss Stele

Knobbi38

#3
Wie bereits gesagt, kann man nur Vermutungen anstellen. Wenn du aber den Fehler schon selber so eingrenzen kannst, würde ich den Zustand, welcher zum Fehler führt, mit einer IF Bedingung prüfen und ggf. abfangen.

Es gäbe auch die Lösung, die letzte Änderung, welche zu einer leeren Ergebnismenge geführt hat, einfach zurückzunehmen und dem Anwender das mit einem Beep zu quittieren. 



Bitsqueezer

Hallo,

nach der Beschreibung würde ich vermuten, daß ein anderer Codeteil den Fokus in ein Feld Deiner Ergebnisliste setzen will - was funktioniert, solange diese nicht gesperrt ist und halt Inhalt hat.

Wenn kein Inhalt, dann werden auch keine Felder angezeigt (i.d.R.) und dann gibt es auch kein Zielfeld.

Also einfach mal nach "SetFocus" im Code suchen.

Gruß

Christian

Stele4

Das waere schoen. Das koennte ich verstehen. Im Code ist solches nicht, aber ich vermute, dass etwas in der Art passiert.

Inzwischen habe ich erfahren, dass z.B. mit 'Form.Filter' ein Textfeld seinen Editiermodus verliert und auch 'Txt.SetFocus' dann nicht mehr hilft.
Ich haette erwaehnen sollen, dass der genannte Code in einem Klassenmodul ist.
Der Verlust geschieht im Klassenmodul. Im Formular (auch ein Klassenmodul) kann mit '.Focus' und '.Text' weiter gearbeitet werden. Warum auch immer.

Meine Loesung fuer heute:
 - Filter merken,
 - neuen Filter setzen,
 - wenn Tabelle leer, alten Filter wiederherstellen,
 - Antwort an aufrufendes Ereignis des Textfeldes,
 - ggf. Wiederherstellen des Eintrages.
Ich fuege noch das Beep ein.

Gruss und Dank!

        '--- Filter anwenden ----------------------------------------------------
470     Debug.Print sRsm
       
480     With oMe 
490         lngID = Nz(oMe(cIdFld), 0)            'akt. Datensatz merken
500         .Painting = False
510         If sRsm <> "" Then                    'wenn Filterstring nicht leer..
520             sFltrOld = .Filter                    'alten Filter merken
530             sRsm = Right(sRsm, Len(sRsm) - 5)
540             .Filter = sRsm                        '==> Filtern
550             .FilterOn = True
560             If .Recordset.RecordCount < 1 Then    'wenn Ergebnis leer..
570                 .Filter = sFltrOld                    'alten Filter anwenden
580                 .Painting = True
590                 GoTo Abbruch2 
600             End If
610         Else
620             .FilterOn = False
630             .Filter = ""
640         End If

650         If lngID > 0 Then .Recordset.FindFirst cIdFld & " = " & lngID
660         .Painting = True
670     End With
       
        '--- Cursor an alte Stelle --------------------------------         
680     If Not bClr Then
690         If Not oActCntl Is Nothing Then
700             oActCntl.SetFocus
710             On Error Resume Next
720             oActCntl.SelStart = iActTxtSelPos
730             oActCntl.SelLength = 0
740             If Err.Number = 2185 Then
                    '...
750             End If
760         End If
770     End If
                           
'780     Call fbFltrCmbAct
790     fcFltr = True

Formular:
Private Sub txtDsc_Fltr_Change()
Dim sMem As String
   
    With Me.txtDsc_Fltr
        sMem = Nz(.Value, "")
        If Not fcFrmHandler.fcFltr() Then       'wenn Filter mit leerem Ergebnis..
            .Undo                                   'notw.?
            .SetFocus
            .Text = sMem                            'alter Wert als Eingabe ==> loest erneut Change aus
            .SelStart = Len(.Text)                  'Cursor ans Ende
            .SelLength = 0
        End If
    End With
   
End Sub

Normalo0815

Hallo Stele4
Zitat von: Stele4 am April 29, 2026, 16:17:35.Text = sMem                            'alter Wert als Eingabe ==> loest erneut Change aus

Die .Text Eigenschaft für ein Formular-Textfeld hat einige Tücken. Wenn ein anderer Wert als der vorhandene per VBA zugewiesen wird, dann werden dadurch sofort einige Ereignisse ausgelöst und Gültigkeitsregeln angewandt. Es ist, wie wenn per Tastatur im Formular-Textfeld Eingaben gemacht würden und dann das Feld verlassen wird, ohne das es verlassen wird.

Zudem ist .Text vom Typ String, d. h. Null kann nicht zugewiesen werden. Es enthält halt das, was gerade am Bildschirm zu sehen ist. Das kann sich von .Value unterscheiden bei speziellen Formtierungen, z. B. Zahlen, Datum ect. (wichtig beim Auslesen von .Text und zuweisen an eine Variable).

Ein Weg wäre vielleicht, alle betroffenen Ereignisse, die .Text auslöst, vor der Zuweisung zu deaktivieren ([Event Procedure] entfernen) und danach wieder zu aktivieren ([Event Procedure] hinzufügen).

-----

Zuweisungen an .Text per VBA würde ich eher vermeiden.
Die .Value Eigenschaft wäre da einfacher zu handhaben.
Freundliche Grüße
Normalo0815   :)

Knobbi38

@Normalo0815:

bei einer ungebundenen Textbox und im ChangeEvent muss man die Text-Eigenschaft auswerten, die Value-Eigenschaft ist hier ungeeignet.

Hallo Stele,

ich habe dir mal ein Beispiel fertig gemacht, wie man eine "Filter-per-Tastendruck" - Logik implementieren könnte. Vielleicht gibt das ja ein paar neue Anregungen.

Knobbi38

PS:
Die Kommentare habe ich übrigens per KI nachträglich hinzufügen lassen.  ;)