DatePicker mit DatumNullWert-Rückgabe

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

      DatePicker mit DatumNullWert-Rückgabe

      Der DateTimePicker kann leider keinen Nullwert im Value-Wert darstellen und an die Datenbank zurückspeichern. Das habe ich wie folgt gelöst:

      Voraussetzungen für den Code:
      1. Eine Windows-Form foDatum öffnen und im Designer einen MonthCalendar platzieren. Der folgenden Code in die Form einkopieren:

      VB.NET-Quellcode

      1. Public Class foDatum
      2. Private Sub foDatum_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      3. ' Die Varabeln Left und Top müssen vorher als Public-Variabeln geschrieben werden. Left und Top kann nicht im Form_Load beschrieben und gerechnet werden, wenn die Form mit form.ShowDialog() geöffnet wird
      4. Me.Left = vfoDatumLeft
      5. Me.Top = vfoDatumTop
      6. Me.Width = 237
      7. Me.Height = 201
      8. End Sub
      9. Private Sub MonthCalendar1_DateSelected(sender As Object, e As DateRangeEventArgs) Handles MonthCalendar1.DateSelected
      10. vDatumsWahl = e.Start.ToShortDateString()
      11. Me.Close()
      12. End Sub
      13. Private Sub MonthCalendar1_KeyDown(sender As Object, e As KeyEventArgs) Handles MonthCalendar1.KeyDown
      14. If e.KeyCode = Keys.Escape Then
      15. vDatumsWahl = Nothing
      16. Me.Close()
      17. End If
      18. End Sub
      19. End Class




      2. Ein DataGridView ist initialisiert und mit einer DB-Connection verbunden. Das könnte in etwa so aussehen (es sind nicht alle Variablen definiert):

      VB.NET-Quellcode

      1. Public dbConn As New OleDbConnection
      2. Public daRes As New OleDbDataAdapter
      3. Public dvRes As New DataView
      4. Public dtRes As New DataTable
      5. Public dsRes As New DataSet
      6. Public bsRes As New BindingSource
      7. Public drvRes As DataRowView = Nothing
      8. dbConn.ConnectionString = "PROVIDER=Microsoft.ACE.OLEDB.12.0; Data Source=" + ACCESS-Datenbank-Pfad und Name
      9. dbConn.Open()
      10. daRes = New OleDbDataAdapter("SELECT " & sqlSelect & " FROM " & sqlFrom & " WHERE " & sqlWhere & " ORDER BY " & sqlOrder, dbConn)
      11. Dim cbRes As New OleDbCommandBuilder(daRes)
      12. dtRes = New DataTable("Ressourcen")
      13. daRes.Fill(dtRes)
      14. dbConn.Close()
      15. Dim bsRes As New BindingSource
      16. dvRes = New DataView(dtRes)
      17. bsRes.DataSource = dvRes
      18. DataGridView.DataSource = bsRes


      Beim Click auf eine Zeile des DataGridView wird das DataRowView drvRes initialisiert und mit Daten gefüllt. Diese Daten werden anschliessend in Textfeldern bearbeitet und jeweils per Code zurückgeschrieben, wie das Beispiel unten zeigt. Auf diese Weise habe ich die volle Kontrolle, was wie in die DB zurückgeschrieben wird.

      VB.NET-Quellcode

      1. drvRes = dvRes(grRes.CurrentRow.Index)


      Der Aufruf erfolgt auf diese Weise:

      VB.NET-Quellcode

      1. Private Sub btResDatum_Click(sender As Object, e As EventArgs) Handles btResDatum.Click ' ein Button sonstwo in der Form
      2. teResDatum.Text = DatumsWahl(Me.Left + 95, Me.Top + 500) ' teResDatum.text ist das Textfeld, in welches das Datum zurückgeschrieben wird, die Positionen Left & Top werden mitgegeben, damit der DatePicker am richtigen Ort erscheint. Leider sind zusätzliche Anpassungen unumgänglich
      3. If vNeuRB = False Then ' hier wird geprüft, ob ein neuer Datensatz in der Datenbank geschrieben oder ein aktueller Datensatz verändert werden soll, die vNeuRB-Variable wird gesetzt, wenn ein neuer Datensatz geschrieben werden soll
      4. drvRes.BeginEdit()
      5. If IsDate(teResDatum.Text) = False Then
      6. drvRes("Datum") = DBNull.Value ' Damit wird der Nullwert an die Datenbank-Zwischenspeicherung übergeben
      7. teResDatum.Text = "__.__.____" ' Das Masken-Textfeld muss wieder zurückgeschrieben werden auf die
      8. Else
      9. drvRes("Datum") = teResDatum.Text ' Hier wird der gewählte Datumswert übergeben
      10. End If
      11. drvRes("WriteDate") = Now() ' Hier wird das aktuelle Änderungsdatum für den Datensatz übergeben
      12. drvRes.EndEdit()
      13. Call ResChangeFields() ' Aufruf der definitiven Speicherung in die Datenbank
      14. teResDatum.SelectAll() ' Das Datum wird markiert, falls etwas von Hand geändert werden soll
      15. End If
      16. End Sub
      17. Public Function DatumsWahl(ByVal xPos As Integer, ByVal yPos As Integer)
      18. vfoDatumLeft = xPos
      19. vfoDatumTop = yPos
      20. foDatum.ShowDialog()
      21. DatumsWahl = vDatumsWahl
      22. End Function
      23. Public Sub ResChangeFields()
      24. Dim dt1Res As DataTable = dtRes.GetChanges()
      25. If dt1Res IsNot Nothing Then
      26. Try
      27. If dbConn.State = ConnectionState.Closed Then dbConn.Open()
      28. daRes.Update(dt1Res)
      29. dtRes.AcceptChanges()
      30. If dbConn.State = ConnectionState.Open Then dbConn.Close()
      31. Catch ex As System.Exception
      32. MessageBox.Show(ex.Message, "Speichern fehlgeschlagen!", MessageBoxButtons.OK, MessageBoxIcon.Information)
      33. dtRes.RejectChanges()
      34. If dbConn.State = ConnectionState.Open Then dbConn.Close()
      35. End Try
      36. End If
      37. End Sub


      Schlusskommentar: Vermutlich wäre vieles einfacher möglich. Ich bin mit diesem Weg durchaus zufrieden :)