Hallo liebe Accessfreunde,
ich möchte ermitteln, welches Steuerelement als nächstes den Fokus bekommt. Klar, wenn ich eine Reihenfolge festlege, dann wird beim Betätigen der TAB-Taste das Steuerelement ausgewählt, das in der Reihenfolge festgelegt ist. Wenn ich jedoch mit der Maus auf ein anderes Steuerelement klicke, dann umgehe ich ja diese Reihenfolge. Wie kann ich für diesen Fall mit VBA vorsorgen und prüfen, ob das STE den Fokus hat, was in der Reihenfolge so vorgesehen ist oder ein anderes?
Ich sehe hir das Problem, dass wenn ich den Code zur Prüfung des STE, was gerade den Fokus hat, z.B. im After-Update-Ereignis von dem STE reinschreibe, was gerade den Fokus verliert, werde ich auch dessen Namen erhalten und nicht von dem STE, was gerade ausgewählt wird. Hier beißt sich für mich die Katze in den Schwanz. Habt ihr da eine Idee?
Hallo Konrad,
hast Du schon mal versucht die Controls mit einer Schleife zu durchlaufen um die Eigenschaft
controlname.tabindex
zu prüfen?
Beste Grüße
Andreas
Zitat von: KonradR am November 03, 2024, 08:40:32Ich sehe hir das Problem, dass wenn ich den Code zur Prüfung des STE, was gerade den Fokus hat, z.B. im After-Update-Ereignis von dem STE reinschreibe, was gerade den Fokus verliert, werde ich auch dessen Namen erhalten und nicht von dem STE, was gerade ausgewählt wird. Hier beißt sich für mich die Katze in den Schwanz.
Wozu glaubst du das zu brauchen?
Ich vermute, dass es (mit Bordmitteln) nicht möglich ist, das Steuerelement zu ermitteln, was als nächstes den Focus bekommen wird, bevor Access tatsächlich versucht den Focus entsprechend zu verschieben.
Aber, nochmal, warum brauchst du das?
Die Validierung von eingegeben Daten macht man besser im
BeforeUpdate-Ereignis. - Ich vermute, dass sich damit deiner Anforderung bereits erfüllen lässt.
Hallo,
Der von Andreas angesprochene .TabIndex ist m.E. schon der richtige
Ansatz. Ich würde den in einer privaten Property im Form-Modul kapseln.
Beim Focuserhalt wird der aktuelle Index geprüft und entsprechend
gesetzt.
gruss ekkehard
Zitat von: Beaker s.a. am November 03, 2024, 12:58:53Der von Andreas angesprochene .TabIndex ist m.E. schon der richtige
Ansatz.
Das glaube ich eher nicht.
Wie hilft das bzgl. der Situation mit der Maus, wie im OP geschrieben:
Zitat von: KonradR am November 03, 2024, 08:40:32Wenn ich jedoch mit der Maus auf ein anderes Steuerelement klicke, dann umgehe ich ja diese Reihenfolge. Wie kann ich für diesen Fall mit VBA vorsorgen [...]
Hallo Konrad,
du solltest das mal näher erläutern, wofür das gut sein soll. Es ist ja gerade ein Vorteil eines Formulars, daß beliebig darin herum gesprungen werden kann, alles andere wäre eine Gängelung des Anwenders.
Gruß
Knobbi38
Zitat von: andyfau am November 03, 2024, 10:24:24hast Du schon mal versucht die Controls mit einer Schleife zu durchlaufen um die Eigenschaft
Danke für die Antwort. Und ja, mit dieser Vorgehensweise würde ich herausfinden, ob das STE, was als nächstes kommt nun den Fokus hat. Entscheidend für mich zu wissen ist, jedoch, hatte vorher ein ganz bestimmtes anderes STE den Fokus. Das bekomme ich mit dieser Vorgehensweise, glaube ich, nicht heraus.
Zitat von: PhilS am November 03, 2024, 12:22:05Wozu glaubst du das zu brauchen?
Es geht einfach darum, dass ich in der Tab-Reihenfolge zwei aufeinanderfolgende Steuerelemente habe. Per SELECT-CASE-Anweisung habe ich folgendes festgelegt:
Private Sub txtZugabeMenge_Exit(Cancel As Integer)
Select Case True
Case IsNull(Me.txtZugabeMenge.Value) And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge und eine Zugabeinheit eingeben"
Case IsNull(Me.txtZugabeMenge.Value) And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge eingeben"
Case Me.txtZugabeMenge.Value = 0 And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge > 0 und eine Zugabeinheit eingeben"
Case Me.txtZugabeMenge.Value = 0 And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge > 0 eingeben"
Case Not IsNull(Me.txtZugabeMenge.Value) And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabeeinheit eingeben"
Case Not IsNull(Me.txtZugabeMenge.Value) And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "SQL-String wird befüllt"
Cancel = True
End Select
End Sub
Wenn ich also vom STE txtZugabeMenge und einen Wert ausgefüllt habe und zum STE txtZugabeEinheit wechsle, dann erscheint immer die Meldung "Bitte eine Zugabeeinheit eingeben". Das ist etwas nervig, weil mir ja klar ist, dass ich noch was ausfüllen muss, wenn ich per TAB-Tast oder per Maus-Taste in das nächste STE wechsle und dort nun was ausfüllen will. Jetzt ist mir eingefallen, dass ich einfach die 5. Case Anweisung auskommentieren könnte. Das habe ich gemacht:
Private Sub txtZugabeMenge_Exit(Cancel As Integer)
Select Case True
Case IsNull(Me.txtZugabeMenge.Value) And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge und eine Zugabeinheit eingeben"
Case IsNull(Me.txtZugabeMenge.Value) And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge eingeben"
Case Me.txtZugabeMenge.Value = 0 And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge > 0 und eine Zugabeinheit eingeben"
Case Me.txtZugabeMenge.Value = 0 And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge > 0 eingeben"
' Case Not IsNull(Me.txtZugabeMenge.Value) And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabeeinheit eingeben"
Case Not IsNull(Me.txtZugabeMenge.Value) And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "SQL-String wird befüllt"
Cancel = True
End Select
End Sub
Und die Meldung verschwindet. War also doch einfacher als gedacht. Vielen Dank für eure Antworten. Es waren viele Inspirationen für mich dabei.
Zitat von: Beaker s.a. am November 03, 2024, 12:58:53Der von Andreas angesprochene .TabIndex ist m.E. schon der richtige
Ansatz. Ich würde den in einer privaten Property im Form-Modul kapseln.
Beim Focuserhalt wird der aktuelle Index geprüft und entsprechend
gesetzt.
Das kann ich noch mal brauchen. Vielen Dank.
Zitat von: KonradR am November 04, 2024, 06:12:08Es waren viele Inspirationen für mich dabei.
Dann möchte ich gerade noch eine weitere Inspiration nachschieben:
Dein aktueller Ansatz, eine Art Gültigkeitsprüfung im Exit-Event eines Steuerelements vorzunehmen, ist weder benutzerfreundlich noch zielführend.
Ein einzelnes Steuerelement für sich genommen, validiert man am besten im BeforeUpdate-Event des jeweiligen Steuerelementes. Den Datensatz als ganzes, also die Kombination aller Steuerelemente, validiert man am besten im BeforeUpdate-Event des Formulars. In beiden BeforeUpdate-Events kannst du über das
Cancel Argument abbrechen und somit verhindern, dass der Benutzer eine ungültige Eingabe speichert.
Hallo!
Man könnte auch alle anderen Steuerelemente inaktiv setzen, wenn man den User in ein bestimmtes Steuerelement "locken" will.
z. B. nach Steuerelement "cbxIncoterms" bei "EXW" muss der Abholort eingetragen werden =>
Bei AfterUpdate/BeforUpdate werden alle anderen Steuerelemente inaktiv gesetzt und nur die Incoterm-Combobox und das Steuerelement für die Ortsangabe aktiviert.
Alternative (würde ich für obiges Beispiel machen):
Fokus automatisiert in die Ortangabe setzen und dort bei Verlassen prüfen, ob ein Wert vorhanden ist, wenn nicht, Msgbox mit Angebot einen Ort einzugeben oder den Incoterm zu wechseln.
Zitat... hatte vorher ein ganz bestimmtes anderes STE den Fokus.
Vielleicht hilft Screen.PreviousControl
Gruß
Josef
Hallo Konrad,
ZitatDas ist etwas nervig, weil mir ja klar ist, dass ich noch was ausfüllen muss, wenn ich per TAB-Tast oder per Maus-Taste in das nächste STE wechsle und dort nun was ausfüllen will.
Es liegt ja bei dir, daß anders zu programmieren und ein entsprechendes Validierungsregelwerk aufzustellen.
In die Fokusbehandlung von Access sollte man nicht ohne Not eingreifen. Wie andere schon angemerkt haben, gehören Validierungen in die Before-Update Ereignisbehandlungsroutine, entweder in des Steuerelements oder des Formulars.
Über das Screen Objekt kannst du in Erfahrung bringen, welches Control vorher den Fokus besaß.
Gruß
Knobbi38
Zitat von: PhilS am November 04, 2024, 08:40:45ist weder benutzerfreundlich
Danke für den Tipp. Kannst du noch genauer beschreiben, warum das benutzerunfreundlich ist, wenn der Datensatz leer ist? Denn wenn ich die Select-Case-Anweisung im BeforeUpdate-Event des jeweiligen Steuerelementes setze, wird sie ja dann dort und zu einem anderen Zeitpunkt ausgeführt. Oder ist sie an dieser benutzerfreundlicher, weil der Datensatz dann erst gar nicht gespeichert und später eventuell gelöscht oder die 0 editiert werden muss?
Zitat von: PhilS am November 04, 2024, 08:40:45Den Datensatz als ganzes, also die Kombination aller Steuerelemente, validiert man am besten im BeforeUpdate-Event des Formulars. In beiden BeforeUpdate-Events kannst du über das Cancel Argument abbrechen und somit verhindern, dass der Benutzer eine ungültige Eingabe speichert.
Viele Dank. Das ist das, was ich gesucht hatte. Das werde ich so umsetzen.
Zitat von: Josef P. am November 04, 2024, 08:57:37Man könnte auch alle anderen Steuerelemente inaktiv setzen, wenn man den User in ein bestimmtes Steuerelement "locken" will.
Das klingt auch interessant. Das ist ein Projekt für später. Jetzt mache ich erst mal die Variante, in der ich das aktive STE im Before-Update-Ereignis des Formulars prüfen.
Zitat von: Josef P. am November 04, 2024, 08:57:37Fokus automatisiert in die Ortangabe setzen und dort bei Verlassen prüfen, ob ein Wert vorhanden ist
Meinst du mit "Ortangabe" den Namen des STE's?
Zitat von: Josef P. am November 04, 2024, 08:57:37den Incoterm zu wechseln.
Meinst du mit Incoterm den Namen des STE's, dass dann den Fokus erhalten soll?
Zitat von: KonradR am November 05, 2024, 06:02:57Kannst du noch genauer beschreiben, warum das benutzerunfreundlich ist,
Messageboxen sind ein einfaches Mittel für den Entwickler, um im Programmcode an der Stelle an der das Programm ein Problem entdeckt den Benutzer darüber zu informieren.
Für den Benutzer sind Messageboxen aber eine Unterbrechung seines gedanklichen und motorischen Ablaufs. Er muss seinen mentalen und motorischen Focus auf die Messagebox verschieben, um diese zu lesen und einen Button dort zu klicken.
Daher sollte man Messageboxen ausschließlich dann einsetzen, wenn es um einen Sachverhalt geht, den man dem Benutzer in genau diesem Moment mitteilen
muss. Also, wenn etwas nicht weitergehen kann, ohne dass der Benutzer sich um ein Problem kümmert, oder wenn man dem Benutzer eine Information liefern möchte, auf die er (vermutlich) in diesem Moment wartet.
Dein ursprünglicher Ansatz mit den MsgBoxen im Exit-Event werden dem Benutzer angezeigt, wenn er nur durch die Steuerelemente navigiert. In diesem Moment also evtl. gar nicht den Anspruch hat, in dem aktuellen oder korrespondierendem Steuerelement etwas einzugeben.
Das BeforeUpdate-Event des Steuerelementes ist da besser geeignet, weil der Benutzer immerhin schon mal eine Änderung an dem Wert des Steuerelementes vorgenommen hat. - Auch hier könnte man überlegen, ob es nicht sinnvoller (benutzerfreundlicher) ist, wenn man das Problem anders kommuniziert, z.B. mit einer farblichen Markierung des/der Steuerelemente(s).
Erst im BeforeUpdate-Event des Formulars ist eine MsgBox (meistens) gerechtfertigt, weil das Programm keinen ungültigen/unvollständigen Datensatz speichern sollte.
Zitat von: PhilS am November 05, 2024, 08:39:57Das BeforeUpdate-Event des Steuerelementes ist da besser geeignet, weil der Benutzer immerhin schon mal eine Änderung an dem Wert des Steuerelementes vorgenommen hat. - Auch hier könnte man überlegen, ob es nicht sinnvoller (benutzerfreundlicher) ist, wenn man das Problem anders kommuniziert, z.B. mit einer farblichen Markierung des/der Steuerelemente(s).
Erst im BeforeUpdate-Event des Formulars ist eine MsgBox (meistens) gerechtfertigt, weil das Programm keinen ungültigen/unvollständigen Datensatz speichern sollte.
Danke für deine ausführliche Erklärung. Das war sehr hilfreich. Also heißt das für mich, dass ich grundlegend versuchen sollte den Einsatz von MSG-Boxen zu vermeiden und eher auf die optische Änderung der STE zu setzen, sofern das überhaupt notwendig ist.
Zitat von: PhilS am November 04, 2024, 08:40:45Den Datensatz als ganzes, also die Kombination aller Steuerelemente, validiert man am besten im BeforeUpdate-Event des Formulars. In beiden BeforeUpdate-Events kannst du über das Cancel Argument abbrechen und somit verhindern, dass der Benutzer eine ungültige Eingabe speichert.
Ich habe jetzt die Prozedur in das Before-Update-Ereignis des Formulars übernommen. Leider passiert da nichts. Die von dir angesprochene optische Anpassung der STE's würde ich noch anpassen. Mir ging es erst mal nur um die Funktionalität. Die beiden STE's sind jeweils ungebunden und die Datensatzänderung, die aufgrund der Änderung der Daten in den benannten STE's passiert habe ich noch nicht eingearbeitet. Kann das ein Grund dafür sein, dass der Code im Before-Update-Ereignis des Formulars nicht angewendet wird?
Hier mein Code:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Select Case True
Case IsNull(Me.txtZugabeMenge.Value) And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge und eine Zugabeinheit eingeben"
Case IsNull(Me.txtZugabeMenge.Value) And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge eingeben"
Case Me.txtZugabeMenge.Value = 0 And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge > 0 und eine Zugabeinheit eingeben"
Case Me.txtZugabeMenge.Value = 0 And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabemenge > 0 eingeben"
' Case Not IsNull(Me.txtZugabeMenge.Value) And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabeeinheit eingeben"
Case Not IsNull(Me.txtZugabeMenge.Value) And Not IsNull(Me.txtZugabeEinheit.Value): MsgBox "SQL-String wird befüllt"
Cancel = True
End Select
End Sub
Zitat von: KonradR am November 07, 2024, 05:43:19Die beiden STE's sind jeweils ungebunden und die Datensatzänderung, die aufgrund der Änderung der Daten in den benannten STE's passiert habe ich noch nicht eingearbeitet.
Das BeforeUpdate-Ereignis des Formulars tritt ein, unmittelbar bevor der Datensatz, der in den gebundenen Steuerelementen angezeigt wird, gespeichert wird. - Ohne Änderung, kein BeforeUpdate.
Wenn die Datenänderungen gar nicht über gebundene Steuerelemente passieren, dass sollte die Prüfung laufen, bevor du anderweitig den Datensatz speicherst. In diesem, für Access eher ungewöhnlichen, Fall ist BeforeUpdate nicht hilfreich.
Beim Einfügen musst du das Form.BeforeInsert Event verwenden.
Also einfach aus beiden Events heraus den Code ansprechen.
Die Prüfung schaut auch eher grauenvoll aus...
Zitat von: markusxy am November 07, 2024, 16:16:59Beim Einfügen musst du das Form.BeforeInsert Event verwenden.
Nicht wirklich. Jedenfalls nicht zum Zweck der Eingabevalidierung.
BeforeInsert tritt ein, wenn in einem neuen, noch leeren Datensatz das allererste Zeichen eingegeben wird. - Viel zu früh für eine sinnvolle Validierung.
BeforeUpdate wird auch bei neuen Datensätzen ausgelöst, wenn der neuen Datensatz gespeichert werden soll.
Zitat von: markusxy am November 07, 2024, 16:16:59Die Prüfung schaut auch eher grauenvoll aus...
Bitte beschreibe das doch etwas genauer. Denn ich finde den Code sehr übersichtlich. Von welchem Standpunkt aus betrachtest du den Code? Wie wäre es denn, wenn der Code deinen Qualitätsanforderungen entspricht?
Hallo Konrad,
ganz einfach, weil für eine Validierung jede Regel geprüft werden muß. Trifft bei einem Select ein Case Fall zu, werden die anderen nicht mehr bearbeitet bzw. geprüft.
Zitat von: knobbi38 am November 08, 2024, 11:37:44Trifft bei einem Select ein Case Fall zu, werden die anderen nicht mehr bearbeitet bzw. geprüft.
Also müsste man das dann mit dem "Or" Operator in einer Zeile Code lösen oder mit der Gültigkeitsregel bzw. Gültigkeitsmeldung für ein Textfeld einer Tabelle lösen, damit alle möglichen Fälle durchlaufen werden?
Im einfachsten Fall für jede Regel ein IF Statement, also
IF Regel1 THEN
...
END IF
IF Regel2 THEN
...
END IF
...
oder man fast eine paar Prüfbedingungen zusammen und kaskadiert das etwas:
IF IsNull(Me.txtZugabeMenge.Value) THEN
IF IsNull(Me.txtZugabeEinheit.Value) THEN
...
ELSE
...
END IF
END IF
Wenn dann noch anstatt eines fixen Textes eine Message_ID verwendet wird, kann der Meldungstext am Ende der IF Blöcke mit dieser Message_ID aus einer Tabelle mit DLookup geladen und ausgegeben werden. So hat man nur noch einen einzelnen Block mit der Meldungsausgabe und nicht verstreut überall 'Msgbox()' im Code. Außderdem können die Texte so in den "Stammdaten" angepaßt werden, ohne das der Code neu angefasst werden muß.
Grüße
Knobbi38
Zitat von: knobbi38 am November 08, 2024, 15:18:24Im einfachsten Fall für jede Regel ein IF Statement, also
Code [Auswählen] Erweitern
IF Regel1 THEN
...
END IF
IF Regel2 THEN
...
END IF
...
Dann wird wirklich jeder Fall durchlaufen. Der einzige Nutzen davon erschließt sich für mich, dass wenn mehrere Regeln erfüllt sind, am Ende eine MSG-Box alle Regeln oder Fehleingaben für den Nutzer aufzeigt und er nicht jeden Fehler einzeln abarbeiten muss. Ist das der Nutzen von diesem Vorgehen?
Zitat von: knobbi38 am November 08, 2024, 15:18:24Wenn dann noch anstatt eines fixen Textes eine Message_ID verwendet wird, kann der Meldungstext am Ende der IF Blöcke mit dieser Message_ID aus einer Tabelle mit DLookup geladen und ausgegeben werden
Da werde ich mal drüber nachdenken. Allerdings sind die MSG-Boxen dann isoliert vom Code irgendwo zentral angeordnet. Diese dann zuzuordnen braucht auch wieder Zeit. Es sei denn es wird eindeutig kommentiert. Spart das so viel Zeit in der Wartung?
Hallo Konrad,
wichtig ist doch, daß alle Regeln mit einbezogen werden müssen. Es kann aber durchaus auch eine Priorisierung geben, nach dem Motto, wenn diese Regel nicht erfüllt ist, brauchen die anderen sowieso nicht mehr geprüft werden.
Neben den einfachen IF Blöcken stehen auch noch weiterhin die Werkzeuge IF-THEN-ELSEIF und SELECT-CASE zur Verfügung. Wie du das geschickt umsetzt, bleibt schlichtweg deiner Kreativität überlassen.
ZitatAllerdings sind die MSG-Boxen dann isoliert vom Code irgendwo zentral angeordnet. Diese dann zuzuordnen braucht auch wieder Zeit. Es sei denn es wird eindeutig kommentiert. Spart das so viel Zeit in der Wartung?
Nicht "die MSG-Boxen" sondern nur ein Codesegment mit einer Msgbox, eventuell sogar eine globale Funktion. Da wird auch nichts mehr zugeordnet, sondern die Meldung aus der Tabelle geladen und angezeigt. Dies kann auch erweitert werden, sodass mehrere Meldungstexte ausgegeben werden können. Beispielsweise können die Message-IDs in einer Collection gesammelt und dann die Meldungstexte dazu in einem Rutsch ausgegeben werden.
Gruß
Knobbi38
Zitat von: knobbi38 am November 08, 2024, 22:57:55wichtig ist doch, daß alle Regeln mit einbezogen werden müssen.
Wenn der Nutzer im Before-Update-Ereignis eine Regel erfüllt und eine Meldung oder eine Aktion erfolgt, reicht das doch. Wenn er z.B. nichts in das Feld eingetragen hat und der Wert NULL ist, dann reicht doch eine Meldung "bitte etwas eintragen". Wenn ein oder mehrere Leerzeichen drin sind, dann ist es doch besser, wenn er eine Meldung bekommt, "Es sind Leerzeichen im STE. Bitte eine Zahl außer 0 eintragen." oder so ähnlich erhält. Für jede Fehleingabe die entsprechende Meldung. Es kann nur ein Fall davon auftreten. Daher ist es aus meiner Sicht absolut ok, wenn der Code bei der entsprechenden Regel abbricht und die gewünschte Aktion ausführt.
Zitat von: knobbi38 am November 08, 2024, 22:57:55Beispielsweise können die Message-IDs in einer Collection gesammelt und dann die Meldungstexte dazu in einem Rutsch ausgegeben werden
Ok, dann habe ich die Meldungstexte für die MSG-Boxen in einer globalen Funktion und weis, dass wenn ich den von einer MSG-Box ändern will, dass nur in dieser globalen Function machen kann. Dann muss ich für die Anpassung immer in diese globale Function wechseln. Bei der Übergabe von Werten erscheint mir das sinnvoll, weil ich mir dann den Einsatz von öffentlichen Variablen spare und damit eine Verwechslungsgefahr bzw. Doppelbelegung umgehe, aber in diesem Fall wäre der Meldungstext an einer anderen Stelle. So wie ich es jetzt habe, kann ich ihn direkt an der Codestelle anpassen, wo die Regelprüfung stattfindet. Das erscheint mir komfortabler in der Wartung, weil ich die ID für den Meldungstext in der globalen Function in einem anderen öffentlichen Modul nicht suchen muss.
Hallo Konrad,
hier liegt ein Missverständnis vor. Die Meldungstexte stehen nicht in einer globalen Funktion, sondern die globale Funktion zeigt den zu den MessageID(s) gehörenden Meldungstext an. Die Meldungstexte selber stehen, wir haben immerhin ein Datenbank, natürlich in einer Tabelle mit der MessageID als PK. Du kannst also die Meldungstexte ändern, ohne das der Code neu kompiliert werden muß.
Es ist eine "Good Practice", solche Konstanten nicht im Code selber zu pflegen, sondern zentral in Modulen oder Tabellen. Diese lassen sich besser Warten und ggf. auch austauschen.
Zitat von: knobbi38 am November 09, 2024, 11:27:27Die Meldungstexte selber stehen, wir haben immerhin ein Datenbank, natürlich in einer Tabelle mit der MessageID als PK. Du kannst also die Meldungstexte ändern, ohne das der Code neu kompiliert werden muß
Das habe ich tatsächlich missverstanden. Danke für den Hinweis. Das es natürlich nützlich ist, öfters genutzte Informationen einmal zentral abzulegen, macht für mich absolut Sinn. Dann wird die Information einmal zentral, hier in der Tabelle, einmal geändert und kann dann überall im Projekt verwendet werden. Das ist sehr komfortabel. Allerdings finde ich meinen Code aktuell hier sehr spezifisch auf zwei STE's programmiert. Wenn ich eine weitere Validierungsprüfung in einem anderen Formular mache, könnten auch mehr oder weniger als zwei STE's von der Validierung betroffen sein. Dann könnte ich natürlich den Namen der STE's in Variablen unterbringen und weitere Schleifen, etc. durchlaufen, aber aktuell will ich es mal dabei belassen und behalte es im Hinterkopf. Spätestens, wenn eine weitere Validierung in einem weiteren Formular dazu kommt, werde ich die von dir emfohlene Variante zu Anwendung bringen. Aktuell habe ich die Empfehlung von Phils eingearbeitet und den Code im Before-Update-Ereignis des Formulars untergebracht. Das funktioniert sehr gut, wie hier zu sehen:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Select Case True
Case IsNull(Me.txtZugabeMenge.Value) And IsNull(Me.txtZugabeEinheit.Value)
MsgBox "Es sind Leerzeichen in den Textfeldern ""Zugabemenge"" und ""Zugabeeinheit""" & vbCrLf & _
"Bitte in beide Felder einen Wert eintragen."
Cancel = True
Case IsNull(Me.txtZugabeMenge.Value) And Me.txtZugabeEinheit.Value <> ""
MsgBox "Es sind Leerzeichen im Textfeld ""Zugabemenge"". Bitte einen Wert eintragen."
Cancel = True
Case IsNull(Me.txtZugabeMenge.Value) And Not IsNull(Me.txtZugabeEinheit.Value)
MsgBox "Bitte eine Zugabemenge eingeben"
Cancel = True
Case Me.txtZugabeMenge.Value = 0 And IsNull(Me.txtZugabeEinheit.Value)
MsgBox "Bitte eine Zugabemenge > 0 und eine Zugabeinheit eingeben"
Cancel = True
Case Me.txtZugabeMenge.Value = 0 And Not IsNull(Me.txtZugabeEinheit.Value)
MsgBox "Bitte eine Zugabemenge > 0 eingeben"
Cancel = True
' Case Not IsNull(Me.txtZugabeMenge.Value) And IsNull(Me.txtZugabeEinheit.Value): MsgBox "Bitte eine Zugabeeinheit eingeben"
Cancel = True
Case Not IsNull(Me.txtZugabeMenge.Value) And Not IsNull(Me.txtZugabeEinheit.Value)
MsgBox "SQL-String wird befüllt"
Cancel = False
Case Else
Cancel = False
MsgBox "Case Else"
End Select
End Sub
Danke für eure Hilfe. Das hat mich ein großes Stück weiter gebracht. Ok, die Validierung wird natürlich an der Stelle abgebrochen wo die Case-Anweisung zutrifft, weil ich weiter bei der Select-Case-Anwendung geblieben bin. Aber aktuell scheint das für mich ok. Wenn ich einen Fall habe, wo alle Kriterien geprüft werden müssen, werde ich die einzelnen If-Anweisungen für jede Fallprüfung verwenden.
Nur mal am Rande angemerkt:
Aus meiner Sicht kannst du die komplette Prüfung auf das Folgende reduzieren und verlierst dabei weder Prüfabdeckung noch Informationsgehalt für den Benutzer.
If Nz(Me.txtZugabeMenge.Value,0) > 0 And Not IsNull(Me.txtZugabeEinheit.Value)
MsgBox "SQL-String wird befüllt"
Else
MsgBox "Bitte eine Zugabemenge > 0 und eine Zugabeinheit eingeben"
Cancel = True
End If