none
Wert in Datenbank über DataGridView-Steuerelement löschen RRS feed

  • Frage

  • Ich habe eine SQL Server Compact 3.5 Datenbank. In einer Tabelle dieser Datenbank ist ein Feld mit folgenden Eigenschaften:

    - Datentyp: datetime

    - NULL - Werte zulassen: ja

    Ich zeige diese Tabelle in einem Formular mit einem DataGridView-Steuerelement an. Wenn ich einmal einen Wert in dieses Feld eingegeben habe und dann diesen Wert lösche (Entf-Taste) und die Zelle verlasse, dann erhalte ich eine FormatException.

    Was muss ich machen, damit ich dieses Feld in der Datenbank auf den ursprünglichen (und erlaubten) NULL-Wert bringe, d.h. es ist kein Datum vorhanden? Gibt es Möglichkeiten bei der Eingabe in das Steuerelement? Oder wie kann ich die FormatException-Routine programmieren damit dies gelingt?

    Dienstag, 28. September 2010 07:14

Antworten

  • Hallo Rainer,

    Ich habe eine SQL Server Compact 3.5 Datenbank.
    In einer Tabelle dieser Datenbank ist ein Feld mit
    folgenden Eigenschaften:

    - Datentyp: datetime
    - NULL - Werte zulassen: ja

    Ich zeige diese Tabelle in einem Formular mit einem
    DataGridView-Steuerelement an.

    Zur Lösung Deines Problems sollte man wissen, wie
    die Daten in das DGV kommen.
    Ist das DGV an eine DataTable/DataView gebunden?
    Wenn nicht, wie (Code) sonst kommen die Daten ins
    DGV?

    Wenn ich einmal einen Wert in dieses Feld eingegeben
    habe und dann diesen Wert lösche (Entf-Taste)

    ... dann hast Du in einer DataGridViewTextBoxCell kein
    gültiges Datum, sondern einen String der Länge 0 ("")
    stehen. Ein solcher String ist nun mal kein Datum und auch
    kein DBNull.Value.

    und die Zelle verlasse, dann
    erhalte ich eine FormatException.

    ... weil ein "" eben nicht zu einem gültigen Datumswert
    umgewandelt werden kann.

    Was muss ich machen, damit ich dieses Feld in der Datenbank
    auf den ursprünglichen (und erlaubten) NULL-Wert bringe,
    d.h. es ist kein Datum vorhanden? Gibt es Möglichkeiten
    bei der Eingabe in das Steuerelement?
    Oder wie kann ich die FormatException-Routine programmieren
    damit dies gelingt?

    s.oben:
    Das kommt darauf an, ob Dein DGV z.B. an eine DataTable resp.
    DataView gebunden ist

        DGV.DataSource = EineDataTable
        DGV.DataSource = EineDataView
    oder
        DGV.DataSource = EinAnderesObjektMit IListSchnittstelle

    oder ob Du Deinem DGV Rows via DGV.Rows.Add() übergeben
    hast.

    Hier mal ein Beispiel mit einem an eine DataTable/Bindingsource
    gebundenes DataGridView.

    Kopiere den nachfolgenden Code in ein leeres Formmodul (Form1.vb)

    ' / Beginn Code
    Public Class Form1

        Private mDT As DataTable
        Private WithEvents mBS As BindingSource
        Private WithEvents DGV As DataGridView
        Private WithEvents TB As TextBox

        Private Sub Form1_Load _
                (ByVal sender As System.Object, _
                 ByVal e As System.EventArgs _
                ) Handles MyBase.Load

            DGV = New DataGridView
            With DGV
                .Name = "DGV"
                .Dock = DockStyle.Fill
                .DefaultCellStyle.Font = New Font("Arial", 12)

                .ColumnHeadersDefaultCellStyle.Font = _
                        New Font("Arial", 8, FontStyle.Bold)
            End With
            Me.Controls.Add(DGV)

            CreateData()

            With DGV
                .DataSource = mBS

                .Columns(0).DefaultCellStyle.Alignment = _
                        DataGridViewContentAlignment.MiddleRight

                .Columns(2).DefaultCellStyle.Alignment = _
                        DataGridViewContentAlignment.MiddleCenter

                .AutoResizeColumns()
            End With
        End Sub

        Private Sub CreateData()
            Dim Rnd As New Random
            Dim i As Integer
            Dim DR As DataRow
            Dim DC As DataColumn
            Dim Names() As String = _
                    New String() _
                    {"Anna", "Fritz", "Karl", "Maria", _
                     "Leo", "Walter", "Klara"}

            mDT = New DataTable
            With mDT
                DC = .Columns.Add("ID", GetType(Integer))
                DC.AllowDBNull = False
                DC.Unique = True

                .Columns.Add("Text", GetType(String))

                DC = .Columns.Add("Datum", GetType(Date))
                DC.AllowDBNull = True
                DC.DefaultValue = DBNull.Value

                For i = 0 To Names.GetUpperBound(0)
                    DR = .NewRow
                    DR.Item("ID") = i
                    DR.Item("Text") = Names(i)
                    DR.Item("Datum") = _
                        New Date _
                        (Rnd.Next(1950, 1990), _
                         Rnd.Next(1, 13), _
                         Rnd.Next(1, 29))

                    .Rows.Add(DR)
                Next
                .AcceptChanges()
            End With

            mBS = New BindingSource
            mBS.DataSource = mDT
        End Sub

        Private Sub DGV_CellValidating _
            (ByVal sender As Object, _
             ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs _
            ) Handles DGV.CellValidating

            If e.ColumnIndex = 2 Then

                If Not DGV.CurrentRow.IsNewRow Then

                    Dim D As Date

                    Dim Buffer As String = _
                            DGV.CurrentCell.EditedFormattedValue.ToString

                    Select Case True
                        Case Buffer = ""
                            ' Bei Leerstring auf DBNull.Value setzen
                            DGV.CurrentCell.Value = DBNull.Value
                        Case Date.TryParse(Buffer, D)
                            ' gültiges Datum, keine Reaktion erforderlich
                        Case Else
                            MsgBox _
                                    (Chr(39) & Buffer & _
                                     "' ist kein gültiges Datum!", _
                                     MsgBoxStyle.Exclamation)

                            e.Cancel = True
                    End Select
                End If
            End If

        End Sub

        Private Sub mBS_PositionChanged _
                (ByVal sender As Object, _
                 ByVal e As System.EventArgs _
                ) Handles mBS.PositionChanged

            ShowDateCellValue()
        End Sub

        Private Sub ShowDateCellValue()
            Select Case mBS.Position
                Case Is > 0, Is < DGV.RowCount - 1
                    Dim D As Object = _
                        DirectCast(mBS.Current, DataRowView).Item(2)

                    Me.Text = "Datum: "
                    If D Is DBNull.Value Then
                        Me.Text &= "DBNull.Value"
                    Else
                        Me.Text &= CDate(D)
                    End If

                Case Else
                    Me.Text = Me.Name
            End Select
        End Sub

    End Class
    ' \\\ E N T E

    Nach dem Programmstart siehst Du die Form1 mit einem DataGridView
    in dem einige Datenzeilen gezeigt werden.
    In Zellen der Spalte Datum können gültige Datumswerte eingetragen
    werden oder diese Zellen können gelöscht (Leerstring) sein.
    Im Falle von Leerstring ("") wird in Sub DGV_CellValidating()
    in jedem Fall in das Datumsfeld der Wert DBNull.Value eingetragen.
    Dies löst keinen Fehler aus, da in Sub CreateData() mit

        DC.AllowDBNull = True

    für die Datumsspalte Null-Werte (DBNull.Value) erlaubt worden sind.

    Gruß aus St.Georgen
    Peter Götz
    www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

    • Als Antwort markiert Rainer Walesch Dienstag, 28. September 2010 15:24
    Dienstag, 28. September 2010 11:27

