Problem mit Überprüfung einer Datumseingabe

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von Lightsource.

    Problem mit Überprüfung einer Datumseingabe

    Hallo zusammen,

    Bei folgendem Problem finde ich als Neueinsteiger nicht die passende Syntax: In einer Inputbox soll ein Datum (Format tt.mm.jjjj) zwischen 1950 und 2050 eingegeben werden. Als Zeichen dürfen in dem zu prüfenden Eingabetext also nur Ziffern und Punkte vorkommen. Kann mir jemand helfen, wie ich das überprüfen kann. Ich stelle mir eine Schleife vor, in der die 10 Zeichen (bei mehr oder weniger Zeichen stimmt das Format eh nicht) darauf überprüft werden, ob sie zu den erlaubten Zeichen gehören.

    Zum Beispiel: Wenn Zeichen(n) nicht in "0123456789." oder "0","1","2", ... dann DatumOK = false

    Ich habe schon viel geblättert und gesucht, finde aber kein Beispiel für eine solche Abfrage. Die weiteren Prüfungen traue ich mir dann schon zu.

    Danke für entsprechende Tipps oder Beispiele

    MfG ViBaGelmo
    Ich würde gleich ein CDate-Objekt erstellen und ggf. eine Exception werfen.

    VB.NET-Quellcode

    1. Dim txt As String = "10.05.2010"
    2. Dim dd As Date = CDate(Nothing)
    3. Try
    4. dd = New Date(CInt(txt.Substring(6, 4)), _
    5. CInt(txt.Substring(3, 2)), _
    6. CInt(txt.Substring(0, 2)))
    7. Catch ex As Exception
    8. ' Meldung
    9. End Try

    Das setzt natürlich die richtige Schreibweise voraus, "10.5. 2010" ginge hier schon schief.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich bin zwar selber noch neu auf diesem Gebiet, aber ich glaube das wäre in etwa so wie du es dir vorstellst. Eine Kombination aus einer for - Schleife der mid() und der instr() Funktion. Funktioiniert bei mir einwandfrei.



    VB.NET-Quellcode

    1. For i = 1 To 10
    2. c = Mid(datum, i, 1)
    3. If InStr(1, "0123456789.", c, vbTextCompare) = 0 Then
    4. datumOK = False
    5. MsgBox "Es ist ein ungültiges Zeichen bei der Eingabe aufgetreten: " & c
    6. GoTo ende
    7. End If
    8. Next i


    viel Erfolg
    Hallo zusammen

    Danke für die interessanten Tipps und Code-Beispiele. Die Funktion "InStr()" leistet ganz genau das, was ich gesucht habe. Die Regex-Variante konnte ich gar nicht nachvollziehen, das scheint mir eher ein Thema für Informatik-Studenten zu sein, nichts für Einsteiger und Hobby-Programmierer :S

    Mit der Lösungshilfe von Crashed konnte ich die Überprüfungsroutine vervollständigen. Mein Programm funktioniert jetzt einwandfrei und ist so weit fertig.
    Nochmals vielen Dank,

    mfG Gelmo

    P.S. Es wäre schön, wenn man sein abgeschlossenes Programm auf einfache Weise unter neuem Namen abspeichern könnte, um dann weitere Funktionen hinzufügen zu können, ohne die stabile Version zu gefährden, falls bei der Weiterentwicklung Probleme auftauchen. Ich habe nach entsprechenden Hinweisen gesurft, hatte aber mit den gefundenen Lösungen noch keinen Erfolg. Aber das ist wohl besser Gegenstand eines neuen Beitrags.
    Das wird ViBaGelmo nach seinem 100. Beitrag zu würdigen wissen.
    Warum einfach wenn es noch einfacher geht?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo zusammen,

    die Beiträge zu meiner ursprünglichen Anfrage widerspiegeln mein Problem. Als Seiteneinsteiger von Delphi (Turbo Delphi 2006 Explorer) habe ich schon eine Vorstellung von der Entwicklung eines Programmes. Die Suche nach VB-Funktionen, die den mir bekannten Delphi-Funktionen entsprechen, ist bisher aber sehr mühsam, und ich hoffe durch Anfragen in diesem Forum schneller voranzukommen.

    So helfen mir Beiträge wie der von Crashed mehr als etwa der Kommentar von Kangaroo, aus dem niemand entnehmen kann, wie der kritisierte Code verbessert werden kann (ich meine jetzt für mich und andere zum Lernen :S )

    IsDate() wäre auch gegangen, aus Übungsgründen wollte ich die Prüfroutine aber genauer anlegen und habe mehrere MessageBoxen angelegt, die dem Nutzer rückmelden, wo genau ein Eingabefehler gemacht wurde.

    Allen vielen Dank für die guten und wohlmeinenden Tipps.

    MfG ViBaGelmo
    Wenn Du in Deiner Anfrage dieses geschrieben hättest und einen Codeschnipsel gepostet hättest, hättest Du gleich qualifiziertere Antworten bekommen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ViBaGelmo schrieb:

    So helfen mir Beiträge wie der von Crashed mehr als etwa der Kommentar von Kangaroo, aus dem niemand entnehmen kann, wie der kritisierte Code verbessert werden kann

    Da hast Du bestimmt Recht, allerdings wirst Du hier oft finden dass Antworten nicht in Form von vollständigem Code (Cut & Paste) sondern in Form von Ansätzen gegeben werden, die (hoffentlich) dem Wissen des Fragenden angepasst sind. Schliesslich soll der Poster ja selber noch etwas Eigeninitiative zeigen, statt nur Gib mir , Gib mir zu schreien. Nicht auf Dich bezogen , eher wie hier

    Gute Tipps bekommt man auch, wenn man zeigt wie man es selber geplant hat und nach Verbesserungen fragt . Es ist erstaunlich wieviele Möglichkeiten .NET bietet , da lernt jeder (ich auch) dazu ...

    Zu meiner Bemerkung über den Code von Crash:
    Wie alle Funktionen die im Namespace Microsoft.VisualBasic sind Instr und Mid alte VB6 Überbleibsel, die nur aus Kompatibilitätsgründen noch in .NET geführt werden. Diese sollte man wirklich nur noch in Ausnahmefällen verwenden und die entsprechenden .NET Methoden nutzen:

    Schau Dir die String-Methoden einmal an:
    - statt Instr nimm lieber .Contains
    - ersetze Mid durch IndexOf oder Substr
    Ausserdem kann man jeden String als Array von Chars ansprechen, so gibt Textbox1.Text(0) z.B. den 1. Character der Textbox zurück (wenn er existiert).

    ... und der Gebrauch von GoTo löst hier halt immer heftigste Schockwellen aus, deren Behandlung von Baldrian bis zu Wiederbelebungsversuchen reichen kann :rolleyes:

    Es wäre übrigens schön , wenn Du die Lösung Deines Problems mal posten würdest. Meiner Meinung nach musst Du mehrere Tips von hier umsetzen:
    a) wenn Du schon bei der Eingabe dem Benutzer Hilfestellung geben möchtest, so kannst Du das Textbox.KeyPressed Event benutzen um unzulässige Eingaben zu unterdrücken:

    VB.NET-Quellcode

    1. Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
    2. ' zulässiger char ?
    3. If "01234567890.".Contains(e.KeyChar) Then Return
    4. ' Taste unterdrücken
    5. e.Handled = True
    6. End Sub

    b) dennoch wirst Du am Ende der Eingabe (Textbox1.LostFocus Event) nicht eine nochmalige Prüfung (z.B. mit isDate) vermeiden können, oder ist die Eingabe von "......." ein zulässiges Datum ?

    @Rod /sign
    Hallo Kangaroo,

    mit diesem Beitrag habe ich mich etwas länger beschäftigt. Anbei poste ich die Funktion, die die Datumseingebe überprüft. Darin habe ich die von dir gemachten Funktionen verwendet und schon eine bessere Vorstellung von der .net-"Philosophie" bekommen. Den Quellcode kann ich noch nicht nachvollziehen:
    - Return gibt das Zeichen (e.Keychar) nur zurück, wenn die Bedungung erfüllt ist?
    - Vermutlich passiert gar nichts, wenn die Bedingung nicht erfüllt ist?
    - Ich kann mir vorstellen, was e.handled = true bedeutet, aber was passiert, wenn das nicht angegeben wird.

    Vielen Dank für die Unterstützung

    Hier die Prüffunktion:

    VB.NET-Quellcode

    1. Private Function DatTextTest(ByVal TDatum As String) As Boolean
    2. Dim ui, lg As Byte
    3. Dim hz, mz As Short
    4. Dim hd As String
    5. lg = TDatum.Length
    6. If lg <> 10 ThenMessageBox.Show("Bitte ein korrektes Datum eingeben" + vbCrLf + "(im Format 'TT.MM.JJJJ') oder Eingabe abbreichen!")
    7. Return False
    8. Exit Function
    9. ElseFor ui = 1 To lg
    10. If Not (DatZeichen.Contains(TDatum(ui - 1))) ThenMessageBox.Show("Das eingegebene Datum enthält unzulässige Zeichen." + vbCrLf + "Bitte ein korrektes Datum eingeben oder die Eingabe abbrechen!")
    11. Return False
    12. Exit Function
    13. End If
    14. Next
    15. End If
    16. If (TDatum(2) <> ".") Or (TDatum(5) <> ".") ThenMessageBox.Show("Das eingegebene Datum ist fehlerhaft formatiert." + vbCrLf + "Bitte ein korrektes Datum eingeben oder die Eingabe abbrechen!")
    17. Return False
    18. Exit Function
    19. End If
    20. hz = TDatum.Substring(6, 4)
    21. If (hz < 1583) Or (hz > 2100) ThenMessageBox.Show("Das Datum muss zwischen 1583 und 2100 liegen!" + vbCrLf + "Bitte ein korrektes Datum eingeben oder die Eingabe abbrechen!")
    22. Return False
    23. Exit Function
    24. End If
    25. hz = TDatum.Substring(3, 2)
    26. If (hz < 1) Or (hz > 12) ThenMessageBox.Show(hz.ToString + " ist ein ungültiger Monatswert im Datum" + vbCrLf + "Bitte ein korrektes Datum eingeben oder die Eingabe abbrechen!")
    27. Return False
    28. Exit Function
    29. End IfDim hs As String = hz.ToString.PadLeft(2, "0")hd = "01." + hs + "." + TDatum.Substring(6, 4)
    30. mz = TageImMonat(hd) ' Berechnet die Tage im aktuellen Monat
    31. hz = Mid(TDatum, 1, 2)
    32. If (hz < 1) Or (hz > mz) ThenMessageBox.Show(hz.ToString + " ist ein ungültiger Tageswert im Datum" + vbCrLf + "Bitte ein korrektes Datum eingeben oder die Eingabe abbrechen!")
    33. Return False
    34. Exit Function
    35. End If
    36. Return True
    37. End Function


    Es gibt bestimmt eine VB-Funktion, die die Monatstage berechnet (Zeile 30). Da ich sie nicht gefunden habe, musste ich sie selbst schreiben. Ich hoffe, der Code ist nicht zu lang. Die im Originalquelltext vorhandenen Einrückungen sind leider in der Vorschau nicht vorhanden.

    Letzte Anmerkung: Die Funktion läßt nun Jahreszahlen von 1583 (1582 wurde der gregorianische Kalender eingeführt) und 2100 zu. In meinem Programm wird der Monat angezeigt, in dem das eingegebene Datum liegt.

    MfG ViBaGelmo
    Hallo,

    TDatum.SubString(6, 4) enthält die Zeichen 7 bis 10 von TDatum, beim heutigen Datum "22.10.2010" also "2010". Offensichtlich beginnt die Zählung wie bei Arrays mit 0. Nachdem ich die zweite Codezeile eingefügt habe, verhält sich das Programm völlig identisch. Ich hielt das für ein Zeichen der Flexibilität von VB, dass auf die Weise in Zeile 1 ein String in eine Zahl umgewandelt werden kann (Versuchsweise klappte sogar hz = "3.5") .


    VB.NET-Quellcode

    1. hz = TDatum.Substring(6, 4)
    2. hz = Val(TDatum.Substring(6, 4))



    MfG ViBaGelmo