Code umgestalten (Daten an XML anhängen/in neue Datei speichern)

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

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von Marcus Gräfe.

    Code umgestalten (Daten an XML anhängen/in neue Datei speichern)

    Hallo und Frohe Ostern

    Ich habe hier eine App im Aufbau. Der u.g Code funktioniert soweit.
    Für jeden Tag einer Kalenderwoche wird eine XML-Datei in einen bestimmten Verzeichnis geschrieben.
    Nun wollte ich das alles in einem DGView abzeigen lassen, was mir dann bewust machte, das ich den Code irgendwie ändern muss.

    Wie komme ich schnell dahin, das für jede KW die täglichen Daten nur in die vorhandene XML an gehangen werden?
    Erst wenn eine neue KW beginnt soll auch eine neue XML geschrieben werden.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub btnSpeichern_Click(sender As Object, e As EventArgs) Handles btnSpeichern.Click
    2. If CheckControls(Me) Then
    3. ' Datum aus dem DateTimePicker auslesen
    4. Dim selectedDate As Date = dtpDatum.Value
    5. ' Speicherort aus den Einstellungen auslesen
    6. Dim settingsFilePath As String = Path.Combine(Application.StartupPath, "settings.xml")
    7. Dim xmlSettings As XDocument = XDocument.Load(settingsFilePath)
    8. Dim Datenverzeichnis As String = xmlSettings.<Settings>.<DataLocation>.Value
    9. ' Ordnerpfad generieren
    10. Dim monat = selectedDate.ToString("MMMM")
    11. Dim jahr = selectedDate.Year.ToString()
    12. Dim monatsOrdner = IO.Path.Combine(Datenverzeichnis, jahr, monat)
    13. If Not IO.Directory.Exists(monatsOrdner) Then
    14. IO.Directory.CreateDirectory(monatsOrdner)
    15. End If
    16. ' Kalenderwochen-Ordner anlegen
    17. Dim calendar As Calendar = CultureInfo.InvariantCulture.Calendar
    18. Dim kalenderwoche As Integer = calendar.GetWeekOfYear(selectedDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday)
    19. Dim kalenderwocheOrdner = "KW- " & kalenderwoche.ToString("D2")
    20. Dim kwOrdnerPfad = IO.Path.Combine(monatsOrdner, kalenderwocheOrdner)
    21. If Not IO.Directory.Exists(kwOrdnerPfad) Then
    22. IO.Directory.CreateDirectory(kwOrdnerPfad)
    23. End If
    24. 'Erstellen einer neuen Instanz von WetterWoche
    25. Dim neueWoche As New WetterWoche
    26. 'Erstellung eines neuen Wettertags und Zuweisung der eingegebenen Werte
    27. Dim neuerTag As New WetterTag
    28. neuerTag.Datum = dtpDatum.Value
    29. neuerTag.NiederschlagRegenTag = CDbl(txtNiederschlagRegenTag.Text)
    30. neuerTag.NiederschlagRegenNacht = CDbl(txtNiederschlagRegenNacht.Text)
    31. neuerTag.NiederschlagSchneeTag = CDbl(txtNiederschlagSchneeTag.Text)
    32. neuerTag.NiederschlagSchneeNacht = CDbl(txtNiederschlagSchneeNacht.Text)
    33. neuerTag.LuftfeuchtigkeitMinTag = CInt(txtLuftfeuchtigkeitMinMaxTag.Text.Split(CChar("/"))(0))
    34. neuerTag.LuftfeuchtigkeitMaxTag = CInt(txtLuftfeuchtigkeitMinMaxTag.Text.Split(CChar("/"))(1))
    35. neuerTag.LuftfeuchtigkeitMinNacht = CInt(txtLuftfeuchtigkeitMinMaxNacht.Text.Split(CChar("/"))(0))
    36. neuerTag.LuftfeuchtigkeitMaxNacht = CInt(txtLuftfeuchtigkeitMinMaxNacht.Text.Split(CChar("/"))(1))
    37. neuerTag.TemperaturTag = CDbl(txtTemperaturTag.Text)
    38. neuerTag.TemperaturNacht = CDbl(txtTemperaturNacht.Text)
    39. neuerTag.WindstaerkeTag = CDbl(txtWindstaerkeTag.Text)
    40. neuerTag.WindstaerkeNacht = CDbl(txtWindstaerkeNacht.Text)
    41. neuerTag.WettergeschehnTag = txtWettergeschehnTag.Text
    42. neuerTag.WettergeschehnNacht = txtWettergeschehnNacht.Text
    43. neuerTag.Luftdruck = CDbl(txtLuftdruck.Text)
    44. neuerTag.Windrichtung = txtWindrichtung.Text
    45. ' Hinzufügen des neuen Wettertags zur Liste
    46. wetterdaten.Add(neuerTag)
    47. ' Speichern der Wetterdaten in der XML-Datei
    48. Dim stadt As String = xmlSettings.<Settings>.<Location>.Value
    49. Dim dateiname As String = String.Format("{0}_{1}.xml", stadt, dtpDatum.Value.ToString("ddMMyyyy"))
    50. Dim filePath As String = Path.Combine(Datenverzeichnis, kwOrdnerPfad, dateiname)
    51. Dim wochXml As New XElement("Wetterwoche", New XAttribute("StadtName", stadt))
    52. ' Hinzufügen der Wetterdaten
    53. For Each Tag As WetterTag In wetterdaten
    54. Dim tagXml As New XElement("Wettertag",
    55. New XAttribute("Datum", Tag.Datum.ToString("yyyy-MM-dd")),
    56. New XElement("NiederschlagRegenTag", Tag.NiederschlagRegenTag),
    57. New XElement("NiederschlagRegenNacht", Tag.NiederschlagRegenNacht),
    58. New XElement("NiederschlagSchneeTag", Tag.NiederschlagSchneeTag),
    59. New XElement("NiederschlagSchneeNacht", Tag.NiederschlagSchneeNacht),
    60. New XElement("LuftfeuchtigkeitMinMaxTag", Tag.LuftfeuchtigkeitMinTag & "/" & Tag.LuftfeuchtigkeitMaxTag),
    61. New XElement("LuftfeuchtigkeitMinMaxNacht", Tag.LuftfeuchtigkeitMinNacht & "/" & Tag.LuftfeuchtigkeitMaxNacht),
    62. New XElement("TemperaturTag", Tag.TemperaturTag),
    63. New XElement("TemperaturNacht", Tag.TemperaturNacht),
    64. New XElement("WindstaerkeTag", Tag.WindstaerkeTag),
    65. New XElement("WindstaerkeNacht", Tag.WindstaerkeNacht),
    66. New XElement("WettergeschehnTag", Tag.WettergeschehnTag),
    67. New XElement("WettergeschehnNacht", Tag.WettergeschehnNacht),
    68. New XElement("Luftdruck", Tag.Luftdruck),
    69. New XElement("Windrichtung", Tag.Windrichtung))
    70. wochXml.Add(tagXml)
    71. Next
    72. ' Speichern der Wetterdaten
    73. wochXml.Save(filePath)
    74. MessageBox.Show("Die Wetterdaten wurden unter " & Environment.NewLine & filePath & Environment.NewLine & " erfolgreich gespeichert.", "Speichern erfolgreich", MessageBoxButtons.OK, MessageBoxIcon.Information)
    75. End If
    76. End Sub


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

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Zuallererst würde ich an deiner Stelle den Code weiter modularisieren.
    Konkret: du hast da sehr viele Werte, die eine Funktion dir als Objekt zurückliefern könnte.
    Das würde den Code schon mal leserlicher machen.

    Zu deinem eigentlichen Problem, dass du pro KW eine Datei hast:
    Ich schlage folgende Ordnerstruktur vor:

    Quellcode

    1. %AppData%/myprogram/
    2. jahr/
    3. kw01.xml
    4. kw02.xml
    5. ...


    In den XMLs kannst du dann folgende Datenstruktur anwenden, wenn du unbedingt ein eigenes Format verwenden willst:

    XML-Quellcode

    1. <week city="mycity" begindate="2023-01-02" enddate="2023-01-09" >
    2. <day date="2023-01-02" >
    3. <weather type="precipitation" unit="ml/m2" >200</weather>
    4. ...
    5. </day>
    6. </week>


    Alternativ, kannst du auch ein bereits existierendes Format wie dieses verwenden.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems

    Selbstständiger Softwareentwickler & IT-Techniker.
    Hi.

    Zum Thema anhängen an Datei.

    Als Erstes liest du das XML der Kalenderwoche ein, oder neu erstellen, falls nicht vorhanden.

    Das sollte dann in deinem Objekt eingelesen sein (denke in deinem Beispiel ist das "wochXml"),
    dann mit XML mit wochXml.Add(blabla....)
    und dann diese in die Datei speichern. (Was dann einem "Append" gleich kommt).

    Es ist sogar möglich, mit XML gezielt einzufügen, da muss aber mit "AddBefore" und Konsorten gemacht werden.

    Zum Thema Tag und Nacht, das ist redundant, dort könnte auch etwas gekürzt werden.
    Wenn zwei Objekte (für Tag/Nacht) angelegt werden, und diese dann mit einer Eigenschaft für Werte und
    einer zusätzlichen Eigenschaft für Tageszeit versehen wird.

    WetterTag.Tageszeit = "Morgens"
    WetterTag.TagesZeit = "Nachts" etc.

    Dann könnte es so aussehen...

    VB.NET-Quellcode

    1. neuerTag.NiederschlagRegen = CDbl(txtNiederschlagRegenTag.Text)
    2. neuerTag.NiederschlagSchnee = CDbl(txtNiederschlagSchneeTag.Text)
    3. ...
    4. neueNacht.NiederschlagRegen = CDbl(txtNiederschlagRegenNacht.Text)
    5. neueNacht.NiederschlagSchnee = CDbl(txtNiederschlagSchneeNacht.Text)
    6. ...


    Ist etwas schwammig formuliert, aber erst einlesen und dann .add() und zum Abschluss speichern der "KWxx.xml".

    Grüße aus HH :)
    Moin moin
    Danke erstmal.
    Ich habe es nun so gelöst.

    Spoiler anzeigen

    VB.NET-Quellcode

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

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

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