PDA

Vollständige Version anzeigen : Erinnerungsfenster


coflo
02.10.2001, 17:36
Hallo Forum,

ich habe in einem Formular ein gebundenes Textfeld Termin(dort schreibe ich auch Termine rein) und möchte mir nun eine Funktion einbauen, die ein Erinnerungsfenster selbständig öffnet. Sobald der termin (Datum,Uhrzeit) herangerückt ist, soll dieses Fenster aufgehen und mir den Termin und die dazugehörige Firma ausgeben. Da ich eine laufende Übeprüfung brauche habe ich in Formulareigenschaft Timer folgendes:

Private Sub Form_Timer()
Dim rst As DAO.Recordset
Dim Meldung
Dim dummy As Variant

Meldung = ""
Set rst = CurrentDb.OpenRecordset("AbfrageTermin")
If Not (rst.BOF And rst.EOF) Then
rst.MoveFirst
While Not rst.EOF
Meldung = Meldung & _
IIf (Date(rst!Termin) = Date(Now()Then _
"Heute:", & Date(rst!Termin)&"." & rst!Firma
rst.MoveNext
Wend
rst.Close
dummy = MsgBox(Meldung, vbOKOnly + vbInformation, "Termin")
End If
Set rst = Nothing
End Sub

Es funktioniert aber nicht - kann mir jemand weiterhelfen?

MarioR
02.10.2001, 19:53
Hallo,

also grundsätzlich sehe ich bei Deiner Lösung einige Probleme:

1. Now() liefert Dir die Systemzeit auf die Sekunde genau. Damit musst Du die Prozedur einmal pro Sekunde (besser zweimal pro Sekunde) durchlaufen, damit Dir kein Termin durch die Lappen geht.
2. Damit sind wir schon beim nächsten Problem. Wenn Du recht viele DS in Deiner Tab hast, wird die Systemperformance gewaltig in die Knie gehen (vielleicht stürzt auch der Rechner ab).
3. Du musst sicher stellen, dass in Dein Textfeld Termin ein gültiges Datum und eine gültige Uhrzeit eingegeben wird (Ok, dass lässt sich sicher mit einer Formatvorgabe erledigen).


Vielleicht ein Lösungsansatz:

Wenn Dir eine Terminmeldung auf die Minute genau zureicht, dann lass die Prozedur nur aller 30s laufen. Weiterhin solltest Du ein Ja/Nein-Feld in die Tab aufnehmen, wo vermerkt wird, ob ein Termin bereits gemeldet wurde. Und das Programm könnte dann so aussehen (ich hoffe das funktioniert - so sicher bin ich mit Recordset nicht :)] ):


Private Sub Form_Timer()
Dim rst As DAO.Recordset
Dim Meldung
Dim dummy As Variant

Meldung = ""
Set rst = CurrentDb.OpenRecordset("AbfrageTermin")
If Not (rst.BOF And rst.EOF) Then
rst.MoveFirst
While Not rst.EOF
If (CDate(rst!Termin) < Now()) And (Not rst!gemeldet) Then
Meldung = Meldung & "Heute: " & rst!Termin & "." & rst!Firma
rst!gemeldet=True
rst.Update
End If
rst.MoveNext
Wend
rst.Close
dummy = MsgBox(Meldung, vbOKOnly + vbInformation, "Termin")
End If
Set rst = Nothing
End Sub


Ich hoffe, dass Dir meine geistigen Ergüsse etwas nützen. :D

coflo
02.10.2001, 21:02
Hallo Mario,

Danke, Dein lösungsansatz hat mich ein Stück weiter gebracht. Ich habe das Zeitintervall hoch gesetzt(30s)und mir noch ein gemeldet-Feld
eingefügt. Trotzdem wird nur einmal geprüft und dann Fehler 94 ;-((

mfg
Conny

AWSW
03.10.2001, 08:43
Morgen Conny,
probier doch mal noch ein ON ERROR einzufügen. Das hilft mir immer mehr als die Angabe dieser Fehlernummern... Außerdem sieht es für den User immer ziemlich kritisch aus, wenn da so ein ~Laufzeitfehler~ auftaucht...


Private Sub Befehl1_Click()
On Error GoTo Err_Befehl1_Click

...
Code
...

Exit_Befehl1_Click:
Exit Sub

Err_Befehl1_Click:
MsgBox "Fehler aufgetretn" & Chr(13) & Chr(13) & Err.Description, , "Fehler"

Resume Exit_Befehl1_Click
End Sub


Duirch die "Err.Description" sollte Dir von Access ein Hinweis gegeben werden, woran es hapert...

Ich hoffe das hilft Dir :D

MarioR
03.10.2001, 10:20
Hallo Conny,

ich denke mal, dass der Fehler durch CDate() ausgelöst wird. Die Funktion verträgt nämlich keine Null-Werte (also rst!Termin ist leer).

Änder das mal so ab:
... CDate(Nz(rst!Termin,Now())) ...

coflo
03.10.2001, 12:28
Hallo Mario,

es hat geklappt - rst!Termin war tatsächlich leer.
Jetzt wird mir aber pausenlos (alle 30s)die MsgBox aufgemacht. Ich habe zum Probieren ein paar Termine eingegeben und nun überschlägt sich die MsgBox bald ;-)), zeigt mir aber nur den Button OK und vbInformation an. Die Meldung fehlt. Ich hab aber auch geseheb, dass meine Systemzeit im Formular nicht richtig "mitläuft".
Vielleicht ist es günstiger, auf die Terminabfrage ein Formular zu setzen welches sich dann öffnet wenn ein Termin ansteht?
ich dachte, dass ich es unsichtbar in mein Hauptformular setze und es sich dann nur öffnet wenn die Zeit ran ist. Allerdings bin ich mir nicht so sicher, dass sowas auch funktioniert.

