Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Textfeld im Formular markieren

Begonnen von Joe0301, November 21, 2016, 12:19:08

⏪ vorheriges - nächstes ⏩

Joe0301

Hallo Forum,

Nachdem ich mich stundenlang durch Foren geklickt habe und nicht fündig geworden bin stelle ich nun meine Frage hier und hoffe ein schlaues Köpfchen kann mir helfen. Ich versuche es so genau wie möglich zu beschreiben.

Ich habe ein Formular zur Eingabe eines neuen Datensatzes in eine Tabelle erstellt.
Dazu habe ich die Eingeabefelder an die Tabelle gebunden. (mit Steuerelementeninhalt)
Das Funktioniert auch alles wie es soll.
Bei einem Eingabefeld wird nun kontrolliert ob es einen Gültigen Inhalt hat mit einer Ereignis Prozedur after update
Bei Fehlerhafter Eingabe kommt eine Message box. Danach soll der Focus wieder auf das Eingabefeld gesetzt und dessen Inhalt MARKIERT werden. Und da liegt der Fehler das Eingabefeld bekommt lediglich den Cursor am Anfang des Inhaltes und markiert ihn nicht.

Private Sub Eingabefeld_AfterUpdate()

Me!Eingabefeld = Me!Eingabefeld.Text

If Me!Eingabefeld > 1000 And Me!Eingabefeld < 10000 Then
If Not IsNull(DLookup("MeinFeld", "MeineTabelle", "MeinFeld = " & Str(Me!Eingabefeld))) Then
MsgBox "MeinFeld " & Str(Me!Eingabefeld) & " ist bereits vorhanden"
Me!Eingabefeld2.SetFocus   'um Focus abzulenken weil Fokus nicht auf ein Feld gelegt werden kann das bereits den Focus hat
Me!Eingabefeld.SetFocus
Else
Me!Eingabefeld2.SetFocus
End If
Else
MsgBox "Ungültige Eingabe"
Me!Eingabefeld2.SetFocus
Me!Eingabefeld.SetFocus
Me!Eingabefeld = Me!Eingabefeld.Text                         'mein versuch die markierung zu erzwingen mit und ohne die zeile
Me!Eingabefeld.SelStart = 0                                        'mein versuch die markierung zu erzwingen an verschiedenen stellen
Me!Eingabefeld.SelLength = Len("" & Me!Eingabefeld)   'mein versuch die markierung zu erzwingen auch mit festen werten

End If
end Sub

Ich hab mal kommentiert was ich bereits versucht habe.
Ich hoffe ich habe meine Problematik verständlich ausgedrückt und entschuldige mich für den langen text.
Und bedanke mich schon mal vielmals für eure Mühe.

MfG
Joe0301



PhilS

Zitat von: Joe0301 am November 21, 2016, 12:19:08Bei einem Eingabefeld wird nun kontrolliert ob es einen Gültigen Inhalt hat mit einer Ereignis Prozedur after update
Bei Fehlerhafter Eingabe kommt eine Message box. Danach soll der Focus wieder auf das Eingabefeld gesetzt und dessen Inhalt MARKIERT werden.
Dein Code zum Markieren sieht für mich auf den ersten Blick plausibel aus. - Er wäre allerdings besser lesbar, wenn du ihn auch hier im Forum als Code formatiert hättest.

Aber warum überprüfst du den Feldinhalt erst bei After_Update? Wenn du sowieso den Fokus zurück auf das Feld setzt und den Benutzer nichts anderes machen lassen willst, bevor die Eingabe korrekt ist, solltest du besser das Before_Update-Ereignis verwenden. Dann ist der Fokus noch auf dem Feld und der geänderte, falsche Inhalt noch gar nicht im Feld gespeichert. - Das macht vieles einfacher.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

MzKlMu

#2
Hallo,
AfterUpdate() ist falsch. Nach Aktualisierung ist alles zu spät, da ist der Datensatz geschrieben. Du musst BeforeUpdate verwenden. Dieses Ereignis (das Speichern) kann mit Cancel = True abgebrochen werden. Da kannst Du Dir auch die ganze Fokussetzerei sparen, denn das Feld wird ja nicht verlassen.
Private Sub Eingabefeld_BeforeUpdate(Cancel As Integer)
    If Me!Eingabefeld > 1000 And Me!Eingabefeld < 10000 Then
        If Not IsNull(DLookup("MeinFeld", "MeineTabelle", "MeinFeld = " & Str(Me!Eingabefeld))) Then
            MsgBox "MeinFeld " & Str(Me!Eingabefeld) & " ist bereits vorhanden"
        End If
    Else
        MsgBox "Ungültige Eingabe"
        Cancel = True
    End If
End Sub


Ungetestet, besonders wegen den If.

PS:
Bitte immer die Codetags benutzen.
Gruß Klaus

Joe0301

