| |
VB.NET - Ein- und UmsteigerEreignis nur einmal täglich durchführen | | | Autor: stefanbla80 | Datum: 08.02.18 13:51 |
| Hallo zusammen,
Ich brauche einen „Denkanstoss“.
Mein Tool öffne ich täglich.
Immer wieder schließe ich dieses wegen Terminen, mache es dann wieder auf wenn ich es brauche.
In der „neuesten Version“ ist es nun so, dass ich mir von meiner ToDo-Liste die eingetragenen Stichworte per Mail schicke – mit jedem öffnen des Tools.
Frage: Gibt es einen „smarten“ und einfachen Weg, dass mir diese Mail nur einmal täglich (mit dem ersten Öffnen des Tools) gesendet wird.
Grüße
Stefan | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: Manfred X | Datum: 08.02.18 13:55 |
| Hallo!
Du könntest jeweils nach dem Senden der Mail das aktuelle Datum
in einer Settings-Variable speichern und stets vor dem Senden
den Inhalt dieser Variable prüfen - und ggf. das Senden stornieren. | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: stefanbla80 | Datum: 08.02.18 19:53 |
| Hallo Manfred,
Danke für Deine Idee.
Das ist mir schon irgendwie "klar" - jedoch wie mache ich das genau?
Wie lösche ich den Eintrag dann wieder, damit die "Datei" nicht voll wird?
Hilft ggf. eine Log_Routine?
Grüße
Stefan | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: stefanbla80 | Datum: 08.02.18 20:02 |
| Ich versuche das grad so:_
Nach dem Senden der Mail erstelle ich in einem Ordner eine Datei
Dim FiStr As FileStream = New FileStream( _
My.Application.Info.DirectoryPath & "\Data\MyNotes\" & user & _
"_MyNotesSend", FileMode.Create)
Dim StrWr As StreamWriter = New StreamWriter(FiStr)
StrWr.Close() Beim Aufrufen des Tools starte ich auch noch diese Abfrage ...
Public Sub Check_MyNotes_Send()
Dim strPath As String
Dim lngAge As Long
Dim lngAusgabe As Long
Dim strType As String
strPath = My.Application.Info.DirectoryPath & "\Data\MyNotes\"
lngAge = 1
strType = ""
lngAusgabe = DeleteFilesAfterXDays(strPath, lngAge, strType)
'Debug.Print("Es wurden " & lngAusgabe & " Dateien aus dem Ordner " &
' strPath & " gelöscht")
End Sub
' Löscht alle Dateien eines Ordners, die älter als x Tage sind
Public Function DeleteFilesAfterXDays(ByVal strFilePath As String, _
Optional ByVal lngFileAge As Long = 10, _
Optional ByVal strFileType As String = "") As Long
Dim lngDeletetFiles As Long
Dim dtmFileCreated As Date
Dim objFSO As Object
Dim objFolder As Object
Dim colFile As Object
Dim objFile As Object
' Fehlerbehandlung aktivieren
On Error GoTo ErrHandler
' Laufparameter für das Gesamtergebnis der gelöschten Dateien
lngDeletetFiles = 0
' Verweis auf das FileSystemObject erstellen
objFSO = CreateObject("Scripting.FileSystemObject")
' Verweis auf den übergebenen Pfad setzen
objFolder = objFSO.GetFolder(strFilePath)
' Verweis auf die Dateien im übergebenen Pfad setzen
colFile = objFolder.Files
' Schleife über alle Dateien im Ordner
For Each objFile In colFile
With objFile
' Prüfung nach dem Dateitypen, sprich der Dateiendung.
' Bei "" werden alle Dateien überprüft, ansonsten der
' an strFileType übergebene Dateityp, bestehend aus den
' letzten Buchstaben nach dem Punkt.
If Len(strFileType) = 0 Or _
Right$(.Name, Len(.Name) - InStrRev(.Name, "")) = strFileType _
Then
' Dateierstellungsdatum der Datei auslesen
dtmFileCreated = .DateCreated
' Datumdifferenz berechnen und mit der Anzahl der
' übergebenen Tagen in lngFileAge vergleichen
If DateDiff("d", dtmFileCreated, Now()) > lngFileAge Then
' Bei Überschreitung der Altersgrenze, wird die Datei
' gelöscht
.Delete()
lngDeletetFiles = lngDeletetFiles + 1
End If
End If
End With
Next
' Anzahl der gelöschten Dateien übergeben
DeleteFilesAfterXDays = lngDeletetFiles
ErrHandler:
' Objekte zerstören
objFolder = Nothing
objFSO = Nothing
colFile = Nothing
objFile = Nothing
End Function Grüße
Stefan | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: Franki | Datum: 09.02.18 03:29 |
| Hallo,
die Datei wird nicht "voll" sie braucht ja nur einen Eintrag zu enthalten nämlich den wann das letzte Mal ausgelesen / gesendet worden ist. Beim erneuten Senden wird dieser einzig vorhandene Eintrag einfach überschrieben.
Also erster Aufruf: Datum/Uhrzeit speichern
Zweiter Aufruf am gleichen Tag: Datei lesen, Datum auswerten, keine neue E-Mail senden, nichts an der Datei verändern.
Erster Aufruf am nächsten Tag: Datei lesen, Auswertung des Datums ergibt, dass es ein neuer Tag ist, dann E-Mail senden, den einzigen Eintrag in der Datei überschreiben (oder Datei neu erstellen) und dann alles von vorne.
In der Datei steht jeweils nur eine Zeile mit dem Datum/Uhrzeit wann zuletzt gesendet worden ist. Das funktioniert zuverlässig. Ausnahme ist evtl. nur die Zeitumstellung auf MSEZ und zurück. Ob das bei dir von Relevanz ist oder nicht mußt du selbst wissen, aber gut das wird sich evtl. von selbst erledigen, da ja laut EU die Sommerzeit auf den Prüfstand gestellt und evtl. abgeschafft wird.
Anstatt Datei kannst du auch eine Wert in den Settings, einer INI, der Registry, einer Datenbak, XML Datei oder sonst wo speichern. Du brauchst aber nur den einen Wert, mehr nicht.
Gruß
Frank | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: stefanbla80 | Datum: 10.02.18 14:03 |
| Hallo Frank,
so habe ich das nun gemacht.
Nach meinen ersten Tests scheint es zu funktionieren ...
Imports System.IO
Imports System.Xml
Module Module_ToDo
Dim Datum As String = Format$(Date.Today, "yyyy-MM-dd")
Dim Zeit As String = TimeOfDay.ToString("HH-mm-ss") 'AM/PM
Dim DateMyNotes As String = ""
Public Sub CreateEMail_ToDo()
If AccessToDoMail = True Then
ReadMySettingsMyNotes()
If Not DateMyNotes = Datum Then
If Form_PlanningGuide.TextBox_MyNotes.Text <> "" Then
Dim Outlook As Object
Dim olMail As Microsoft.Office.Interop.Outlook.MailItem
Dim TextTaskMail As String = ""
Outlook = CreateObject("Outlook.Application")
Dim a As Integer
TextTaskMail = "Hello " & currentUser_FirstName & vbNewLine _
& vbNewLine & "Herewith you will receive the summary of" & _
"your private 'MyNotes' from tabpage PinBoard (" & _
"PlanningGuide)." & _
vbNewLine & "Please check the details." & vbNewLine & _
"-----------------------------------------------------" & _
"-----------------------------------------------------" & _
"----" & vbNewLine & _
Form_PlanningGuide.TextBox_MyNotes.Text
TextTaskMail = Replace(TextTaskMail, vbCrLf, " <br> ", 1, _
-1, 1)
TextTaskMail = Replace(TextTaskMail, vbNewLine, " <br> ", _
1, -1, 1)
TextTaskMail = Replace(TextTaskMail, Chr(13), " <br> ", 1, _
-1, 1)
TextTaskMail = Replace(TextTaskMail, Chr(10), " <br> ", 1, _
-1, 1)
olMail = Outlook.CreateItem(a)
olMail.Subject = "MyNotes" & " - " & Datum & " " & Zeit & "" & _
"- " & currentUser_FirstName & " " & currentUser_LastName
olMail.HTMLBody = "<div style='font-size:11pt; font-family:" & _
"MetaPlusLF; '>" & TextTaskMail & "</div>"
'##########################################################
' ###############
'Mail To/CC
olMail.To = currentUser_LastName & " " & _
currentUser_FirstName
'Mail To/CC
'##########################################################
' ###############
olMail.Send()
Outlook = Nothing
olMail = Nothing
WriteMySettingsMyNotes()
End If
End If
End If
End Sub
Public Sub ReadMySettingsMyNotes()
Dim xml_Doc As XmlDocument
Dim xml_NodeLoad As XmlNode
Dim xml_PathMyNotes As String = My.Application.Info.DirectoryPath & _
"\Data" & "\PlanningGuideSettings_" & user & ".xml"
If IO.File.Exists(xml_PathMyNotes) Then
xml_Doc = New XmlDocument()
xml_Doc.Load(xml_PathMyNotes)
If (xml_Doc.SelectSingleNode( _
"Settings/UserSettings/MyNotes/Item_1") Is Nothing = False) Then
xml_NodeLoad = xml_Doc.SelectSingleNode( _
"Settings/UserSettings/MyNotes/Item_1")
If xml_NodeLoad.InnerText <> "" Then
DateMyNotes = xml_NodeLoad.FirstChild.Value
End If
End If
End If
End Sub
Public Sub WriteMySettingsMyNotes()
Dim xml_Doc As XmlDocument
Dim xml_NodeWrite As XmlNode
Dim xml_PathMyNotes As String = My.Application.Info.DirectoryPath & _
"\Data" & "\PlanningGuideSettings_" & user & ".xml"
Dim NodeText As String = ""
If IO.File.Exists(xml_PathMyNotes) Then
xml_Doc = New XmlDocument()
xml_Doc.Load(xml_PathMyNotes)
If (xml_Doc.SelectSingleNode( _
"Settings/UserSettings/MyNotes/Item_1") Is Nothing = False) Then
xml_NodeWrite = xml_Doc.SelectSingleNode( _
"Settings/UserSettings/MyNotes/Item_1")
xml_NodeWrite.InnerText = Datum
End If
xml_Doc.Save(xml_PathMyNotes)
End If
End Sub
End Module Grüße
Stefan | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: effeff | Datum: 10.02.18 15:01 |
| Du brauchst keine Extra-XML-Datei anzulegen. Es reicht, wie von ManfredX geschrieben, einfach nur das Datum in eine Anwendungsvariable zu schreiben. Dazu gehst Du in den Projekteinstellungen auf "Einstellungen" und änderst den neuen Eintrag ab. Dort steht noch "Setting" und Du änderst das z. B. auf "Datum". Als Format wählst Du "Datum". Den Rest lässt Du leer.
Du kann jetzt sehr einfach auf diese Variable zugreifen:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles _
Button2.Click
'Wert setzen
My.Settings.Datum = Format(Date.Now.ToString("dd.MM.yyyy",
CultureInfo.InvariantCulture))
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles _
Button3.Click
'Wert lesen
MessageBox.Show(My.Settings.Datum)
End Sub Du kannst Dir also den ganzen Aufwand, den Du betreibst, sparen...
EALA FREYA FRESENA | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: Franki | Datum: 11.02.18 03:35 |
| Hallo,
im Endeffekt ist es ja so, dass My.Settings auch nichts anderes macht als eine Datei zu erzeugen im Dateisystem die dann wieder gelesen, überschrieben usw. wird. Aus Sicht von Performance und Speicherplatz also kein nennenswerter Unterschied, ob man selbst eine Datei erzeugt oder das über Settings macht.
Aber mit eigenen Dateien zu arbeiten halte ich für mich persönlich für vorteilhafter und zwar aus folgenden Gründen:
Man ist einfach flexibler bei Multiuserbetrieb, Multirechnerbetrieb, Multistandordbetrieb usw. wenn man immer auf die gleiche Datei, bzw. deren Inhalt zugreifen möchte oder muss wenn man deren Standort kennt.
Diese Datei kann sogar auf einem Webserver, einer Cloud usw. ausgelagert werden, so dass sie für jegliche Konstellation verfügbar ist.
Ganz zu schweigen von Datensicherungen / Datenrücksicherungen, da ist das mit einer durch Windows oder .NET verwalteten Datei erheblich schwieriger bzw. unmöglich den vorherigen Zustand zeitnah wieder herstellen zu können.
Natürlich kommt es immer auf den Einzelfall der jeweiligen Anwendung an, aber grade bei meinen Anwendung die ich nur für Eigenbedaft brauche möchte ich felxibel sein und auch mal schnell auf einen anderen Rechner der meine Anwendung noch gar nicht kennt wechseln können. Also die Anwendung per Setup vom Stick installieren, die aktuelle Datensicherung auf diesen Rechner kopieren und ich habe in ein paar Minuten den aktuellen Stand auf fast jedem Rechner der Welt. Das geht mit Registry Einträgen oder Settings nicht wirklich.
Aber gut, wir schweifen vom Thema ab wir wissen nicht was genau gefordert ist in dieser Richtung usw.
Gruß
Frank | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: Manfred X | Datum: 11.02.18 11:48 |
| Hallo!
In Settings-Variable schreibt man Informationen,
die zur Einrichtung, Gestaltung oder Wahl der Funktionsweise
einer "App" genutzt werden - und die deshalb direkt mit
der "App" bzw. einem "App"-User verknüpft sind.
Man legt dort keine Daten ab, die durch die "App"
verarbeitet werden - die also keine inhaltliche Bedeutung besitzen,
die in einer direkten Beziehung zu einer bestimmten
"App" steht.
Diese Unterscheidung sollte prinzipiell beachtet werden.
Auf den Einzelfall kommt es dabei nicht an.
[I]Aus Sicht von Performance und Speicherplatz also kein nennenswerter
Unterschied, ob man selbst eine Datei erzeugt oder das über Settings macht.[/I]
Die Nutzung von Settings-Variablen hat nichts mit Performance
zu tun, sondern - wie oben dargelegt - ob ein Bezug zwischen Information
und "App" besteht.
Übrigens:
Wenn ein Programm "immer auf die gleiche Datei" zugreifen soll,
schreibt man deren [B]Pfad[/B] zweckmäßig in eine Settings-Variable.
Und noch eins:
Für den "Eigenbedarf" kann man (aus Bequemlichkeit) irgendwas
zusammenstöpseln. Das ist klar.
Ansonsten aber: Immer eine ordentliche Windows-Installationsroutine
verwenden (z.B. Click-Once)!
Dann werden auch Settings-Dateien oder Ressourcen auf dem Zielrechner
korrekt eingerichtet. | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: Franki | Datum: 12.02.18 02:26 |
| Hallo Manfred X
Zitat: | | Man legt dort keine Daten ab, die durch die App
verarbeitet werden - die also keine inhaltliche Bedeutung
besitzen, die in einer direkten Beziehung zu einer bestimmten
App steht. | |
Aber das Datum was in der Ausgangsfrage relevant ist hat doch eine inhaltliche Bedeutung für die App und oder den/die User. Du hast aber empfholen dieses Datum in die Settings zu schreiben.
Zitat: | |
Übrigens: Wenn ein Programm immer auf die gleiche Datei
zugreifen soll, schreibt man deren [B]Pfad[/B] zweckmäßig in eine
Settings-Variable.
| |
Ja das ist ein vernünftiger Weg, aber nur dann wenn der Pfad auch von überall erreichbar ist, bzw. von überall der gleiche Pfad aus den Settings ausgelesen werden kann bzw. aktuell ist.
Zitat: | |
Und noch eins: Für den Eigenbedarf kann man (aus Bequemlichkeit)
irgendwas zusammenstöpseln. Das ist klar. Ansonsten aber: Immer eine ordentliche Windows-Installationsroutine
verwenden (z.B. Click-Once)!
| |
Richtig, ich füge nachträglich noch drei Ausrufezeichen dazu, das galt aber schon immer seit es Windows gibt dass ein vernünftiges Setup unbedingt erforderlich ist. Und das wird sich wohl hoffentlich auch nie ändern.
Zitat: | |
Dann werden auch Settings-Dateien oder Ressourcen auf dem
Zielrechner korrekt eingerichtet. | |
Hier bin ich skeptisch: Denn welchen Inhalt haben denn die Settings Variablen bei bzw. nach einem Setup? Garantiert nicht den aktuellen Wert (in diesem Fall das Datum). Da muss die Anwendung erst mal auf den Pfad zur externen Datei zugreifen können, den auch erreichen können usw. Aber ist dann ja schon außerhalb der Settigns Variable selbst. Einen Pfad darin zu speichern ist OK, aber wenn der nichts anderes enthält als den Verweis zur externen Datei die wichtig ist bzw. deren Informationen ausgelesen werden sollen, dann ist das ein Schritt der immer schon gängig war und sich bis heute bewährt hat.
Und dennoch kommt es auf den Einzeilfall an, denn wie wir uns evtl. erinnern gab es mal in einem Song die Aussage, dass man einen Antrag auf die Erteilung eines Antragsformulars stellen muss...
Gruß
Frank | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: Manfred X | Datum: 12.02.18 08:50 |
| Hallo!
Zum hier vorliegenden Thema:
Dieser Datums-Wert ergibt sich aus der aktuellen App-Nutzung und muß deshalb
nicht "von irgendwo" geladen werden.
Allgemein:
Bei Settings handelt es sich um einen komfortablen Framework-"Automatismus",
der dem Programmierer eine Reihe von Aufgaben abnimmt, z.B.
- geordneter spezifischer Zugriff (normierte Systemordner)
- Datenbindung
- Typsicherheit und Defaultwerte
- Speicherung von Modifikationen
Diesen Komfort kannst Du auch nutzen, wenn Deine aktuellen Settings-Informationen
in einer Cloud abgelegt sind. Die entsprechende Settings-Datei kann von dort
geladen und im lokalen Dateisystem an die dafür vorgesehenen Stelle kopiert werden
(z.B. durch geeignete Gestaltung einer Installationsroutine). | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: Franki | Datum: 15.02.18 02:05 |
| Hallo ManfredX
Zitat: | |
Zum hier vorliegenden Thema:
Dieser Datums-Wert ergibt sich aus der aktuellen App-Nutzung
und muß deshalb nicht von irgendwo geladen werden. | |
In dem Fall hast du recht.
Wenn es sich um eine Einzelplatzanwendung handelt spielt das keine Rolle wo die Informationen gespeichert werden.
Zitat: | |
Allgemein:
Bei Settings handelt es sich um einen komfortablen
Framework-Automatismus, der dem Programmierer eine Reihe von Aufgaben abnimmt,
| |
Ja, aber genau diesen Automatismus gab es in der Vergangenheit ja auch, damals waren es *.ini Dateien die von Windows vorgegeben waren, dann wurde das durch Registry Einträge abgelöst in den verschiedenen Bereichen der Registry und heute sind es die Settings unter .NET. Da hat sich aber im Wesentlichen nichts dran geändert.
Aber immer schon war die Herausforderung wenn es sich um Mehrbenutzerbetrieb, MultiUserBetrieb oder gar Netzwerk handelte. Da mussten immer schon andere Lösungen her, da alle angeführten Speichermöglichkeiten sich immer mehr oder wenige auf den eigenen Rechner des jeweiligen Users bezogen haben.
Zitat: | |
Diesen Komfort kannst Du auch nutzen, wenn Deine aktuellen
Settings-Informationen in einer Cloud abgelegt sind. Die entsprechende
Settings-Datei kann von dort geladen und im lokalen Dateisystem an die dafür vorgesehenen Stelle kopiert werden
(z.B. durch geeignete Gestaltung einer
Installationsroutine). | |
Ja aber dann sind wir wieder beim Ausgangsthema, ob eine "normale" Datei gegenüber dem Settings Automatismus Vor- oder Nachteile bietet. Ich habe einige Projekte die von unterschiedlichen Anwendungen bedient werden. Es gibt Clients mit Vb.NET, andere mit VB6 und einige die per WebApp über Smartphone arbeiten (HTML5, CSS und JavaScript).
Das funktioniert hervorragend, die Datenbasis ist eine Datenbank die online erreichbar ist, zur Not auch lokal wenn alle im gleichen Netz sind. Aber für solch simple Sachen wie ein Datum zu synchronisieren möchte ich die DB nicht bemühen, das geht performanter über eine einfache Datei, sei es *.irgendwas
Die modernen Möglichkeiten sind da meiner Meinung nach völlig überzogen und bieten keinerlei Mehrwert, das ist mit Kanonen auf Spatzen geschossen.
Wenn mann den Mehrwert braucht, ok, wenn nicht, dann reicht auch Back to the roots, da fährt man oft besser mit.
Gruß
Frank | |
Re: Ereignis nur einmal täglich durchführen | | | Autor: Manfred X | Datum: 15.02.18 03:33 |
| Hallo!
Die Settings-Klassen sind für einen bestimmten Zweck konzipiert,
für den sie im Hinblick auf Standardisierung / Automatisierung
gegenüber INI-Dateien oder Registry-Schlüsseln erhebliche Vorteile
bieten (siehe oben).
Es handelt sich dabei aber nicht um eine Funktionalität, die Datenbanken
oder die Nutzung von Cloud-Speicher ersetzt. Dafür gibt es andere
Automatisierungs-Klassen.
Steuerungs-Informationen für ein Programm (z.B. Synchronisierung) sind
oft sensibel - es ist deshalb im Einzelfall zu prüfen, ob sie in einer
ONLINE erreichbaren einfachen Datei hinreichend sicher "verwahrt" werden
können (Authentifizierung). | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevISDN 1.0
Überwachung aller eingehender Anrufe!
Die DLL erkennt alle über die CAPI-Schnittstelle eingehenden Anrufe und teilt Ihnen sogar mit, aus welchem Ortsbereich der Anruf stammt. Weitere Highlights: Online-Rufident, Erkennung der Anrufbehandlung u.v.m. Weitere InfosTipp des Monats Neu! sevCommand 4.0
Professionelle Schaltflächen im modernen Design!
Mit nur wenigen Mausklicks statten auch Sie Ihre Anwendungen ab sofort mit grafischen Schaltflächen im modernen Look & Feel aus (WinXP, Office, Vista oder auch Windows 8), inkl. große Symbolbibliothek. Weitere Infos
|