mfg Conny

MarioR
03.10.2001, 15:52
Das mit der Messagebox ohne Meldung ist logisch, aber solche Denkfehler findet man meistens erst beim Test raus :)

Änder mal den Programmcode so ab:


...
rst.Close
If Meldung<>"" Then
dummy = MsgBox(Meldung, vbOKOnly + vbInformation, "Termin")
End If
End If
...


Die Messagebox als Meldefenster zu nutzen find ich schon i.O. Die Frage ist bloss, wieviele Terminmeldungen gleichzeitig auftreten könnten (ich denk da z.B. an den Moment direkt nach dem Programmstart). Vielleicht wird da die Messagebox etwas überfrachtet. Das musst Du selbst einschätzen.

Outlook macht z.B. für jeden Termin ein extra Meldefenster auf. Vielleicht ist das eine bessere Lösung. Dann müsste der Code so aussehen:


Private Sub Form_Timer()
Dim rst As DAO.Recordset
Dim Meldung
Dim dummy As Variant
Set rst = CurrentDb.OpenRecordset("AbfrageTermin")
If Not (rst.BOF And rst.EOF) Then
rst.MoveFirst
While Not rst.EOF
If (CDate(Nz(rst!Termin,Now())) < Now()) And (Not rst!gemeldet) Then
Meldung = "Heute: " & rst!Termin & "." & rst!Firma
dummy = MsgBox(Meldung, vbOKOnly + vbInformation, "Termin")
rst!gemeldet=True
rst.Update
End If
rst.MoveNext
Wend
rst.Close
End If
Set rst = Nothing
End Sub

coflo
03.10.2001, 16:37
Nun geht gar kein Meldungsfenster mehr auf ;-((

mfg Conny

MarioR
03.10.2001, 17:19
Ungemeldete Termine liegen aber an, oder?

Was für ein Format hat den Dein Tab-Feld Termin?

coflo
03.10.2001, 17:34
Standarddatum und ja ungemeldete Termine sind eingetragen

coflo
03.10.2001, 17:47
Fehlermeldung bei
rst!gemeldet = True

rst!gemeldet zeigt als Wert Falsch an und Fehlermeldung lautet:

Update oder Cancelupdate ohne Addnew oder Edit (Laufzeitfehler 3020)

MarioR
03.10.2001, 18:42
Ja, Asche auf mein Haupt. Da fehlt noch ein Edit:


...
Meldung = Meldung & "Heute: " & rst!Termin & "." & rst!Firma
rst.Edit
rst!gemeldet=True
...

coflo
03.10.2001, 20:29
So, bin wieder da ;-))

Das Edit habe ich selbst noch reingesetzt- fiel mir dann auch auf, als die Fehlermeldung kam.
Habe erstmal den ersten Code genommen - da zeigt er mir aber alle Meldungen in einem Meldungsfenster an - wird furchtbar unübersichtlich. Ich denke, die zweite Form ist besser.
Ist es eigentlich günstig so ca. jede Minute einen Durchlauf zu starten - ich gehe mal davon aus, dass ich sehr,sehr viele Datensätze haben werde und denke mir, dass man dann eventuell das System lahm legt?

Auf jeden Fall: ich danke Dir für die tolle Hilfe!

mfg Conny

MarioR
03.10.2001, 21:29
Das mit der Systemlast hatte ich ja gestern schon erwähnt.

Aber mir ist gerade aufgefallen, dass Du ja eine Abfrage als Datengrundlage für Dein Recordset hast. Ich würde mal vorschlagen, dass Du in der Abfrage schon alle ungemeldeten Termine, die anliegen, ausfilterst. Damit musst Du bei jedem Schleifendurchlauf nicht mehr alle DS prüfen, sondern meldest nur noch die anstehenden Termine.

Viel Spass noch

Sascha Trowitzsch
03.10.2001, 23:27
Andere Möglichkeit wegen der Performance:

Beim Start der DB eine temporäre Tabelle mit Tabellenerstellungsabfrage anlegen, die nur die Datensätze (Termine) für den heutigen Tag enthält. Das sind doch wahrscheinlich nicht so viele.
Diese Tabelle für die Abfrage 'AbfrageTermin' benutzen.
Sonst Marios Code benutzen.

(Anmerkung zu Tabellenerstellungsabfrage:
Zuvor bereits vorhandene Temp-Tabelle löschen oder DoCmd.SetWarnings false vorschalten.)

Ciao, Sascha

coflo
04.10.2001, 08:18
Guten Morgen Mario und Sascha,

ich lasse mir nur die ungemeldeten Termine in der Abfrage anzeigen - es funktioniert ;-))))!
Das mit der temp-tabelle werde ich trotzdem mal im Hinterkopf behalten.

mfg Conny

MarioR
04.10.2001, 11:38
Noch 'ne Anmerkung zu den Tabellenerstellungsabfragen.
Das hat den Nachteil, dass Du mit der temporären Tabelle nach und nach Deine DB aufbläst. Dann musst Du in regelmässigen Abständen die DB wieder komprimieren.