Vielen Dank für die schnelle Antwort
ZitatAber warum überprüfst du den Feldinhalt erst bei After_Update? Wenn du sowieso den Fokus zurück auf das Feld setzt und den Benutzer nichts anderes machen lassen willst, bevor die Eingabe korrekt ist, solltest du besser das Before_Update-Ereignis verwenden.
Hab da beim auswählen nicht genau genug drüber nachgedacht. Jedoch gibt es noch eine Schaltfläche mit der die Eingabe abgebrochen werden kann.

Private Sub Eingabefeld_BeforeUpdate(Cancel As Integer)
If Me!Eingabefeld > 1000 And Me!Eingabefeld < 10000 Then
If Not IsNull(DLookup("MeinFeld", "MeineTabelle", "MeinFeld = " & Str(Me!Eingabefeld))) Then
MsgBox "MeinFeld " & Str(Me!Eingabefeld) & " ist bereits vorhanden"
cancel = true
Me!Eingabefeld.SelStart = 0                                       
Me!Eingabefeld.SelLength = Len("" & Me!Eingabefeld) 
Else
End If
Else
MsgBox "Ungültige Eingabe"
Cancel = True
Me!Eingabefeld.SelStart = 0                                       
Me!Eingabefeld.SelLength = Len("" & Me!Eingabefeld)
End If
End Sub


Yeah damit ist mein ursprüngliches Probelm gelöst vielen dank dafür .. happy
Jedoch funktioniert die Abbrechen Schaltfläche jetzt nur noch nach einer gültigen eingabe, und
diese soll immer funktionieren. wie kann ich das umgehen ?
und bitte sagt mir jetzt nicht das es dafür ein after update Ereignis sein muss :D

MfG
Joe0301

MzKlMu

Hallo,
Du musst den Rückgabewert der MsgBox auswerten und entsprechend reagieren.
Welche MsGBox willst Du abbrechen und was soll geschehen beim Abbrechen.
Gruß Klaus

Joe0301

Die Abbrechen Schaltfläche ist auf dem Formular selbst vorhanden.
Und macht über Undo alle eingaben rückgängig und schließt das Formular.
macht dies jedoch erst, wenn Das Eingabe Feld eine gültige Eingabe besitzt.
nach bestätigen der ungültigen Eingabe soll auch noch abgebrochen werden können.

MfG
Joe0301

MzKlMu

Hallo,
warum nimmst Du nicht die Abbrechen Schaltfläche der MsgBox "Ungültige Eingabe" ?
Mit einer extra Schaltfläche geht das nicht ganz so einfach. Es muss ja das Cancel = True umschifft werden, was aber im BeforeUpdate notwendig ist.
Gruß Klaus

Joe0301

Hallo,
Das wäre nur Wünschenswert bei Umentscheidung des Users einen Direktausstieg zu ermöglichen und keine
Fehlermeldung zu erzeugen die eigentlich gar nicht zu der Schaltfläche passt.
Fehlermeldungen werden auch mal schnell weggeklickt. Oder dadurch das Formular versehentlich geschlossen.

Aber naja wenn es nicht anderes geht muss ich es über die Messagebox machen, ist auch nicht dramatisch.

Vielen Dank für eure Hilfe !

MfG
Joe0301

PS: Trotzdem würde mich noch interessieren wieso der Text nach dem after update Ereignis nicht markiert wird
ist für mich irgendwie unlogisch.


DF6GL

Hallo,


wenn Du den Code zum Afterupdate-Ereignis mal mit Einzelschritt durchläufst, wirst Du feststellen, dass der Text  tatsächlich markiert wird. "Dummerweise" wird aber der Fokus nach/beim Verlassen der Prozedur (End Sub) vom internen Ablauf auf ein anderes Feld gesetzt, was wiederum die "Entmarkierung" des Feld-Textes zur Folge hat...
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

Beaker s.a.

Hallo Joe,
Prüfe in der BeforeUpdate-Prozedur auf
Me.NewRecord
setze
Cancel = True
und verlasse die Prozedur.
gruss ekkehard
Alles, was geschieht, geschieht. - Alles, was während seines Geschehens etwas anderes geschehen lässt, lässt etwas anderes geschehen. - Alles, was sich selbst im Zuge seines Geschehens erneut geschehen lässt, geschieht erneut. - Allerdings tut es das nicht unbedingt in chronologischer Reihenfolge.
(Douglas Adams, Mostly Harmless)

Joe0301

Hallo DF6GL,
Vielen Dank für die Erklärung nun weiß ich wenigstens was passiert :)

Hallo Beaker s.a.,
Vielen Dank für deinen Tipp
Ich habe versucht deinen code umzusetzen, jedoch komme ich dann aus dem Feld gar nicht mehr raus :D

If Me.NewRecord Then    'auch Me.NewRecord = true getestet
    cancel = True
    Exit Sub
    End If


