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
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.
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.
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
Hallo,
Du musst den Rückgabewert der MsgBox auswerten und entsprechend reagieren.
Welche MsGBox willst Du abbrechen und was soll geschehen beim Abbrechen.
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
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.
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.
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...
Hallo Joe,
Prüfe in der BeforeUpdate-Prozedur auf
Me.NewRecord
setze
Cancel = True
und verlasse die Prozedur.
gruss ekkehard
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
Hallo,
WO (in welcher Prozedur) steht denn das Code-Fragment?
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
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
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
Hallo,
du kannst ja statt zu markieren, den "falschen" Wert in der Msgbox anzeigen und das Textfeld auf NULL setzen, bzw. mit ME.Undo bearbeiten.