Kalenderselektion in Textdatei speichern und lesen mit VB.NET
Hallo zusammen,
ich habe derzeit ein kleines Tool in Überlegung womit man in einer einfachen Kalendermaske (MonthCalendar) auf ein Datum klickt und diese dann in eine textdatei untereinander gespeichert werden.
Soweit so gut.
Das habe ich zurzeit eher einfach gelöst:
Zurzeit speicher ich also einfach die selektierten Tage in eine Textdatei.
Jetzt komm ich aber auf 2, ich nenne es mal, Probleme.
1. möchte ich das Visuel in der VB.NET Maske wiedergeben zb. der Tag farblich marktiert.
und
2. Wenn ich auf einen Tag klicke, der bereits abgespeichert ist, soll dieser wieder gelöscht werden.
Eine Lösung für 1tens fällt mir derzeit nicht ein, da VB.NET nicht viele Möglichkeiten gibt, den Kalender zu formatieren.
zu 2tens fällt mir derzeit nur die Möglichkeit ein, mit einer Schleife durch die Datei zu schauen und das Feld herauszusuchen und den Eintrag zu löschen. Was aber auf Dauer zu Performanceproblemen führen wird (denke ich zumindest).
Eine weitere Möglichkeit wäre eine Access-Datenbank einzubinden, aber ob sich das lohnt?
Oder fällte euch eine bessere Idee ein, die Daten zu speichern und zu laden?
Hintergrund ist, das ein Powershell Skript auf die erstellte Textdatei zugreifen und prüfen soll ob heute einer der hinterlegten Tage ist und das Skript ausführt oder schließt.
Ich danke euch schonmal für eure Tips
ich habe derzeit ein kleines Tool in Überlegung womit man in einer einfachen Kalendermaske (MonthCalendar) auf ein Datum klickt und diese dann in eine textdatei untereinander gespeichert werden.
Soweit so gut.
Das habe ich zurzeit eher einfach gelöst:
Public Class Form1
Dim DatumListe As String
Public Sub MonthCalendar1_DateSelected(sender As Object, e As DateRangeEventArgs) Handles MonthCalendar1.DateSelected
MonthCalendar1.MaxSelectionCount = 1
Dim Datum As String = MonthCalendar1.SelectionRange.Start.ToShortDateString() + vbNewLine
System.IO.File.AppendAllText("G:\FD_50_Bank\System\Zahltagskalender\Zahltage2.txt", Datum)
End Sub
End Class
Zurzeit speicher ich also einfach die selektierten Tage in eine Textdatei.
Jetzt komm ich aber auf 2, ich nenne es mal, Probleme.
1. möchte ich das Visuel in der VB.NET Maske wiedergeben zb. der Tag farblich marktiert.
und
2. Wenn ich auf einen Tag klicke, der bereits abgespeichert ist, soll dieser wieder gelöscht werden.
Eine Lösung für 1tens fällt mir derzeit nicht ein, da VB.NET nicht viele Möglichkeiten gibt, den Kalender zu formatieren.
zu 2tens fällt mir derzeit nur die Möglichkeit ein, mit einer Schleife durch die Datei zu schauen und das Feld herauszusuchen und den Eintrag zu löschen. Was aber auf Dauer zu Performanceproblemen führen wird (denke ich zumindest).
Eine weitere Möglichkeit wäre eine Access-Datenbank einzubinden, aber ob sich das lohnt?
Oder fällte euch eine bessere Idee ein, die Daten zu speichern und zu laden?
Hintergrund ist, das ein Powershell Skript auf die erstellte Textdatei zugreifen und prüfen soll ob heute einer der hinterlegten Tage ist und das Skript ausführt oder schließt.
Ich danke euch schonmal für eure Tips
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 464347
Url: https://administrator.de/forum/kalenderselektion-in-textdatei-speichern-und-lesen-mit-vb-net-464347.html
Ausgedruckt am: 28.04.2025 um 17:04 Uhr
5 Kommentare
Neuester Kommentar
Servus @Pat.bat ,
ach da gibt es so viele Möglichkeiten, aber eine Datenbank extra dafür wäre Overkill. Für solche einfachen Dinge eigenen sich heutzutage z.B. XML-Dateien in denen du Daten strukturiert ablegen kannst und welche du hinterher auch wieder strukturiert in PowerShell über ein [XML] Object auslesen kannst.
Da du offentlich in dem Bereich noch etwas unerfahren hantierst belasse ich es erst mal bei einem einfachen Beispiel das du mit etwas Lesen nachvollziehen können solltest:
(Methoden wie XMLSerialization von Objekten (z.B. von DataTables etc.) lasse ich hier mal explizit außen vor denke das wäre noch etwas zu viel für Dich, wäre aber aber eine effektivere Nutzung wenn es um mehr Daten geht als nur ein einfaches Datum)
(Errorhandling Try Catches etc. für das Beispiel weggelassen)
Das Beispiel benutzt zur Speicherung eine XML-Datei (im Beispiel im Temporären Ordner des Systems abgelegt). Diese wird beim Öffnen erzeugt sofern sie noch nicht existiert. Existiert sie wird sie eingelesen und die Datumswerte dem Kalender als BoldedDates hinzugefügt. Klick der Nutzer nun auf einen Tag oder einen Bereich der noch nicht fett markiert ist werden diese Datumswerte aus der XML-Datei erst einmal im Speicher hinzugefügt und das Datum fett markiert, existieren die Datumswerte werden sie stattdessen entfernt ebenso wie die Markierung.
Schließt der Anwender die Form wird die XML-Datei im Speicher auf die Platte geschrieben.
In Powershell kannst du die Daten aus der XML auch sehr schnell wieder auslesen
Kannst du ja nach Gusto anpassen und war nur ein Beispiel von vielen anderen Varianten besonders XMLSerialization bringt da nochmal mehr Komfort. Beispiele wie man sowas auch in Powershell handelt hatte ich hier schon mal im Zusammenhang mit DataTables gepostet.
Powershell Datagridview und XML Datenhaltung
Du kannst natürlich auch eine simple Textdatei dafür nutzen wenn du unbedingt willst, auslesen, in ein Array oder Collection speichern dann im Speicher mit den bekannten Methoden zum Suchen von Keys modifizieren und am Ende wieder zurückschreiben.
Grüße Uwe
Btw. du könntest die ganze Form auch direkt so wie in VB.Net mit Powershell erstellen wenn du möchtest, kenne aber deinen Workflow diesbezüglich nicht und wofür es zum Einsatz kommt.
ach da gibt es so viele Möglichkeiten, aber eine Datenbank extra dafür wäre Overkill. Für solche einfachen Dinge eigenen sich heutzutage z.B. XML-Dateien in denen du Daten strukturiert ablegen kannst und welche du hinterher auch wieder strukturiert in PowerShell über ein [XML] Object auslesen kannst.
Da du offentlich in dem Bereich noch etwas unerfahren hantierst belasse ich es erst mal bei einem einfachen Beispiel das du mit etwas Lesen nachvollziehen können solltest:
(Methoden wie XMLSerialization von Objekten (z.B. von DataTables etc.) lasse ich hier mal explizit außen vor denke das wäre noch etwas zu viel für Dich, wäre aber aber eine effektivere Nutzung wenn es um mehr Daten geht als nur ein einfaches Datum)
Imports System.Xml
Imports System.IO
Imports System.Xml.Serialization
Imports System.Globalization
Public Class Form1
Dim xmlDoc As New XmlDocument
' Pfad zum XML Dokument
Dim xmlPath As String = Environ("TEMP") & "\" & "daten.xml"
Private Sub MonthCalendar1_DateSelected(sender As Object, e As System.Windows.Forms.DateRangeEventArgs) Handles MonthCalendar1.DateSelected
Dim d As Date
' Für jedes slektierte Datum
For i = 0 To DateDiff(DateInterval.Day, e.Start, e.End)
d = e.Start.AddDays(i)
' Wenn das Datum bereits markiert ist
If MonthCalendar1.BoldedDates.Contains(d) Then
' entferne die Markierung
MonthCalendar1.RemoveBoldedDate(d)
Else
' Füge Markierung hinzu
MonthCalendar1.AddBoldedDate(d)
End If
' Aktualisiere XML im Speicher über Funktion welche Hinzufügen und Entfernen übernimmt
UpdateXML(d)
Next
' Aktualisiere markierte Datumswerte im Kalender
MonthCalendar1.UpdateBoldedDates()
End Sub
Private Sub Form1_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
' Speichere XML Datei im Dateisystem
xmlDoc.Save(xmlPath)
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
' Wenn XML Datei existiert lade die Datei und markiere die Werte im Kalender
If File.Exists(xmlPath) Then
Dim node As XmlNode
xmlDoc.Load(xmlPath)
For Each node In xmlDoc.SelectNodes("/Data/Date")
MonthCalendar1.AddBoldedDate(DateTime.ParseExact(node.InnerText, "dd\.MM\.yyyy", CultureInfo.InvariantCulture))
Next
MonthCalendar1.UpdateBoldedDates()
Else ' XML-Datei existiert noch nicht, erstelle das Gerüst der Datei im Speicher
Dim XmlDeclaration As XmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", Nothing)
xmlDoc.InsertBefore(XmlDeclaration, xmlDoc.DocumentElement)
Dim nodeRoot As XmlElement = xmlDoc.CreateElement("Data")
xmlDoc.AppendChild(nodeRoot)
End If
End Sub
' Methode die die XML-Datei im Speicher aktualisiert und die Datumswerte darin aktualisiert
Private Sub UpdateXML(ByVal d As Date)
Dim findNode As XmlElement = xmlDoc.DocumentElement.SelectSingleNode("/Data/Date[. = '" & d.ToString("dd\.MM\.yyyy") & "']")
If findNode Is Nothing Then
Dim nodeDate As XmlElement = xmlDoc.CreateElement("Date")
nodeDate.InnerText = d.ToShortDateString()
xmlDoc.DocumentElement.AppendChild(nodeDate)
Else
xmlDoc.DocumentElement.RemoveChild(findNode)
End If
End Sub
End Class
Das Beispiel benutzt zur Speicherung eine XML-Datei (im Beispiel im Temporären Ordner des Systems abgelegt). Diese wird beim Öffnen erzeugt sofern sie noch nicht existiert. Existiert sie wird sie eingelesen und die Datumswerte dem Kalender als BoldedDates hinzugefügt. Klick der Nutzer nun auf einen Tag oder einen Bereich der noch nicht fett markiert ist werden diese Datumswerte aus der XML-Datei erst einmal im Speicher hinzugefügt und das Datum fett markiert, existieren die Datumswerte werden sie stattdessen entfernt ebenso wie die Markierung.
Schließt der Anwender die Form wird die XML-Datei im Speicher auf die Platte geschrieben.
In Powershell kannst du die Daten aus der XML auch sehr schnell wieder auslesen
$xml = [xml](gc "D:\datei.xml")
$xml.Data.Date
Kannst du ja nach Gusto anpassen und war nur ein Beispiel von vielen anderen Varianten besonders XMLSerialization bringt da nochmal mehr Komfort. Beispiele wie man sowas auch in Powershell handelt hatte ich hier schon mal im Zusammenhang mit DataTables gepostet.
Powershell Datagridview und XML Datenhaltung
Du kannst natürlich auch eine simple Textdatei dafür nutzen wenn du unbedingt willst, auslesen, in ein Array oder Collection speichern dann im Speicher mit den bekannten Methoden zum Suchen von Keys modifizieren und am Ende wieder zurückschreiben.
Grüße Uwe
Btw. du könntest die ganze Form auch direkt so wie in VB.Net mit Powershell erstellen wenn du möchtest, kenne aber deinen Workflow diesbezüglich nicht und wofür es zum Einsatz kommt.
Keine Ursache.
Kommt halt auf den Anwendungszweck und das Projekt an.
Viele Erfolg weiterhin.
Grüße Uwe
Zitat von @Pat.bat:
Mit Powershell das ganze zu machen sehe ich als zu aufwändig, oder? Da ich mit der Zeit die Maske, wie schon erwähnt, noch mit Funktionen und Ansichten erweitern möchte.
Nicht wirklich, mit entsprechendem Projekt-Editor (wie z.B. von SAPIEN) ist das fast der gleiche Aufwand wie in VS.Mit Powershell das ganze zu machen sehe ich als zu aufwändig, oder? Da ich mit der Zeit die Maske, wie schon erwähnt, noch mit Funktionen und Ansichten erweitern möchte.
Kommt halt auf den Anwendungszweck und das Projekt an.
Unter umständen werde ich in Zukunft aber auf C# wechseln.
Würde ich dir auch sehr ans Herz legen.Viele Erfolg weiterhin.
Grüße Uwe
In der Tat hast du da noch etwas Verständnisprobleme beim Handling von XML-Knoten. Im Normalfall erstellt man die Knoten und hängt sie von der untersten Ebene an die nächst übergeordnete an und am Schluss dann den Teilbaum ins Dokument. Natürlich musst du bei obigem Beispiel auch noch die anderen Methoden beachten und anpassen.
Für currentProzess (Denglisch is in oder wat
) habe ich mal nur zur Demo einen statischen String gesetzt.
Im Normalfall macht man sowas über eine separate Klasse, die lässt sich dann auch gleichzeitig zur Serialization einsetzen und die Daten in eine Datatable/Collection or whatever laden und deren Methoden zum Hinzufügen und Entfernen nutzen.
Wie gesagt das war nur ein Basic-Sample und nichts großartig generalisiertes.
Für currentProzess (Denglisch is in oder wat
Imports System.Xml
Imports System.IO
Imports System.Xml.Serialization
Imports System.Globalization
Public Class Form1
Dim xmlDoc As New XmlDocument
Dim xmlPath As String = Environ("TEMP") & "\" & "daten.xml"
Dim currentProzess As String = "BlaBlup"
Private Sub MonthCalendar1_DateSelected(sender As Object, e As System.Windows.Forms.DateRangeEventArgs) Handles MonthCalendar1.DateSelected
Dim d As Date
For i = 0 To DateDiff(DateInterval.Day, e.Start, e.End)
d = e.Start.AddDays(i)
If MonthCalendar1.BoldedDates.Contains(d) Then
MonthCalendar1.RemoveBoldedDate(d)
Else
MonthCalendar1.AddBoldedDate(d)
End If
UpdateXML(d)
Next
MonthCalendar1.UpdateBoldedDates()
End Sub
Private Sub Form1_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
xmlDoc.Save(xmlPath)
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
If File.Exists(xmlPath) Then
Dim node As XmlNode
xmlDoc.Load(xmlPath)
For Each node In xmlDoc.SelectNodes("/Data/" & currentProzess & "/Date")
MonthCalendar1.AddBoldedDate(DateTime.ParseExact(node.InnerText, "dd\.MM\.yyyy", CultureInfo.InvariantCulture))
Next
MonthCalendar1.UpdateBoldedDates()
Else
Dim XmlDeclaration As XmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", Nothing)
xmlDoc.InsertBefore(XmlDeclaration, xmlDoc.DocumentElement)
Dim nodeRoot As XmlElement = xmlDoc.CreateElement("Data")
Dim nodeProzess As XmlElement = xmlDoc.CreateElement(currentProzess)
nodeRoot.AppendChild(nodeProzess)
xmlDoc.AppendChild(nodeRoot)
End If
End Sub
Private Sub UpdateXML(ByVal d As Date)
Dim findNode As XmlElement = xmlDoc.SelectSingleNode("/Data/" & currentProzess & "/Date[. = '" & d.ToString("dd\.MM\.yyyy") & "']")
If findNode Is Nothing Then
Dim nodeDate As XmlElement = xmlDoc.CreateElement("Date")
nodeDate.InnerText = d.ToShortDateString()
Dim nodeProzess As XmlElement = xmlDoc.SelectSingleNode("/Data/" & currentProzess)
If nodeProzess Is Nothing Then
nodeProzess = xmlDoc.CreateElement(currentProzess)
nodeProzess.AppendChild(nodeDate)
xmlDoc.DocumentElement.AppendChild(nodeProzess)
Else
nodeProzess.AppendChild(nodeDate)
End If
Else
findNode.ParentNode.RemoveChild(findNode)
End If
End Sub
End Class
Wie gesagt das war nur ein Basic-Sample und nichts großartig generalisiertes.