Das Feld bekommt den Focus in der Form Load Prozedur, nachdem der neue Datensatz geladen wurde.
Als VBA gibt es sonst nur noch die Click Prozeduren für speichern und das Abbrechen.
Habe gelesen das die Exit Funktion wieder in die aufrufende Prozedur zurückspringt. Bedeutet das, dass das Formular in meinem Fall immer wieder neu geladen wird ? oder liegt mein Fehler woanders ?

MfG
Joe0301

DF6GL

Hallo,

WO (in welcher Prozedur) steht denn das Code-Fragment?
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

Joe0301


Private Sub Eingabefeld_BeforeUpdate(Cancel As Integer)

If Me.NewRecord Then    'auch Me.NewRecord = true getestet
    cancel = True
    Exit Sub
    End If

If Me!Eingabefeld > 1000 And Me!Eingabefeld < 10000 Then
If Not IsNull(DLookup("MeinFeld", "MeineTabelle", "MeinFeld = " & Str(Me!Eingabefeld))) Then
MsgBox "MeinFeld " & Str(Me!Eingabefeld) & " ist bereits vorhanden"
cancel = true
Me!Eingabefeld.SelStart = 0                                       
Me!Eingabefeld.SelLength = Len("" & Me!Eingabefeld) 
Else
End If
Else

If Me.NewRecord Then    'hier als zweiter test
    cancel = True             ''hier als zweiter test
    Exit Sub
    End If

MsgBox "Ungültige Eingabe"
Cancel = True
Me!Eingabefeld.SelStart = 0                                       
Me!Eingabefeld.SelLength = Len("" & Me!Eingabefeld)
End If
End Sub

da stehts drin, erst an der oberen stelle Probiert, dann nochmal in der else schleife


Private Sub Form_Load()

DoCmd.GoToRecord , , acNewRec
Me!Eingabefeld.SetFocus


End Sub


Und daraus erhählt das Feld erstmalig den Focus.


Private Sub Schaltfläche_Abbrechen_Click()

  On Error Resume Next
   DoCmd.SetWarnings False
   DoCmd.RunCommand acCmdUndo
   DoCmd.SetWarnings True
   DoCmd.Close acForm, Me.Name, acSavePrompt
   MsgBox "Eingabe wird abgebrochen! Fenster wurde automatisch geschlossen."
   Forms![MeinEingabeformular].Refresh
End Sub



und nochmal zur Sicherheit den Code der Schaltfläche zum Abbrechen

Ich hoffe das reicht an Info. vielen dank für die Mühe.

MfG
Joe0301

DF6GL

Hallo,

Was genau willst Du überhaupt insgesamt damit bezwecken?


Und wie gesagt, die Markierung des Textes funktioniert in diesem Ereignis nicht (dauerhaft).

Der "zweite Test" ist obsolet, die Bedingung liefert immer "false"  und somit wird der nachfolgende Code nicht ausgeführt.

Weiterhin:

Private Sub Schaltfläche_Abbrechen_Click()  ' Wie heißt das Form mit dieser Proz.?

  On Error Resume Next
   DoCmd.SetWarnings False
   DoCmd.RunCommand acCmdUndo
   DoCmd.SetWarnings True

'anstelle:
Me.Undo
Me.Undo
Me.Undo
   DoCmd.Close acForm, Me.Name  , acSavePrompt
 
MsgBox "Eingabe wird abgebrochen! Fenster wurde automatisch geschlossen."
   Forms![MeinEingabeformular].Refresh   ' Wenn der Code in diesem Form abläuft, ist diese Zeile überflüssig, weil das Form vorher geschlossen wurde.
End Sub

Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

Joe0301

Hallo,
Zitat von: DF6GL am November 22, 2016, 12:33:55

Was genau willst Du überhaupt insgesamt damit bezwecken?
Es sollte als Eingabeerleichterung dienen.

Eingabe Ungültig: Fehlermeldung
Fehlermeldung bestätigt: Text makiert um neue fixe Eingabe zu ermöglichen und noch Feedback vorhanden was eingeben wurde.

User guckt noch mal in die Unterlagen und denkt sich: passt doch alles ich breche die Eingabe ab (Schaltfläche)

Schaltfläche wird gecklickt: Formular schließt sich.

Fertig.

Mehr wollte ich nicht bezwecken, aber ist den aufwand langsam nicht mehr wert diese "Kosmetikprobleme" :D


Ich werde jetzt die Variante mit dem Beenden über die Messagebox verwenden.
was den Zweck auch erfüllt.
Zitat
Private Sub Schaltfläche_Abbrechen_Click()  ' Wie heißt das Form mit dieser Proz.?

Das ist in der VBA des Formulares Eingabeformular, in der sich alle Prozeduren befinden über die wir hier gesprochen haben.

In diesem Sinne mein Hauptproblem was mich gestört hat ist gelöst und dafür bedanke ich mich, auch für die weiteren nützlichen tipps dabei !

MfG
Joe0301