Eingabe umwandeln / verifizieren

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von TS71M.

    Eingabe umwandeln / verifizieren

    Hallo Leute,

    Ich habe ein Datagridview mit mehreren Spalten und ein typisiertes Dataset dahinter. Funktioniert alles.
    Die beiden Spalten "Start time' und 'end time' sind datetime spalten.
    nun folgende zwei Aufgaben ;)
    1. Bei Eingabe einer neuen Zeit setzt er automatisch das Datum auf heute. Das bedeutet ich gebe 6:00 ein und in der db kommt 29/04/2016 06:00:00 ein.
      Wie kann ich verhindern, dass er das Datum ändert; oder wie gebe ich das dazugehörige Datum vor?
    2. es nervt 6:00 immer als sechs, Doppelpunkt, null, null eingeben zu müssen. Ich würde gerne es so machen, dass wenn der User nur eine ein- oder zweistellige Zahl eingibt, dass dies immer Stunden sind (also 14 => 14:00) und wenn mehr als zwei Stellen dann ist alles ab der 2. Stelle Minuten (1423 => 14:23).
    Vielen Dank schon mal für alle Ratschläge und Hilestellungen.
    Bilder
    • TaskPlanner.jpg

      87,33 kB, 928×197, 164 mal angesehen
    @TS71M
    zu 1.:

    VB.NET-Quellcode

    1. Dim dt = DateTime.Now.Date
    2. MessageBox.Show(dt.ToString)
    3. Dim ts = New TimeSpan(11, 55, 33)
    4. dt = dt.Add(ts)
    5. MessageBox.Show(dt.ToString)

    zu 2.: Sieh Dir mal das DataGridView.Validating-Event an.
    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!
    Im DGV_CellParsing - Event kann man beliebige Umwandlungs-Funktionen reinbasteln - Da kannst du auch hinbasteln, dass aus 12345 die Uhrzeit 12:34:05 wird.

    TS71M schrieb:

    wie gebe ich das dazugehörige Datum vor?
    Die Frage ist: Was ist das "dazugehörige Datum"?
    Soll der User das Datum nicht ändern können?
    Aber ein Datum soll doch drinne stehen, oder?
    Wie soll das Datum hineinkommen?
    Also ich hab da jetzt mal was zusammengebastelt, was zwar funzt, ich mir aber denke, dass dies wahrscheinlich viel einfacher ginge ?(

    VB.NET-Quellcode

    1. Private Sub dgvTaskPlanning_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs) Handles dgvTaskPlanning.CellParsing
    2. If e.RowIndex < 0 AndAlso e.RowIndex > dgvTaskPlanning.RowCount - 2 Then Return
    3. If e.ColumnIndex <> dgvtbcStartTime.Index AndAlso e.ColumnIndex <> dgvtbcEndTime.Index Then Return
    4. Try
    5. Dim str As String = e.Value.ToString
    6. Dim ts As New TimeSpan
    7. Dim h, m As New Integer
    8. Select Case IsDate(e.Value)
    9. Case True
    10. If CDate(e.Value).Date <> dtpGlobalDate.Value.Date Then
    11. Dim d As Date = CDate(e.Value)
    12. h = d.Hour
    13. m = d.Minute
    14. End If
    15. Case False
    16. Select Case str.Length
    17. Case 0 To 2
    18. If CInt(e.Value) > 24 Then : MessageBox.Show("No values greater than 23 for hours") : e.ParsingApplied = False : End If
    19. h = CInt(e.Value)
    20. m = 0
    21. Case 3
    22. h = CInt(str.Substring(0, 1))
    23. m = CInt(str.Substring(1, 2))
    24. If m > 59 Then : MessageBox.Show("No values greater than 59 for minutes") : e.ParsingApplied = False : End If
    25. Case 4
    26. h = CInt(str.Substring(0, 2))
    27. m = CInt(str.Substring(2, 2))
    28. Case Else
    29. MessageBox.Show("No valid time. Please change.", "Enter Time")
    30. e.ParsingApplied = False
    31. End Select
    32. End Select
    33. ts = New TimeSpan(h, m, 0)
    34. e.Value = dtpGlobalDate.Value.Date.Add(ts)
    35. e.ParsingApplied = True
    36. Catch ex As Exception
    37. e.ParsingApplied = False
    38. End Try
    39. If Not e.ParsingApplied Then MessageBox.Show("Parsing not successful", "Enter Time")
    40. End Sub


    Vorschläge? ;)
    jo, sehr gut!

    meins ist bisserl knapper, aber auch weil meine Parse-Aktion sehr simpel ist:

    VB.NET-Quellcode

    1. Private Sub ItemDataGridView_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs) Handles ItemDataGridView.CellParsing
    2. If e.ColumnIndex <> 1 Then Return
    3. Try ' im Fehlerfall greift das Standard-Parsing, mit seiner Fehler-Meldung
    4. Dim dt = CDate(ItemDataGridView(e.ColumnIndex, e.RowIndex).Value).Date
    5. Dim s = e.Value.ToString
    6. Dim numbs = {Integer.Parse(s.Substring(0, 2)), Integer.Parse(s.Substring(2))}
    7. e.Value = dt + New TimeSpan(numbs(0), numbs(1), 0)
    8. e.ParsingApplied = True
    9. Catch ex As Exception
    10. End Try
    11. End Sub
    Halt Select Case True IsDate(e.Value), CDate und Kram sollteste rauswerfen.
    Du kannst versuchen, direkt nach Timespan zu parsen, und wenn das nicht klappt, dann halt die verschiedenen Integers aus dem String elaborieren - da gibts viele Möglichkeiten.
    Der Punkt ist eben, dass - wenn als Timespan nicht parseable, dass dann die Eingabe als Eingabe von Nummern zu lesen versucht wird, und aus den Nummern erzeugt man dann den Timespan.

    Ich hab einfach vorausgesetzt, dass der User bis zu 4 Digits eintippt, aber man kann auch verschiedenste Trennzeichen berücksichtigen und hastenichjesehn.

    Im Fehlerfall setze ich einfach ParsingApplied nicht, das hat zur Folge, dass das DGV zu parsen versucht, und dann kommt ja erwünschterweise der Standard-Fehler zum Zuge.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Super und danke.
    Ich habe das Ganze nun nocht etwas verfeinert und in eine function eingebaut, da ich dies in anderen Forms auch noch nutzen möchte:

    VB.NET-Quellcode

    1. Public Shared Function ParseTimeEnter(val As Object, dptGlobal As DateTimePicker) As Date
    2. Try
    3. Dim dt = dptGlobal.Value.Date
    4. Dim s = val.ToString
    5. Dim numbs(1) As Integer
    6. Select Case s.Length
    7. Case 1
    8. numbs = {Integer.Parse(s.Substring(0, 1)), 0}
    9. Case 2
    10. numbs = {Integer.Parse(s.Substring(0, 2)), 0}
    11. Case 3
    12. numbs = {Integer.Parse(s.Substring(0, 1)), Integer.Parse(s.Substring(1))}
    13. Case 4
    14. numbs = {Integer.Parse(s.Substring(0, 2)), Integer.Parse(s.Substring(2))}
    15. Case Else
    16. Return Nothing
    17. End Select
    18. Return dt + New TimeSpan(numbs(0), numbs(1), 0)
    19. Catch ex As Exception
    20. Return Nothing
    21. End Try
    22. End Function
    23. End Class


    und im Event:

    VB.NET-Quellcode

    1. If e.ColumnIndex <> dgvtbcStartTime.Index AndAlso e.ColumnIndex <> dgvtbcEndTime.Index Then Return
    2. e.Value = clTask.ParseTimeEnter(e.Value, dtpGlobalDate)
    3. e.ParsingApplied = If(e.Value Is Nothing, False, True)


    Somit wandelt er alles bis 4 Stellen um:
    5 => 5:00
    17=> 17:00
    537 => 5:37
    1421=> 14:21
    :thumbsup:
    Super - Wiederverwendbarkeit macht guten Code aus!

    Die Methode sollte imo kein DateTimePicker-Argument verlangen, sondern einfach ein Date - ist flexibler.


    Hmm - das 2. Arg kann sogar ganz weggelassen werden:

    VB.NET-Quellcode

    1. Private Sub ItemDataGridView_CellParsing(sender As Object, e As DataGridViewCellParsingEventArgs) Handles ItemDataGridView.CellParsing
    2. If e.ColumnIndex <> 1 Then Return
    3. Dim ts = TimeParseSpecial(e.Value.ToString)
    4. If ts = TimeSpan.MinValue Then Return
    5. e.Value = dtpGlobalDate.Value.Date + ts
    6. If e.ParsingApplied = True Then
    7. End Sub
    8. ''' <summary> returnt bei Fehlschlag Timespan.MinValue </summary>
    9. Public Shared Function TimeParseSpecial(txt As String) As TimeSpan
    10. Try
    11. Dim numbs() As Integer
    12. Select Case txt.Length
    13. Case 1
    14. numbs = {Integer.Parse(txt.Substring(0, 1)), 0}
    15. Case 2
    16. numbs = {Integer.Parse(txt.Substring(0, 2)), 0}
    17. Case 3
    18. numbs = {Integer.Parse(txt.Substring(0, 1)), Integer.Parse(txt.Substring(1))}
    19. Case 4
    20. numbs = {Integer.Parse(txt.Substring(0, 2)), Integer.Parse(txt.Substring(2))}
    21. End Select
    22. Return New TimeSpan(numbs(0), numbs(1), 0)
    23. Catch ex As Exception
    24. Return TimeSpan.MinValue
    25. End Try
    26. End Function

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Hey super, wird immer kompakter.
    Einen Einwand hätte ich aber noch

    Bei Eingabe von Stunden grösser 24 würde der Timespan dann Tage enthalten. Addiert man diese zum Datum bekommt man einen anderen Tag und das darf nicht passieren.Deshalb habe ich noch folgendes hinzugefügt:

    VB.NET-Quellcode

    1. If numbs(0) >= 24 Then numbs(0) = 0

    und im Event

    VB.NET-Quellcode

    1. e.ParsingApplied = If(ts = TimeSpan.MinValue, False, True)



    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „TS71M“ ()