Datagridview Spalte mit Datumsformat - Zellen ohne Inhalt nicht formatieren

  • VB.NET

Es gibt 39 Antworten in diesem Thema. Der letzte Beitrag () ist von Yanbel.

    Datagridview Spalte mit Datumsformat - Zellen ohne Inhalt nicht formatieren

    Hallo
    Ich habe ein Datagridview mit mehreren Datumsspalten. Dieses Datagridview ist an eine Bindingsource gebunden.
    Über Textboxen und einen speichern Button können die Werte im DataSet geändert werden.
    Nun möchte ich alle Datumsangaben mit zweistelliger Jahreszahl speichern. Dazu habe ich die entsprechenden Spalten über den Smart Tag --> DefaultCellStyle als Datum, mit dem Format "dd.MM.yy" formatiert -das klappt auch alles.
    Edit: Die Spalten im DataSet selber sind als System.DateTime formatiert (falls das eine Rolle spielt)

    Allerdings wird hier nun immer ein Wert angezeigt, auch wenn der gespeicherte Datumswert eigentlich nothing ist.
    Ich kann also nicht gescheid aus meinem DataSet löschen.
    Hier ein Beispiel eines Datums:

    VB.NET-Quellcode

    1. Private Sub SaveOrder()
    2. If OrderBindingSource.Current Is Nothing Then
    3. MessageBox.Show("Bitte erst eine Bestellung auslösen.")
    4. Exit Sub
    5. End If
    6. Dim SelectedOrder = DirectCast(DirectCast(OrderBindingSource.Current, DataRowView).Row, DtsSettings.OrderRow)
    7. 'Datumswerte prüfen und in Variablen speichern
    8. Dim orderdate As Date
    9. If Not Datecheck(orderdate) Then
    10. MessageBox.Show("ungültiges Bestelldatum")
    11. Exit Sub
    12. End If
    13. 'usw. für die anderen Datumswerte
    14. MessageBox.Show(orderdate.ToString)
    15. 'SelectedOrder.orderdate = orderdate
    16. End Sub
    17. Private Function Datecheck(ByRef DatefromTB As Date) As Boolean
    18. If TBOrderDate.Text = "" Then
    19. DatefromTB = Nothing
    20. Return True
    21. Else
    22. If Not Date.TryParse(TBOrderDate.Text, DatefromTB) Then
    23. DatefromTB = Nothing
    24. Return False
    25. End If
    26. End If
    27. Return True
    28. End Function


    Folgendes setzt jetzt immer ein falsches (oder leeres) Datum voraus - sagen wir die Textbox fürs orderdate bleibt leer, dann will ich dieses löschen.
    Nehme ich die Formatierung aus der "orderdate" Spalte raus, wird mir korrekterweise kein Wert angezeigt. Der entsprechende Wert im DataSet sollte ja nothing sein.
    Mit oben eingestellter Formatierung (Datum und "dd.MM.yy") wird mir aber der 01.01.0001 angezeigt.

    Wie bekomme ich dieses Problem mit zweistelligen Jahreszahlen gelöst?

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

    Schaue dir das DGV.CellFormatting-Event einmal an...
    docs.microsoft.com/de-de/dotne…mework-4.8#code-snippet-2
    Hier wird nur die Ansicht des Zellwertes geändert, der Wert selber bleibt unberührt...
    Du könntest das Aussehen der Wertausgabe selbst bestimmen und im DGV anzeigen lassen...
    Danke für den Link!
    Ich habe mir dieses Beispiel nun zu Grunde gelegt und daraus folgenden Code gezaubert:

    VB.NET-Quellcode

    1. Private Sub OrderDataGridView_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles OrderDataGridView.CellFormatting
    2. If Me.OrderDataGridView.Columns(e.ColumnIndex).Name = "orderdate" Then ShortFormDateFormat(e)
    3. If Me.OrderDataGridView.Columns(e.ColumnIndex).Name = "deliverydate" Then ShortFormDateFormat(e)
    4. If Me.OrderDataGridView.Columns(e.ColumnIndex).Name = "invoicereceive" Then ShortFormDateFormat(e)
    5. If Me.OrderDataGridView.Columns(e.ColumnIndex).Name = "invoicedate" Then ShortFormDateFormat(e)
    6. End Sub

    VB.NET-Quellcode

    1. Private Shared Sub ShortFormDateFormat(ByVal formatting As DataGridViewCellFormattingEventArgs)
    2. Try
    3. Dim dateString As System.Text.StringBuilder = New System.Text.StringBuilder()
    4. Dim theDate As Date = DateTime.Parse(formatting.Value.ToString())
    5. If theDate.Month < 10 Then
    6. dateString.Append(0 & theDate.Month)
    7. Else
    8. dateString.Append(theDate.Month)
    9. End If
    10. dateString.Append(".")
    11. If theDate.Day < 10 Then
    12. dateString.Append(0 & theDate.Day)
    13. Else
    14. dateString.Append(theDate.Day)
    15. End If
    16. dateString.Append(".")
    17. dateString.Append(theDate.Year.ToString().Substring(2))
    18. formatting.Value = dateString.ToString
    19. formatting.FormattingApplied = True
    20. Catch notInDateFormat As FormatException
    21. formatting.FormattingApplied = False
    22. End Try
    23. End If


    Die ShortFormDateFormat Sub ist letzlich 1zu1 aus der MSDN übernommen. Die einzige Änderung die ich getätigt habe ist, die Prüfung ob Tageszahlen, oder Monatszahlen < 10 sind, um noch die führende 0 anzufügen.
    Da mir das irgendwie recht kompiziert ist, habe ich die Sub wie folgt geändert:

    VB.NET-Quellcode

    1. Private Shared Sub ShortFormDateFormat(ByVal formatting As DataGridViewCellFormattingEventArgs)
    2. Dim tempdate As Date
    3. If formatting.Value IsNot Nothing Then
    4. If Date.TryParse(formatting.Value.ToString, tempdate) Then
    5. formatting.Value = tempdate.ToString("dd.MM.yy")
    6. End Sub

    Macht irgendwie das gleiche.

    Aber ich habe im Urin, dass beide Wege nicht die besten sind...
    Edit: Es taucht auch bei beiden Codes eine kleine (aber merkbare) Verzögerung auf, wenn ich Daten (bisher erst 4 Zeilen) übers Binding in die Dgv lade - da würde ich lieber mit vierstelligen Jahreszahlen leben.

    Aber könnte das Problem nicht die Ursache der System.DateTime Formatierung im DataSet haben?
    Ich meine mal irgendwo gelesen zu haben, dass DateTime im DataSet nicht nothing sein kann.
    Das kann ich ja auch nicht als Default Value auswählen.
    Macht es hier evtl. Sinn, die Datumsangaben als String im DataSet zu formatieren?

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

    Grundsatzgegenfrage: Da eine Bestellung ohne Datum keinen Sinn ergibt - warum dann die Bestellung überhaupt speichern? Also "Vorlage" für später?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Weil ich ja verschiedenartige Datumswerte Speicher.
    Eine Lieferung ohne "orderdate" resultiert in einem Fehler.
    Aber es gibt noch Lieferdatum, Rechnungsdatum und Datum des Rechnungerhaltes.
    Hier sind dann leere Daten möglich.

    Zum Datentyp im Dataset.
    Habe gerade eben String ausprobiert und die Datunswerte im Designer formatiert. Das sieht behindert aus. Nicht zu gebrauchen.

    Also komme ich um eine Formatierung im Code nicht Drumherum?
    Das gibt wie gesagt eine merkbare Verzögerung :(
    Ok, damit ich selber mal Performancetests machen kann:
    Ich hab ne DateTime-Spalte in meiner DataTable.
    Ein an die DT gebundenes DGV, wo alles angezeigt wird; Datumsspalte ist mit CellStyle-Format "dd.MM.yy"
    Und was noch? Denn wenn ich es dabei belasse, erhalte ich ohne zusätzlichen Code bei Eingabe von Datumsangaben (für das Du statt ner TextBox entweder nen MonthCalendar oder nen DateTimePicker nehmen solltest):

    Was fehlt mir, um das zu erreichen, was Du willst?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    DerSmurf schrieb:

    Nun möchte ich alle Datumsangaben mit zweistelliger Jahreszahl speichern. Dazu habe ich die entsprechenden Spalten über den Smart Tag --> DefaultCellStyle als Datum, mit dem Format "dd.MM.yy" formatiert -das klappt auch alles.
    Edit: Die Spalten im DataSet selber sind als System.DateTime formatiert (falls das eine Rolle spielt)
    Du verwendest die Begriffe "Speichern" und "Formatieren" so falsch, dass nicht klar ist, was du meinst.
    Entsprechend wenig zielführend dürften die Antworten ausfallen.

    Also:

    DerSmurf schrieb:

    Nun möchte ich alle Datumsangaben mit zweistelliger Jahreszahl speichern.
    Das scheint mir Quack. Speichern kannst du das Dataset, und das wird halt gespeichert wies ist - gottlob sind die Spalten als DateTime formatiert, dann speichern sie als DateTime und nicht als iwas mit zweistelliger Jahreszahl.

    DerSmurf schrieb:

    Edit: Die Spalten im DataSet selber sind als System.DateTime formatiert (falls das eine Rolle spielt)
    Spalten im Dataset kann man nicht als DateTime formatieren - man kann sie als DateTime deklarieren.

    So, nun was du eiglich wolle?
    Vielleicht willst du ja Datum-Werte formatiert anzeigen, sodass die Anzeige eine 2-stellige Zahreszahl aufweist?
    Das würde Sinn ergeben, und wäre das allereinfachste, dafür verfügt jede DGV-Column im DefaultCellstyle über einen Format-String, den man im Designer setzen kann, und formatiert ist.

    Aber mach dir vor allem die Begriffe klar:
    • Speichern: Daten auf Platte schreiben
    • Deklarieren: Festlegen, dass es ein Objekt gibt, und welchen Datentyp es hat (etwa die OrderDate-Property vom Typ DateTime).
    • Formatieren: Einen Wert eines Objektes umwandeln zum Zwecke einer gefälligen Anzeige. Das Objekt wird dabei nicht verändert, nur der anzuzeigende Wert wird abgelesen und umgeformt, meist in einen String, den man dann schön anzeigen kann.
    OK @ErfinderDesRades ich gebe mir Mühe die Begriffe korrekt einzusetzen.
    Sorry, ich glaube hier verwirrt mich mein VBA mit Excel ein wenig.

    Du hast in allen Punkten Recht (also es verhält sich in meinem Programm so, wie du es erahnst), außer dem letzten:

    ErfinderDesRades schrieb:

    Vielleicht willst du ja Datum-Werte formatiert anzeigen, sodass die Anzeige eine 2-stellige Zahreszahl aufweist?
    Das würde Sinn ergeben, und wäre das allereinfachste, dafür verfügt jede DGV-Column im DefaultCellstyle über einen Format-String, den man im Designer setzen kann, und formatiert ist.


    Genau das stellt mich vor oben beschriebenem Problem.
    Ich habe für @VaporiZed mal ein Bild der Form angehangen.
    Es gibt insgesamt 4 Datumsspalten, wobei die erste (Bestelldatum) immer ein Datum haben muss.
    Alle anderen sollen auch leer bleiben dürfen.
    Nun habe ich mir folgenden Speichercode für meine Datumswerte überlegt. Vielleicht liegt ja auch hier der Fehler.
    Sinn und Zweck dieses Codes ist es, die eingebenen Datumswerte aus der den Textboxen im DataTable zu speichern, egal welcher Wert dort vorher stand. Ist die Eingabe in einer Textbox leer, soll das Datum im DataSet leer bleiben, oder leer werden.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub SaveOrder()
    2. If OrderBindingSource.Current Is Nothing Then
    3. MessageBox.Show("Bitte erst eine Bestellung auslösen.")
    4. Exit Sub
    5. End If
    6. Dim SelectedOrder = DirectCast(DirectCast(OrderBindingSource.Current, DataRowView).Row, DtsSettings.OrderRow)
    7. 'Datumswerte prüfen und in Variablen speichern
    8. Dim orderDate As Date, deliveryDate As Date, InvoiceReceive As Date, InvoiceDate As Date
    9. If TBOrderDate.Text = "" Then
    10. MessageBox.Show("Es darf keine Bestellung ohne Bestelldatum geben")
    11. Exit Sub
    12. End If
    13. If Not Datecheck(orderDate, TBOrderDate.Text) Then
    14. MessageBox.Show("ungültiges Bestelldatum")
    15. Exit Sub
    16. End If
    17. If Not Datecheck(deliveryDate, TBDeliveryDate.Text) Then
    18. MessageBox.Show("ungültiges Lieferdatum")
    19. Exit Sub
    20. End If
    21. If Not Datecheck(InvoiceReceive, TBInvoiceReceive.Text) Then
    22. MessageBox.Show("ungültiges Datum für Rechnungserhalt")
    23. Exit Sub
    24. End If
    25. If Not Datecheck(InvoiceDate, TBInvoiceDate.Text) Then
    26. MessageBox.Show("ungültiges Rechnungsdatum")
    27. Exit Sub
    28. End If
    29. 'Lieferzeit errechnen
    30. Dim DeliverDuration As Double = deliveryDate.Subtract(orderDate).TotalDays
    31. 'Rechnungsnummer und Notiz speichern
    32. Dim Invoicenumber As String = TBInvoiceNumber.Text
    33. Dim Note As String = TBNote.Text
    34. 'Nettosummen
    35. Dim net19 As Double, net7 As Double
    36. If Not Sumcheck(net19, TBNet19.Text) Then
    37. MessageBox.Show("ungültige Netto 19% Summe")
    38. Exit Sub
    39. End If
    40. If Not Sumcheck(net7, TBNet7.Text) Then
    41. MessageBox.Show("ungültige Netto 7% Summe")
    42. Exit Sub
    43. End If
    44. 'Gesamt Rechnungssumme
    45. Dim Total As Double = (net19 * 1.19) + (net7 * 1.07)
    46. 'Daten in den DataTable schreiben
    47. SelectedOrder.OrderDate = orderDate
    48. SelectedOrder.DeliveryDate = deliveryDate
    49. SelectedOrder.DeliverDuration = DeliverDuration
    50. SelectedOrder.InvoiceReceive = InvoiceReceive
    51. SelectedOrder.InvoiceDate = InvoiceDate
    52. SelectedOrder.InvoiceNumber = Invoicenumber
    53. SelectedOrder.Net19 = net19
    54. SelectedOrder.Net7 = net7
    55. SelectedOrder.Total = Total
    56. SelectedOrder.Note = Note
    57. 'Bestelungen nach Bestelldatu absteigend sortieren
    58. OrderDataGridView.Sort(OrderDataGridView.Columns(0), System.ComponentModel.ListSortDirection.Descending)
    59. End Sub
    60. Private Function Datecheck(ByRef DatefromSub As Date, ByVal DatefromTB As String) As Boolean
    61. If DatefromTB = "" Then
    62. DatefromSub = Nothing
    63. Return True
    64. Else
    65. If Not Date.TryParse(DatefromTB, DatefromSub) Then
    66. DatefromSub = Nothing
    67. Return False
    68. End If
    69. End If
    70. Return True
    71. End Function
    72. 'Funktion zum prüfen der eingegebenen Nettosummen
    73. Private Function Sumcheck(ByRef netfromSub As Double, ByVal netFromTB As String) As Boolean
    74. If netFromTB = "" Then
    75. netfromSub = Nothing
    76. Return True
    77. Else
    78. If Not Double.TryParse(netFromTB, netfromSub) Then
    79. netfromSub = Nothing
    80. Return False
    81. End If
    82. End If
    83. Return True
    84. End Function


    Meine Spalten im Datagridview sind entsprechend mit Datum und "dd.MM.yy" formatiert.
    Lege ich nun eine neue Bestellung an (neue DataRow, welche nur das orderdate enthält), bleiben die restlichen drei Datumsspalten noch leer.
    Sobald ich aber z.B. ein Lieferdatum angebe und den speichern Button betätige, werden alle nicht belegten Datumswerte im Datagridview als 01.01.0001 angezeigt. Entferne ich die Formatierung aus den DGV Spalten, werden keine Werte für nicht gesetzte Daten angezeigt, aber die Jahreszahlen eben 4 stellig angezeigt.

    Ich möchte also quasi die im DS gespeicherten Datumswerte mit zwei stelliger Jahreszahl im DGV anzeigen und wenn es kein Datum gibt, weil keins eingegeben wurde, oder weil ein bereits eingegebenes Datum entfernt wurde, dann soll in der entsprechenden Zelle (ich hoffe das heißt im DGV genau wie in Excel) nichts angezeigt werden.
    Bilder
    • Anmerkung 2019-06-26 085058.png

      45 kB, 1.151×713, 22 mal angesehen
    Der Unterschied zwischen Deinem und meinem Code ist: Du sagst: Wenn Datumseingabe = Müll, dann ist Variable X vom Typ Date = Nothing. Und X speicherst Du im tDS ab. Ich sage: Wenn Müll eingegeben wird, speichere Nothing im tDS ab.
    Was ist der inhaltliche Unterschied? Date ist eine Structure. Wenn man ner Date-Variable Nothing zuweist, erhältst Du 01.01.0001. Und das speicherst Du ab.
    Wenn man aber Nothing im tDS in ner DateTime-Spalte abspeichert, kann man einstellen, dass bei NullValue ThrowException drinsteht. Und das führt dann dazu, dass im DGV gar nix drinsteht! Und das ist ja Dein Ziel.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    OK, das habe ich verstanden.
    Aber dann könnte ich ja mit deinem Code kein vorhandenes Datum löschen.
    Dies möchte ich in meinem Projekt (wenn möglich) mit nur diesem einen speichern Button realisieren.
    Sollte ich dann evtl. doch darüber nachdenken meine DateTime deklaration der DT Spalte in String zu ändern?
    Weil der String eben leer sein kann? Ich meine das DataSet selbst kann ja eh nicht mit Daten rechnen.
    Wenn ich dann mit diesen Datumswerten mal rechnen möchte, z.B. um die Lieferzeit zu errechnen, könnte ich den String ja in eine Date umwandeln.

    Was ich aber nicht verstehe ist dann, warum mir mit identischem Code, ohne Formatierung der DGV Spalten, nicht auch dieses Datum (01.01.0001) angezeigt wid.
    Denn auch dann habe ich ja durch selectedorder.welchesDateauchimmer = nothing das Datum 01.01.0001 gespeichert.
    Nix mit String.
    Ein Datum kannst Du löschen, indem Du im tDS direkt Nothing abspeicherst. Das geht mit Deinem Code nicht, da Du ne Date-Variable als Zwischenspeicher nutzt.
    Das direkte Abspeichern von Nothing ist was anderes, als wenn Du den Wert einer Date-Variable, der einen Wert Nothing abspeicherst.
    Nothing → tDS → bei Abfrage des Wertes: ThrowException → im DGV: leer
    Nothing → DateVariable → ergibt 01.01.0001 → tDS; im tDS wird 01.01.0001 gespeichert → bei Abfrage des Wertes: 01.01.0001 → im DGV: 01.01.0001
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Aaaaaaah!
    Das ist gut.
    Dann ändere ich meinen Code einfach und füge bei der Datumskonvertierung eine boolean Variable ein.
    Damit fange ich dann beim schreiben ins DS ab, ob es ein Datum gibt oder nicht und speichere dann eben das Datum, oder nothing.
    Oder darf (ist das sauber) ich auch beim schreiben ins DataSet abfragen, ob meine gespeicherte Datumsvariable = "01.01.0001" ist? und dann entsprechend reagieren?

    Verstehe nicht ganz warum du die Spalten deines DGV nicht initial bei laden der Form einmalig formatierst. Dann werden die die Daten doch korrekt angezeigt.

    VB.NET-Quellcode

    1. Private Sub FormatDGV
    2. DGV.Columns.Add(New DataGridViewTextBoxColumn With {.Name = "Datum", .DataPropertyName = "Datum"})
    3. With DGV.Columns("Datum")
    4. .ReadOnly = False
    5. .Visible = True
    6. .Width = 120
    7. .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
    8. .HeaderText = "Datum"
    9. .SortMode = DataGridViewColumnSortMode.Automatic
    10. .DefaultCellStyle.Format = "dd.MM.yyyy"
    11. End With
    12. End Sub


    Das machst du mit jeder Column und dann schubst du die Daten einfach nur noch über die DataSource ins DGV. Formatieren jede Spalte in der Methode, ruf sie einmal beim Laden der Form auf und solange du dein DGV nicht clearst bleibt die Formatierung erhalten.


    Spezielle Frage zu euren Visual Basic-Projekten, Code-Design, SQL-Queries, etc. könnt ihr mir auch direkt schicken. Aber wenn ihr sie im Forum postet profitieren alle davon.
    What? Die wurden doch im Form-Designer schon längst formatiert. Und zwar mit 2-stelliger Jahresangabe.
    @DerSmurf: ja, geht auch. Und dann, bei "01.01.0001" eben Nothing in die Table schreiben. Wie Du willst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    @Yanbel
    Wenn ich die Erklärung von @VaporiZed richtig verstanden habe, würde deine Lösung mein Problem ja auch nur kaschieren.
    Denn mein Code schreibt halt Datumswerte ins DataSet, die da nicht hingehören.
    Also muss ich doch meinen Speichercode ändern, und sollte nicht mal über andere Formatierungen nachdenken?
    @DerSmurf
    @VaporiZed hat absolut recht. Einziger Vorteil an meinem Codebeispiel ist, das Nothing mitverarbeitet wird ohne gesonderte Prüfung. Das die Daten in deiner Quelle korrekt sein müssen, ist dafür natürlich Grundvoraussetzung. Ich arbeite bei sowas gerne mit einzelnen Klassen statt mit Datasets da mir die Set-Methode einer Property dabei in die Hände spielt.

    VB.NET-Quellcode

    1. Private _Bestelldatum As Date?
    2. Public Property Bestelldatum As Date?
    3. Get
    4. Return _Bestelldatum
    5. End Get
    6. Set(value As Date?)
    7. If isDate(value) AndAlso value > New Date(1753,1,1) AndAlso value < New Date(9999,12,31)
    8. _Bestelldatum = value
    9. Else
    10. _Bestelldatum = Nothing
    11. Else
    12. End Set
    13. End Property


    Diese Prüfung kannst du dann individuell deinen Bedürfnissen anpassen. So verhinderst du das überhaupt fehlerhafte Daten in deine Datenquelle aufgenommen werden.

    VB.NET-Quellcode

    1. If isDate(value) AndAlso value > New Date(1753,1,1) AndAlso value < New Date(9999,12,31)



    Spezielle Frage zu euren Visual Basic-Projekten, Code-Design, SQL-Queries, etc. könnt ihr mir auch direkt schicken. Aber wenn ihr sie im Forum postet profitieren alle davon.

    DerSmurf schrieb:

    Nun habe ich mir folgenden Speichercode...
    Ich sehe da keinen SpeicherCode.
    allerlei Werte werden dort abgeprüft, und dann in eine OrderRow eingetragen.
    Anschliessend wird das dgv sortiert, warumauchimmer.
    Gespeichert wird da nix.
    Also es werden Textboxen-Werte in die aktuelle OrderRow eingetragen
    Hey @VaporiZed
    Das haut nicht hin.

    hier die Codeänderung: (der relevante Teil)

    VB.NET-Quellcode

    1. 'Daten in den DataTable schreiben
    2. SelectedOrder.OrderDate = orderDate
    3. If deliveryDate = Nothing Then
    4. SelectedOrder.DeliveryDate = Nothing
    5. SelectedOrder.DeliverDuration = Nothing
    6. Else
    7. SelectedOrder.DeliveryDate = deliveryDate
    8. 'Lieferzeit errechnen
    9. Dim DeliverDuration As Double = deliveryDate.Subtract(orderDate).TotalDays
    10. SelectedOrder.DeliverDuration = DeliverDuration
    11. End If
    12. If InvoiceReceive = Nothing Then
    13. SelectedOrder.InvoiceReceive = Nothing
    14. Else
    15. SelectedOrder.InvoiceReceive = InvoiceReceive
    16. End If
    17. If InvoiceDate = Nothing Then
    18. SelectedOrder.InvoiceDate = Nothing
    19. Else
    20. SelectedOrder.InvoiceDate = InvoiceDate
    21. End If

    Ich habe das ganze im Einzelschritt durchlaufen lassen.
    Die Bedingung wird korrekt (wie von mir erwartet) abgearbeitet.
    Aber auch nach SelectedOrder.EinDatum = nothing, wird mir im Dgv der 01.01.01 angezeigt. :cursing:

    Edit: Meine an die gleiche DataTable gebundenen Textboxen zeigen mit deinem Code aber kein Datum an.
    Diese formatiere ich per Code im DgvCellFormatting Event:

    VB.NET-Quellcode

    1. Private Sub OrderDataGridView_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles OrderDataGridView.CellFormatting
    2. FormatCells()
    3. End Sub
    4. Private Sub FormatCells()
    5. Dim number As Double
    6. Dim tempdate As Date
    7. If Double.TryParse(TBNet7.Text, number) Then TBNet7.Text = number.ToString("0.00")
    8. If Double.TryParse(TBNet19.Text, number) Then TBNet19.Text = number.ToString("0.00")
    9. If Double.TryParse(TBTotal.Text, number) Then TBTotal.Text = number.ToString("0.00")
    10. If Double.TryParse(LBLDeliverDuration.Text, number) Then LBLDeliverDuration.Text = number.ToString("0.00")
    11. If Date.TryParse(TBOrderDate.Text, tempdate) Then TBOrderDate.Text = tempdate.ToString("dd.MM.yy")
    12. If Date.TryParse(TBDeliveryDate.Text, tempdate) Then TBDeliveryDate.Text = tempdate.ToString("dd.MM.yy")
    13. If Date.TryParse(TBInvoiceReceive.Text, tempdate) Then TBInvoiceReceive.Text = tempdate.ToString("dd.MM.yy")
    14. If Date.TryParse(TBInvoiceDate.Text, tempdate) Then TBInvoiceDate.Text = tempdate.ToString("dd.MM.yy")
    15. End Sub


    hier noch der gesamte Code (der Vollständigkeit halber)
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub SaveOrder()
    2. If OrderBindingSource.Current Is Nothing Then
    3. MessageBox.Show("Bitte erst eine Bestellung auslösen.")
    4. Exit Sub
    5. End If
    6. Dim SelectedOrder = DirectCast(DirectCast(OrderBindingSource.Current, DataRowView).Row, DtsSettings.OrderRow)
    7. 'Datumswerte prüfen und in Variablen speichern
    8. Dim orderDate As Date, deliveryDate As Date, InvoiceReceive As Date, InvoiceDate As Date
    9. If TBOrderDate.Text = "" Then
    10. MessageBox.Show("Es darf keine Bestellung ohne Bestelldatum geben")
    11. Exit Sub
    12. End If
    13. If Not Datecheck(orderDate, TBOrderDate.Text) Then
    14. MessageBox.Show("ungültiges Bestelldatum")
    15. Exit Sub
    16. End If
    17. If Not Datecheck(deliveryDate, TBDeliveryDate.Text) Then
    18. MessageBox.Show("ungültiges Lieferdatum")
    19. Exit Sub
    20. End If
    21. If Not Datecheck(InvoiceReceive, TBInvoiceReceive.Text) Then
    22. MessageBox.Show("ungültiges Datum für Rechnungserhalt")
    23. Exit Sub
    24. End If
    25. If Not Datecheck(InvoiceDate, TBInvoiceDate.Text) Then
    26. MessageBox.Show("ungültiges Rechnungsdatum")
    27. Exit Sub
    28. End If
    29. 'Rechnungsnummer und Notiz speichern
    30. Dim Invoicenumber As String = TBInvoiceNumber.Text
    31. Dim Note As String = TBNote.Text
    32. 'Nettosummen
    33. Dim net19 As Double, net7 As Double
    34. If Not Sumcheck(net19, TBNet19.Text) Then
    35. MessageBox.Show("ungültige Netto 19% Summe")
    36. Exit Sub
    37. End If
    38. If Not Sumcheck(net7, TBNet7.Text) Then
    39. MessageBox.Show("ungültige Netto 7% Summe")
    40. Exit Sub
    41. End If
    42. 'Gesamt Rechnungssumme
    43. Dim Total As Double = (net19 * 1.19) + (net7 * 1.07)
    44. 'Daten in den DataTable schreiben
    45. SelectedOrder.OrderDate = orderDate
    46. If deliveryDate = Nothing Then
    47. SelectedOrder.DeliveryDate = Nothing
    48. SelectedOrder.DeliverDuration = Nothing
    49. Else
    50. SelectedOrder.DeliveryDate = deliveryDate
    51. 'Lieferzeit errechnen
    52. Dim DeliverDuration As Double = deliveryDate.Subtract(orderDate).TotalDays
    53. SelectedOrder.DeliverDuration = DeliverDuration
    54. End If
    55. If InvoiceReceive = Nothing Then
    56. SelectedOrder.InvoiceReceive = Nothing
    57. Else
    58. SelectedOrder.InvoiceReceive = InvoiceReceive
    59. End If
    60. If InvoiceDate = Nothing Then
    61. SelectedOrder.InvoiceDate = Nothing
    62. Else
    63. SelectedOrder.InvoiceDate = InvoiceDate
    64. End If
    65. SelectedOrder.InvoiceNumber = Invoicenumber
    66. SelectedOrder.Net19 = net19
    67. SelectedOrder.Net7 = net7
    68. SelectedOrder.Total = Total
    69. SelectedOrder.Note = Note
    70. 'Bestellungen nach Bestelldatum absteigend sortieren
    71. OrderDataGridView.Sort(OrderDataGridView.Columns(0), System.ComponentModel.ListSortDirection.Descending)
    72. End Sub
    73. 'Funktion zum Prüfen eingegebener Datumswerte
    74. Private Function Datecheck(ByRef DatefromSub As Date, ByVal DatefromTB As String) As Boolean
    75. If DatefromTB = "" Then
    76. DatefromSub = Nothing
    77. Return True
    78. Else
    79. If Not Date.TryParse(DatefromTB, DatefromSub) Then
    80. DatefromSub = Nothing
    81. Return False
    82. End If
    83. End If
    84. Return True
    85. End Function
    Bilder
    • Anmerkung 2019-06-26 165748.png

      23,49 kB, 378×747, 15 mal angesehen
    • Anmerkung 2019-06-26 171955.png

      23,08 kB, 562×572, 10 mal angesehen
    • Anmerkung 2019-06-26 172248.png

      93,85 kB, 1.064×763, 11 mal angesehen

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