Alle Antworten

  • Hallo Rainer,

    es gibt da so ein DefaultCellStyle, den man belegen kann.

    Me.dataGridView1.DefaultCellStyle.NullValue = "01.01.1900"
    
    Ich denke das könnte passen.
    Please 'Mark as Answer' if I helped. This helps others who have the same problem!
    Dienstag, 28. September 2010 10:13
  • Hallo Rainer,

    Ich habe eine SQL Server Compact 3.5 Datenbank.
    In einer Tabelle dieser Datenbank ist ein Feld mit
    folgenden Eigenschaften:

    - Datentyp: datetime
    - NULL - Werte zulassen: ja

    Ich zeige diese Tabelle in einem Formular mit einem
    DataGridView-Steuerelement an.

    Zur Lösung Deines Problems sollte man wissen, wie
    die Daten in das DGV kommen.
    Ist das DGV an eine DataTable/DataView gebunden?
    Wenn nicht, wie (Code) sonst kommen die Daten ins
    DGV?

    Wenn ich einmal einen Wert in dieses Feld eingegeben
    habe und dann diesen Wert lösche (Entf-Taste)

    ... dann hast Du in einer DataGridViewTextBoxCell kein
    gültiges Datum, sondern einen String der Länge 0 ("")
    stehen. Ein solcher String ist nun mal kein Datum und auch
    kein DBNull.Value.

    und die Zelle verlasse, dann
    erhalte ich eine FormatException.

    ... weil ein "" eben nicht zu einem gültigen Datumswert
    umgewandelt werden kann.

    Was muss ich machen, damit ich dieses Feld in der Datenbank
    auf den ursprünglichen (und erlaubten) NULL-Wert bringe,
    d.h. es ist kein Datum vorhanden? Gibt es Möglichkeiten
    bei der Eingabe in das Steuerelement?
    Oder wie kann ich die FormatException-Routine programmieren
    damit dies gelingt?

    s.oben:
    Das kommt darauf an, ob Dein DGV z.B. an eine DataTable resp.
    DataView gebunden ist

        DGV.DataSource = EineDataTable
        DGV.DataSource = EineDataView
    oder
        DGV.DataSource = EinAnderesObjektMit IListSchnittstelle

    oder ob Du Deinem DGV Rows via DGV.Rows.Add() übergeben
    hast.

    Hier mal ein Beispiel mit einem an eine DataTable/Bindingsource
    gebundenes DataGridView.

    Kopiere den nachfolgenden Code in ein leeres Formmodul (Form1.vb)

    ' / Beginn Code
    Public Class Form1

        Private mDT As DataTable
        Private WithEvents mBS As BindingSource
        Private WithEvents DGV As DataGridView
        Private WithEvents TB As TextBox

        Private Sub Form1_Load _
                (ByVal sender As System.Object, _
                 ByVal e As System.EventArgs _
                ) Handles MyBase.Load

            DGV = New DataGridView
            With DGV
                .Name = "DGV"
                .Dock = DockStyle.Fill
                .DefaultCellStyle.Font = New Font("Arial", 12)

                .ColumnHeadersDefaultCellStyle.Font = _
                        New Font("Arial", 8, FontStyle.Bold)
            End With
            Me.Controls.Add(DGV)

            CreateData()

            With DGV
                .DataSource = mBS

                .Columns(0).DefaultCellStyle.Alignment = _
                        DataGridViewContentAlignment.MiddleRight

                .Columns(2).DefaultCellStyle.Alignment = _
                        DataGridViewContentAlignment.MiddleCenter

                .AutoResizeColumns()
            End With
        End Sub

        Private Sub CreateData()
            Dim Rnd As New Random
            Dim i As Integer
            Dim DR As DataRow
            Dim DC As DataColumn
            Dim Names() As String = _
                    New String() _
                    {"Anna", "Fritz", "Karl", "Maria", _
                     "Leo", "Walter", "Klara"}

            mDT = New DataTable
            With mDT
                DC = .Columns.Add("ID", GetType(Integer))
                DC.AllowDBNull = False
                DC.Unique = True

                .Columns.Add("Text", GetType(String))

                DC = .Columns.Add("Datum", GetType(Date))
                DC.AllowDBNull = True
                DC.DefaultValue = DBNull.Value

                For i = 0 To Names.GetUpperBound(0)
                    DR = .NewRow
                    DR.Item("ID") = i
                    DR.Item("Text") = Names(i)
                    DR.Item("Datum") = _
                        New Date _
                        (Rnd.Next(1950, 1990), _
                         Rnd.Next(1, 13), _
                         Rnd.Next(1, 29))

                    .Rows.Add(DR)
                Next
                .AcceptChanges()
            End With

            mBS = New BindingSource
            mBS.DataSource = mDT
        End Sub

        Private Sub DGV_CellValidating _
            (ByVal sender As Object, _
             ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs _
            ) Handles DGV.CellValidating

            If e.ColumnIndex = 2 Then

                If Not DGV.CurrentRow.IsNewRow Then

                    Dim D As Date

                    Dim Buffer As String = _
                            DGV.CurrentCell.EditedFormattedValue.ToString

                    Select Case True
                        Case Buffer = ""
                            ' Bei Leerstring auf DBNull.Value setzen
                            DGV.CurrentCell.Value = DBNull.Value
                        Case Date.TryParse(Buffer, D)
                            ' gültiges Datum, keine Reaktion erforderlich
                        Case Else
                            MsgBox _
                                    (Chr(39) & Buffer & _
                                     "' ist kein gültiges Datum!", _
                                     MsgBoxStyle.Exclamation)

                            e.Cancel = True
                    End Select
                End If
            End If

        End Sub

        Private Sub mBS_PositionChanged _
                (ByVal sender As Object, _
                 ByVal e As System.EventArgs _
                ) Handles mBS.PositionChanged

            ShowDateCellValue()
        End Sub

        Private Sub ShowDateCellValue()
            Select Case mBS.Position
                Case Is > 0, Is < DGV.RowCount - 1
                    Dim D As Object = _
                        DirectCast(mBS.Current, DataRowView).Item(2)

                    Me.Text = "Datum: "
                    If D Is DBNull.Value Then
                        Me.Text &= "DBNull.Value"
                    Else
                        Me.Text &= CDate(D)
                    End If

                Case Else
                    Me.Text = Me.Name
            End Select
        End Sub

    End Class
    ' \\\ E N T E

    Nach dem Programmstart siehst Du die Form1 mit einem DataGridView
    in dem einige Datenzeilen gezeigt werden.
    In Zellen der Spalte Datum können gültige Datumswerte eingetragen
    werden oder diese Zellen können gelöscht (Leerstring) sein.
    Im Falle von Leerstring ("") wird in Sub DGV_CellValidating()
    in jedem Fall in das Datumsfeld der Wert DBNull.Value eingetragen.
    Dies löst keinen Fehler aus, da in Sub CreateData() mit

        DC.AllowDBNull = True

    für die Datumsspalte Null-Werte (DBNull.Value) erlaubt worden sind.

    Gruß aus St.Georgen
    Peter Götz
    www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

    • Als Antwort markiert Rainer Walesch Dienstag, 28. September 2010 15:24
    Dienstag, 28. September 2010 11:27
  • Hallo Dennis,

    es gibt da so ein DefaultCellStyle, den man belegen kann.

    Me.dataGridView1.DefaultCellStyle.NullValue = "01.01.1900"
    

    Ich denke das könnte passen.

    Genau das passt eben nicht, denn damit wäre die entsprechende Zelle ja nicht leer, sondern würde das Datum 01.01.1900 zeigen. Die Zelle soll in diesem Fall kein Datum sondern eben nichts zeigen, also DBNull.Value. Gruß aus St.Georgen Peter Götz www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

    Dienstag, 28. September 2010 11:39
  • Hallo Peter,

    so klappt's. Danke.

    mfg Rainer

    Dienstag, 28. September 2010 15:25