gespeicherte XML-Daten ggf. später ändern

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

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Dksksm.

    gespeicherte XML-Daten ggf. später ändern

    Hallo zusammen.
    Meine WetterApp nimm nun langsam die Formen an, welche gefordert sind.
    Nun ist beim eingeben von realen Daten ein "Fehler" aufgetaucht.

    Wenn man z.B. bei der ersten Eingabe, Daten falsch eingegebenen hat oder etwas vergessen hat, wir ein ZWEITER Eintrag mit selben Datum in die XML geschrieben. Siehe mein Code / Daten

    Das ist natürlich nicht gut, weil so meine ganzen Diagramme etc nicht stimmen.


    Wie kann ich nun auf einfachstem Wege, mein Eingabecode so abändern, das z.B. die XML eingelesen wird und dann ggf die Daten entweder neu geschrieben werden oder im Falle das ein Datensatz besteht, dieser "geändert" wird.
    Von mir aus kann das "ändern" auch in einem separatem Form passieren.

    Ich hoffe mir kann jemand eine "einfache" Hilfe dazu anbieten.
    DANKE

    Spoiler anzeigen

    Die XML-Datei

    XML-Quellcode

    1. <?xml version="1.0"?>
    2. <ArrayOfWeatherData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    3. <WeatherData>
    4. <Datum>2023-05-07T00:00:00</Datum>
    5. <WetterTag>sdfsdfsdfsdf</WetterTag>
    6. <WetterNacht>dsfsdfs</WetterNacht>
    7. <RegenTag>2</RegenTag>
    8. <SchneeTag>0</SchneeTag>
    9. <SchneeNacht>3</SchneeNacht>
    10. <LuftfminTag>56</LuftfminTag>
    11. <LuftfmaxTag>22</LuftfmaxTag>
    12. <LuftfminNacht>12</LuftfminNacht>
    13. <LuftfmaxNacht>44</LuftfmaxNacht>
    14. <TempTag>16</TempTag>
    15. <TempNacht>11</TempNacht>
    16. <WindTag>2</WindTag>
    17. <WindNacht>1</WindNacht>
    18. </WeatherData>
    19. <WeatherData>
    20. <Datum>2023-05-07T00:00:00</Datum>
    21. <WetterTag>R/T</WetterTag>
    22. <WetterNacht>K/LB</WetterNacht>
    23. <RegenTag>6</RegenTag>
    24. <SchneeTag>0</SchneeTag>
    25. <SchneeNacht>0</SchneeNacht>
    26. <LuftfminTag>77</LuftfminTag>
    27. <LuftfmaxTag>66</LuftfmaxTag>
    28. <LuftfminNacht>44</LuftfminNacht>
    29. <LuftfmaxNacht>55</LuftfmaxNacht>
    30. <TempTag>13</TempTag>
    31. <TempNacht>4</TempNacht>
    32. <WindTag>2</WindTag>
    33. <WindNacht>1</WindNacht>
    34. </WeatherData>
    35. </ArrayOfWeatherData>


    Die Datei zum speichern der Daten

    VB.NET-Quellcode

    1. Die Datei zum speichern der Daten
    2. Public Class frmInput
    3. Private _weatherData As List(Of WeatherData)
    4. Private ReadOnly _datafolder As String = Path.Combine(Application.StartupPath, "ApSet.xml")
    5. Dim _monthDirectory As String
    6. Dim _yearDirectory As String
    7. Dim NewDatafolder As String
    8. Public Sub New()
    9. InitializeComponent()
    10. ' Initialisiere die Liste der Wetterdaten
    11. _weatherData = New List(Of WeatherData)()
    12. End Sub
    13. Private Sub ReadDataFolderFromXml()
    14. Try
    15. Dim xDoc As XDocument = XDocument.Load(_datafolder)
    16. Dim dataFolderElement As XElement = xDoc.Root.Element("dataFolder")
    17. Dim dataLocation As XElement = xDoc.Root.Element("location")
    18. If dataFolderElement IsNot Nothing AndAlso dataLocation IsNot Nothing Then
    19. Dim savePath As String = dataFolderElement.Value.Trim()
    20. Dim location As String = dataLocation.Value.Trim()
    21. Me.Text = "Eingaben für den Ort: " & location
    22. lbl_savepath.Text = savePath
    23. NewDataFolder = savePath
    24. Else
    25. Throw New Exception("Die Elemente 'dataFolder' oder 'location' konnten nicht gefunden werden.")
    26. End If
    27. Catch ex As Exception
    28. MessageBox.Show(ex.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    29. Me.Close()
    30. End Try
    31. End Sub
    32. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    33. ClearInputFields()
    34. ' Initialisiere die Liste der Wetterdaten und Speicherort auslesen
    35. _weatherData = New List(Of WeatherData)()
    36. ReadDatafolderFromXml()
    37. End Sub
    38. Private Function CheckControls(ByVal parent As Control) As Boolean
    39. For Each ctrl As Control In parent.Controls
    40. If TypeOf ctrl Is TextBox AndAlso String.IsNullOrEmpty(ctrl.Text) Then
    41. MessageBox.Show("Bitte füllen Sie alle Felder aus!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    42. ctrl.Focus()
    43. Return False
    44. ElseIf ctrl.Controls.Count > 0 Then
    45. If Not CheckControls(ctrl) Then
    46. Return False
    47. End If
    48. End If
    49. Next
    50. Return True
    51. End Function
    52. Private Sub ConvertDecimalSeparator()
    53. For Each gb As Control In Me.Controls
    54. If gb.Enabled AndAlso TypeOf gb Is GroupBox Then
    55. For Each tb As TextBox In gb.Controls.OfType(Of TextBox)()
    56. If IsNumericWithDecimalPoint(tb.Text) Then
    57. tb.Text = tb.Text.Replace(",", ".").Replace(".", ",")
    58. End If
    59. Next
    60. End If
    61. Next
    62. End Sub
    63. Private Function IsNumericWithDecimalPoint(ByVal text As String) As Boolean
    64. Dim decimalSeparator As String = Globalization.CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator
    65. Dim pattern As String = "^[+-]?\d*\" & decimalSeparator & "?\d+$|^[+-]?\d+" & decimalSeparator & "\d+$"
    66. Return System.Text.RegularExpressions.Regex.IsMatch(text, pattern)
    67. End Function
    68. Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
    69. If CheckControls(Me) Then
    70. Try
    71. ConvertDecimalSeparator()
    72. ' Lese die Daten aus dem Formular
    73. Dim datum As DateTime = dtpDatum.Value
    74. Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture("de-DE")
    75. Dim dateString As String = datum.ToString("dd.MM.yyyy", culture)
    76. Dim WetterTag As String = txtWetterTag.Text
    77. Dim WetterNacht As String = txtWetterNacht.Text
    78. Dim RegenTag As Double = Double.Parse(txtRegenTag.Text)
    79. 'Dim RegenNacht As Double = Double.Parse(txtRegenNacht.Text)
    80. Dim SchneeTag As Double = Double.Parse(txtSchneeTag.Text)
    81. Dim SchneeNacht As Double = Double.Parse(txtSchneeNacht.Text)
    82. Dim LuftfMinTag As Double = Double.Parse(txtLuftfMinTag.Text)
    83. Dim LuftfMaxTag As Double = Double.Parse(txtLuftfMaxTag.Text)
    84. Dim LuftfMinNacht As Double = Double.Parse(txtLuftfMinNacht.Text)
    85. Dim LuftfMaxNacht As Double = Double.Parse(txtLuftfMaxNacht.Text)
    86. Dim TempTag As Double = Double.Parse(txtTempTag.Text)
    87. Dim TempNacht As Double = Double.Parse(txtTempNacht.Text)
    88. Dim WindTag As Double = Double.Parse(txtWindTag.Text)
    89. Dim WindNacht As Double = Double.Parse(txtWindNacht.Text)
    90. 'Dim luftdruck As Double = Double.Parse(txtLuftdruck.Text)
    91. 'Dim windrichtung As String = txtWindrichtung.Text
    92. ' Erstelle ein neues WeatherData-Objekt
    93. Dim data As New WeatherData()
    94. data.Datum = CDate(dateString) 'datum
    95. data.WetterTag = WetterTag
    96. data.WetterNacht = WetterNacht
    97. data.RegenTag = RegenTag
    98. 'data.RegenNacht = RegenNacht
    99. data.SchneeTag = SchneeTag
    100. data.SchneeNacht = SchneeNacht
    101. data.LuftfminTag = LuftfMinTag
    102. data.LuftfmaxTag = LuftfMaxTag
    103. data.LuftfminNacht = LuftfMinNacht
    104. data.LuftfmaxNacht = LuftfMaxNacht
    105. data.TempTag = TempTag
    106. data.TempNacht = TempNacht
    107. data.WindTag = WindTag
    108. data.WindNacht = WindNacht
    109. 'data.Luftdruck = luftdruck
    110. 'data.Windrichtung = windrichtung
    111. Dim existingData As List(Of WeatherData) = Nothing
    112. Dim existingFileName = Path.Combine(NewDatafolder, datum.ToString("yyyy-MM") & ".xml")
    113. If File.Exists(existingFileName) Then
    114. Dim existingSerializer = New XmlSerializer(GetType(List(Of WeatherData)))
    115. Using existingFileStream = New FileStream(existingFileName, FileMode.Open)
    116. existingData = TryCast(existingSerializer.Deserialize(existingFileStream), List(Of WeatherData))
    117. End Using
    118. End If
    119. If existingData IsNot Nothing Then
    120. existingData.Add(data)
    121. Dim serializer = New XmlSerializer(GetType(List(Of WeatherData)))
    122. Using fileStream = New FileStream(existingFileName, FileMode.Create)
    123. serializer.Serialize(fileStream, existingData)
    124. End Using
    125. Else
    126. _weatherData.Add(data)
    127. Dim fileName = Path.Combine(NewDatafolder, data.Datum.ToString("yyyy-MM") & ".xml")
    128. Dim serializer = New XmlSerializer(GetType(List(Of WeatherData)))
    129. Using fileStream = New FileStream(fileName, FileMode.Create)
    130. serializer.Serialize(fileStream, _weatherData)
    131. End Using
    132. End If
    133. MessageBox.Show("Daten wurden erfolgreich gespeichert!")
    134. Catch ex As Exception
    135. MessageBox.Show("Fehler beim Speichern der Daten: " & ex.Message)
    136. End Try
    137. End If
    138. End Sub
    139. Private Sub chk_Regen_CheckedChanged(sender As Object, e As EventArgs) Handles chk_Regen.CheckedChanged
    140. AktualisiereRegenLabel()
    141. End Sub
    142. Private Sub AktualisiereRegenLabel()
    143. If chk_Regen.Checked Then
    144. txtRegenNacht.Text = "0"
    145. txtRegenNacht.Enabled = False
    146. Else
    147. txtRegenNacht.Text = " "
    148. txtRegenNacht.Enabled = True
    149. End If
    150. End Sub
    151. Private Sub ClearInputFields()
    152. ' Leere alle aktivierten Textboxen in GroupBox-Steuerelementen
    153. For Each gb As GroupBox In Me.Controls.OfType(Of GroupBox)()
    154. For Each ctrl As Control In gb.Controls
    155. If TypeOf ctrl Is TextBox AndAlso ctrl.Enabled Then
    156. DirectCast(ctrl, TextBox).Clear()
    157. End If
    158. Next
    159. Next
    160. ' Setze das Datum des DateTimePicker-Steuerelements auf das aktuelle Datum
    161. For Each dtp As DateTimePicker In Me.Controls.OfType(Of DateTimePicker)()
    162. If dtp.Enabled Then
    163. dtp.Value = DateTime.Now
    164. End If
    165. Next
    166. 'MessageBox.Show("Daten wurden erfolgreich geleert")
    167. End Sub
    168. Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
    169. ClearInputFields()
    170. End Sub
    171. Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
    172. Me.Close()
    173. End Sub
    174. End Class
    175. Public Class WeatherData
    176. Public Property Datum As DateTime
    177. Public Property WetterTag As String
    178. Public Property WetterNacht As String
    179. Public Property RegenTag As Double
    180. 'Public Property RegenNacht As Double
    181. Public Property SchneeTag As Double
    182. Public Property SchneeNacht As Double
    183. Public Property LuftfminTag As Double
    184. Public Property LuftfmaxTag As Double
    185. Public Property LuftfminNacht As Double
    186. Public Property LuftfmaxNacht As Double
    187. Public Property TempTag As Double
    188. Public Property TempNacht As Double
    189. Public Property WindTag As Double
    190. Public Property WindNacht As Double
    191. 'Public Property Luftdruck As Double
    192. 'Public Property Windrichtung As String
    193. End Class

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Durchsuche deine Liste _weatherData auf einen Eintrag mit dem Datum welches du (neu) schreiben willst. Mach also eine Query die entweder null ist wenn nichts gefunden wurde oder ansonsten den gefunden Eintrag beinhaltet.
    Gib einen Warnhinweis aus und wenn der Bestätigt wird, überschreibst du die Werte deiner Query, also nichts mit "add" an der Stelle weil nichts zu adden ist. Das wars dann schon.
    Wenn ich den Code richtig erfasst habe, stecken nach Programmstart aber nicht alle Aufzeichnungen in _weatherData drin. Dementsprechend müssten erstmal die archivierten Daten nach dem entsprechenden Datum durchsucht werden und diese dann nach _weatherData verfrachtet werden. Aber sonst stimme ich zu.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo ;)
    ​stecken nach Programmstart aber nicht alle Aufzeichnungen

    Was meinst du damit?

    Wäre es evtl eine Idee, ein neues Form zu machen mit einen DGV und darin die Daten ggf zu ändern und die XML dann entsprechend zu aktualisieren?
    Wenn ja, wie würde das codseitig aussehen?
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    VaporiZed schrieb:

    Wenn ich den Code richtig erfasst habe, stecken nach Programmstart aber nicht alle Aufzeichnungen in _weatherData drin.


    Stimmt... aus meiner Sicht eine suboptimale Herangehensweise. Aber vorhandene Daten werdne ja in existingData deserialisiert. Dann eben hier ansetzen.
    Ich würde mir aber überlegen, ob das Konzept so sinnvoll ist und Funktionen von Ereignissen (Button_Click) lösen und separieren. DGV und sowas wird nicht benötigt, kann man machen wäre aber ein anderes Konzept.
    ​Aber vorhandene Daten werdne ja in existingData deserialisiert. Dann eben hier ansetzen.


    Und wie soll ich da vorgehen? Stehe gerade mächtig auf dem Schlauch????
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Amelie schrieb:

    Hallo
    »stecken nach Programmstart aber nicht alle Aufzeichnungen«
    Was meinst du damit?
    Du hast eine ApSet.xml und Monats-XML-Dateien. Welche Daten speicherst Du in welcher Datei?
    Ist zu irgendeinem Zeitpunkt beim bisherigen Programmverlauf gegeben, dass sämtliche bisherige Wetterdaten in einer Variable vom Typ List(Of WeatherData) drinstecken, sodass Du ohne Zwischendurchwiederladen immer Zugriff auf alle bisher erfassten Wetterdaten hast?

    btw: Warum wandelst Du beim Speichern mit

    VB.NET-Quellcode

    1. Dim dateString As String = datum.ToString("dd.MM.yyyy", culture)
    das Datum in einen Text, wenn Du nur wenig später mit

    VB.NET-Quellcode

    1. data.Datum = CDate(dateString)
    diesen Text doch wieder in ein Datum umwandelst?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    In der ApSet-XLM sind der Ortsname der Username und die Verzeichnisse abgelegt.
    Die Eigentlichen Wetter-Daten werden in einem anderen Verzeichnis gespeichert. Z.B.: D:\WetterApp\2023\2023-05.xml

    immer Zugriff auf alle bisher erfassten Wetterdaten hast?

    Wenn ich das richtig verstehe, ja in dem "mainform" wo ich die Daten in einem DGV anzeigen lasse.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Wenn Du alle Daten im MainForm hast, dann kannst Du doch so einfach erkennen, ob es schon einen Datensatz für den Tag gibt. Und dann kannst Du den alten auch löschen. Und dann kannst Du bei [speichern] oder Programmende einfach erkennen, welche Monatsdatei neu erstellt werden muss. Ich seh grad das Problem nicht. Außer vielleicht, dass Dein o.g. Formular einfach nicht die Aufgabe haben sollte, Daten zu lesen oder zu speichern, wenn es nicht alle relevanten Informationen hat, die es braucht.
    Daher: Entweder das MainForm hat alle Daten und kümmert sich somit auch um Laden und Speichern von allem. Oder das SubForm kann alle relevanten Daten selber Laden und Speichern. Dann muss es aber auch wissen, ob es bereits Daten gibt, die überschrieben werden müssen. Aber nach einer Änderung in einem Monat muss die betroffene Datei komplett neu geschrieben werden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Falsch kann aber auch bedeuten: Ein Rechtschreibfehler, den man nach dem Speichern später korrigieren will. Ein Zahlendreher, falsches Datum, …
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ja genau, ein "Fehler" kann sein was @VaporiZed schon schrieb, oder das bestimmte Daten noch nicht vorhanden sind.

    Der Rest, ich baue gerade etwas um. Melde mich wieder. ;)



    Also ich habe das Konzept geändert.
    Es sollen nun die Daten in ein DGV eingegeben und dann als XML-Datei gespeichert werden.
    Desweiteren sollen dann fehlende oder Falsche Eingaben im DGV geändert und gespeichert werden können.

    Es gibt z.Zt. nur das eine Form im Projekt.
    Wenn ich nun ein einer Zelle etwas eingebe und zur nächste, Zelle in der selben Zeile springe bekomme ich den Fehler.

    Fehlermeldung: Ungültige Konvertierung von der Zeichenfolge in Typ Double.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Xml.Serialization
    3. Public Class Inputnew
    4. 'Klasse für Wetterdaten
    5. Public Class WeatherData
    6. Public Datum As Date
    7. Public Property WetterTag As String
    8. Public Property WetterNacht As String
    9. Public Property RegenTag As Double
    10. Public Property SchneeTag As Double
    11. Public Property SchneeNacht As Double
    12. Public Property LuftfminTag As Double
    13. Public Property LuftfmaxTag As Double
    14. Public Property LuftfminNacht As Double
    15. Public Property LuftfmaxNacht As Double
    16. Public Property TempTag As Double
    17. Public Property TempNacht As Double
    18. Public Property WindTag As Double
    19. Public Property WindNacht As Double
    20. End Class
    21. 'Klasse für Array von Wetterdaten
    22. Public Class WeatherDataArray
    23. Inherits List(Of WeatherData)
    24. End Class
    25. Private Sub Inputnew_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    26. ' Datumsangaben für aktuellen Monat im DataGridView anzeigen
    27. Dim daysInMonth As Integer = DateTime.DaysInMonth(dtpDatum.Value.Year, dtpDatum.Value.Month)
    28. For i As Integer = 1 To daysInMonth
    29. DGV_1.Rows.Add(New String() {New Date(dtpDatum.Value.Year, dtpDatum.Value.Month, i).ToString("dd-MM-yyyy"), "", "", "", "", "", "", "", "", "", "", "", "", ""})
    30. Next
    31. DGV_1.Columns(0).ReadOnly = True
    32. DGV_1.AllowUserToAddRows = False
    33. End Sub
    34. Private Sub btn_Save_Click(sender As Object, e As EventArgs) Handles btn_Save.Click
    35. 'Daten aus DGV in Array speichern
    36. Dim data As New WeatherDataArray
    37. For Each row As DataGridViewRow In DGV_1.Rows
    38. If Not row.IsNewRow Then
    39. Dim weatherData As New WeatherData
    40. weatherData.Datum = Date.Parse(CStr(row.Cells(0).Value))
    41. weatherData.WetterTag = CStr(row.Cells(1).Value)
    42. weatherData.WetterNacht = CStr(row.Cells(2).Value)
    43. weatherData.RegenTag = CDbl(row.Cells(3).Value)
    44. weatherData.SchneeTag = CDbl(row.Cells(4).Value)
    45. weatherData.SchneeNacht = CDbl(row.Cells(5).Value)
    46. weatherData.LuftfminTag = CDbl(row.Cells(6).Value)
    47. weatherData.LuftfmaxTag = CDbl(row.Cells(7).Value)
    48. weatherData.LuftfminNacht = CDbl(row.Cells(8).Value)
    49. weatherData.LuftfmaxNacht = CDbl(row.Cells(9).Value)
    50. weatherData.TempTag = CDbl(row.Cells(10).Value)
    51. weatherData.TempNacht = CDbl(row.Cells(11).Value)
    52. weatherData.WindTag = CDbl(row.Cells(12).Value)
    53. weatherData.WindNacht = CDbl(row.Cells(13).Value)
    54. data.Add(weatherData)
    55. End If
    56. Next
    57. 'Daten als XML-File speichern
    58. Dim serializer As New XmlSerializer(GetType(WeatherDataArray))
    59. 'Der Pfad wird später aus der ApSet.xml gelesen
    60. Using writer As New StreamWriter("A:\WetterApp\2023\2023-05.xml")
    61. serializer.Serialize(writer, data)
    62. End Using
    63. End Sub
    64. Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DGV_1.CellEndEdit
    65. 'Änderungen im DGV speichern
    66. Dim rowIndex As Integer = DGV_1.CurrentRow.Index
    67. Dim row As DataGridViewRow = DGV_1.Rows(rowIndex)
    68. If Not row.IsNewRow Then
    69. Dim data As New WeatherData
    70. data.Datum = Date.Parse(CStr(row.Cells(0).Value))
    71. data.WetterTag = CStr(row.Cells(1).Value)
    72. data.WetterNacht = CStr(row.Cells(2).Value)
    73. data.RegenTag = CDbl(row.Cells(3).Value)
    74. data.SchneeTag = CDbl(row.Cells(4).Value)
    75. data.SchneeNacht = CDbl(row.Cells(5).Value)
    76. data.LuftfminTag = CDbl(row.Cells(6).Value)
    77. data.LuftfmaxTag = CDbl(row.Cells(7).Value)
    78. data.LuftfminNacht = CDbl(row.Cells(8).Value)
    79. data.LuftfmaxNacht = CDbl(row.Cells(9).Value)
    80. data.TempTag = CDbl(row.Cells(10).Value)
    81. data.TempNacht = CDbl(row.Cells(11).Value)
    82. data.WindTag = CDbl(row.Cells(12).Value)
    83. data.WindNacht = CDbl(row.Cells(13).Value)
    84. 'Daten im Array aktualisieren
    85. Dim dataRowIndex As Integer = rowIndex - 1
    86. Dim dataArray As WeatherDataArray = TryCast(DGV_1.DataSource, WeatherDataArray)
    87. If dataArray IsNot Nothing AndAlso dataArray.Count > dataRowIndex Then
    88. dataArray(dataRowIndex) = data
    89. End If
    90. End If
    91. End Sub
    92. Private Sub dtpDatum_ValueChanged(sender As Object, e As EventArgs) Handles dtpDatum.ValueChanged
    93. DGV_1.Rows.Clear()
    94. ' Datumsangaben für ausgewählten Monat im DataGridView anzeigen
    95. Dim daysInMonth As Integer = DateTime.DaysInMonth(dtpDatum.Value.Year, dtpDatum.Value.Month)
    96. For i As Integer = 1 To daysInMonth
    97. DGV_1.Rows.Add(New String() {New Date(dtpDatum.Value.Year, dtpDatum.Value.Month, i).ToString("dd-MM-yyyy"), "", "", "", "", "", "", "", "", "", "", "", "", ""})
    98. Next
    99. End Sub
    100. End Class



    Beiträge zusammengefasst ~VaporiZed
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    8|
    Nein, bitte nicht manuell das DGV mit Strings füllen. Nimm eine BindingSource, setze Deine List(Of WeatherData) als DataSource und binde das DGV an die BindingSource.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo
    Ich habe nun erneut begonnen.
    EDIT vorhin falschen Code geladen...
    gleich kommt der richtige.

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

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

    So es hat etwas gedauert aber hier nun der neue Code. Es gibt nur das eine Form.
    Nach einigen Test´s funktioniert er.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Data
    3. Imports System.Xml.Serialization
    4. Public Class frm_Main
    5. 'Klasse für Wetterdaten
    6. Public Class WeatherData
    7. Public Property Datum As Date
    8. Public Property WetterTag As String
    9. Public Property WetterNacht As String
    10. Public Property RegenTag As Double
    11. Public Property SchneeTag As Double
    12. Public Property SchneeNacht As Double
    13. Public Property LuftfminTag As Double
    14. Public Property LuftfmaxTag As Double
    15. Public Property LuftfminNacht As Double
    16. Public Property LuftfmaxNacht As Double
    17. Public Property TempTag As Double
    18. Public Property TempNacht As Double
    19. Public Property WindTag As Double
    20. Public Property WindNacht As Double
    21. End Class
    22. 'Klasse für Array von Wetterdaten
    23. Public Class WeatherDataArray
    24. Inherits List(Of WeatherData)
    25. End Class
    26. Private weatherDataList As New WeatherDataArray
    27. Private filePath As String
    28. Private Sub frm_Main_Load(sender As Object, e As EventArgs) Handles Me.Load
    29. lbl_Datum.Text = dtpDatum.Value.ToString("MMMM - yyyy")
    30. ' Dateinamen aus DTP generieren
    31. Dim fileName As String = dtpDatum.Value.ToString("MM-yyyy") & ".xml"
    32. filePath = Path.Combine("B:\", fileName)
    33. If File.Exists(filePath) Then
    34. ' Daten aus XML-Datei laden
    35. LoadWeatherDataFromXmlFile(filePath)
    36. Else
    37. ' Neue Daten erstellen
    38. Dim daysInMonth As Integer = DateTime.DaysInMonth(dtpDatum.Value.Year, dtpDatum.Value.Month)
    39. weatherDataList = New WeatherDataArray()
    40. For i As Integer = 1 To daysInMonth
    41. Dim item As New WeatherData()
    42. item.Datum = New Date(dtpDatum.Value.Year, dtpDatum.Value.Month, i)
    43. weatherDataList.Add(item)
    44. Next
    45. End If
    46. 'Datenquelle und Bindingsource einrichten
    47. Dim weatherDataBindingSource As New BindingSource
    48. weatherDataBindingSource.DataSource = weatherDataList
    49. DGV_1.DataSource = weatherDataBindingSource
    50. ' Andere DataGridView-Einstellungen
    51. DGV_1.Columns(0).ReadOnly = True
    52. DGV_1.AllowUserToAddRows = False
    53. End Sub
    54. Private Sub btn_Save_Click(sender As Object, e As EventArgs) Handles btn_Save.Click
    55. SaveWeatherDataToXmlFile(filePath, weatherDataList)
    56. End Sub
    57. ' Funktion zum Speichern von Daten in einer XML-Datei
    58. Private Sub SaveWeatherDataToXmlFile(ByVal filePath As String, ByVal weatherDataList As List(Of WeatherData))
    59. Try
    60. 'Wetterdaten als XML-Datei speichern
    61. Dim serializer As New XmlSerializer(GetType(WeatherDataArray))
    62. Using writer As New StreamWriter(filePath)
    63. serializer.Serialize(writer, weatherDataList)
    64. End Using
    65. MessageBox.Show("Die Wetterdaten wurden erfolgreich gespeichert.")
    66. Catch ex As Exception
    67. MessageBox.Show(String.Format("Fehler beim Speichern der Wetterdaten: {0}", ex.Message))
    68. End Try
    69. End Sub
    70. ' Funktion zum Laden von Daten aus einer XML-Datei
    71. Private Sub LoadWeatherDataFromXmlFile(filePath As String)
    72. 'Wetterdaten aus XML-Datei laden
    73. If File.Exists(filePath) Then
    74. Dim serializer As New XmlSerializer(GetType(WeatherDataArray))
    75. Using reader As New StreamReader(filePath)
    76. weatherDataList = DirectCast(serializer.Deserialize(reader), WeatherDataArray)
    77. End Using
    78. Else
    79. MessageBox.Show("Die Wetterdaten-Datei wurde nicht gefunden.")
    80. End If
    81. 'Daten im DGV anzeigen
    82. Dim weatherDataBindingSource As New BindingSource
    83. weatherDataBindingSource.DataSource = weatherDataList
    84. DGV_1.DataSource = weatherDataBindingSource
    85. End Sub
    86. Private Sub dtpDatum_ValueChanged(sender As Object, e As EventArgs) Handles dtpDatum.ValueChanged
    87. ClearDataGridView()
    88. ' Dateinamen aus DTP generieren
    89. Dim fileName As String = dtpDatum.Value.ToString("MM-yyyy") & ".xml"
    90. filePath = Path.Combine("B:\", fileName)
    91. If File.Exists(filePath) Then
    92. ' Daten aus XML-Datei laden
    93. LoadWeatherDataFromXmlFile(filePath)
    94. Else
    95. ' Neue Daten erstellen
    96. Dim daysInMonth As Integer = DateTime.DaysInMonth(dtpDatum.Value.Year, dtpDatum.Value.Month)
    97. weatherDataList = New WeatherDataArray()
    98. For i As Integer = 1 To daysInMonth
    99. Dim item As New WeatherData()
    100. item.Datum = New Date(dtpDatum.Value.Year, dtpDatum.Value.Month, i)
    101. weatherDataList.Add(item)
    102. Next
    103. End If
    104. 'Datenquelle und Bindingsource einrichten
    105. Dim weatherDataBindingSource As New BindingSource
    106. weatherDataBindingSource.DataSource = weatherDataList
    107. DGV_1.DataSource = weatherDataBindingSource
    108. ' Andere DataGridView-Einstellungen
    109. DGV_1.Columns(0).ReadOnly = True
    110. DGV_1.AllowUserToAddRows = False
    111. End Sub
    112. Private Sub ClearDataGridView()
    113. 'Alle Zeilen im DataGridView löschen
    114. If DGV_1.Rows.Count > 0 Then
    115. For i As Integer = DGV_1.Rows.Count - 1 To 0 Step -1
    116. DGV_1.Rows.RemoveAt(i)
    117. Next
    118. End If
    119. End Sub
    120. ' Dezimalpunkt ersetzen
    121. Private Sub DGV_1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DGV_1.EditingControlShowing
    122. If TypeOf e.Control Is DataGridViewTextBoxEditingControl Then
    123. Dim textBox As DataGridViewTextBoxEditingControl = CType(e.Control, DataGridViewTextBoxEditingControl)
    124. AddHandler textBox.KeyPress, AddressOf TextBox_KeyPress
    125. End If
    126. End Sub
    127. Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs)
    128. If e.KeyChar = "." Then
    129. e.KeyChar = CChar(",")
    130. End If
    131. End Sub
    132. ' Das DGV formatieren / Farben Zeilen und negativ Zahlen
    133. Private Sub DGV_1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DGV_1.CellFormatting
    134. If e.ColumnIndex = 0 AndAlso Not e.Value Is Nothing Then
    135. e.Value = DateTime.Parse(e.Value.ToString()).ToString("dd-MM-yyyy")
    136. e.FormattingApplied = True
    137. End If
    138. ' Überprüfen, ob es sich um eine Zelle mit einer Zahl handelt
    139. If e.ColumnIndex >= 0 AndAlso IsNumeric(e.Value) Then
    140. ' Überprüfen, ob die Zahl negativ ist
    141. If CDbl(e.Value) < 0 Then
    142. ' Setzen Sie die Textfarbe auf Rot
    143. e.CellStyle.ForeColor = Color.Red
    144. Else
    145. ' Setzen Sie die Textfarbe auf Standardfarbe
    146. e.CellStyle.ForeColor = DGV_1.DefaultCellStyle.ForeColor
    147. End If
    148. End If
    149. If e.RowIndex Mod 2 = 1 Then
    150. e.CellStyle.BackColor = Color.LightGray
    151. End If
    152. End Sub
    153. ' Button zum Einstellen des Datums um einen Monat zurück
    154. Private Sub btnPrevMonth_Click(sender As Object, e As EventArgs) Handles btnPrevMonth.Click
    155. dtpDatum.Value = dtpDatum.Value.AddMonths(-1)
    156. lbl_Datum.Text = dtpDatum.Value.ToString("MMMM - yyyy")
    157. End Sub
    158. ' Button zum Einstellen des Datums um einen Monat nach vorne
    159. Private Sub btnNextMonth_Click(sender As Object, e As EventArgs) Handles btnNextMonth.Click
    160. dtpDatum.Value = dtpDatum.Value.AddMonths(1)
    161. lbl_Datum.Text = dtpDatum.Value.ToString("MMMM - yyyy")
    162. End Sub
    163. End Class

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Die weatherDataBindingSource (Zeile 53) würde ich Private definieren (Zeile 32?).
    Die Zeilen 90 - 93 in der Funktion LoadWeatherDataFromXmlFile mach gar keinen Sinn. Die Zuweisung überschreibst du in der Funktion (oder Sub wie ihr in VB.Net sagt) frm_Main_Load ab Zeile 52 gleich wieder.
    Tatsächlich glaube ich nicht einmal, dass das funktioniert, weil die Variablenzuweisung in Zeile 91 beim Verlassen der Sub wieder zerstört werden müßte.

    Mehr habe ich mir jetzt nicht angeguckt.