I want to set an alert at a selected time and date of the calendar and be notified then. How can I do that? I thought of using a timer and, at 00:00 hour, calculate all timers and set them at the required intervals. But I wonder if there is an easier way...
Asked
Active
Viewed 505 times
0

Andreas Rejbrand
- 105,602
- 8
- 282
- 384

Marus Gradinaru
- 2,824
- 1
- 26
- 55
-
5Run a scheduled task and leave it to the OS to worry about whether the system time is synced? – MartynA Jul 01 '20 at 20:14
-
4Timers are inherently inaccurate, so don't recalculate their intervals, just let them run normally and check the current clock time at regular intervals. Otherwise, use the [Task Scheduler](https://learn.microsoft.com/en-us/windows/win32/taskschd/task-scheduler-start-page) API and let the OS notify your app when the target time arrives. – Remy Lebeau Jul 01 '20 at 21:42
-
But when the time comes, this Task Scheduler notify my application silenly, an let me decide what to do, or it alert directly the user ? – Marus Gradinaru Jul 02 '20 at 07:35
-
@MarusNebunu: It is certainly possible to make it notify your app, so that you can decide exactly what should happen. Hopefully someone will write an A with a simple example for you. – Andreas Rejbrand Jul 02 '20 at 09:11
-
The Jedi library has a component for setting up scheduled tasks - see the 2nd & 3rd answers in the duplicated q. – MartynA Jul 02 '20 at 11:09
1 Answers
1
I use it with Timer as you say. I leave the codes below to help you.
The logic of the codes is this; the user sets a date and time. Then, every time a record is entered or the application is opened, this information is refreshed from the database. It is added to a StringList. You can use the onAfterOpen or onAfterPost events for this add and refresh event.
procedure TfrmMain.listUpdate;
begin
listAlerts.Clear;
with QryTemp do
begin
Close;
SQL.Clear;
SQL.Text := 'SELECT * FROM tblAlerts';
Open;
First;
while not Eof do
begin
listAlerts.Add(FieldByName('alertDateTime').Value);
Next;
end;
end;
end;
Then Timer becomes active and continually refreshes the StringList object. If any data matches the current time and date, it shows the alarm.
procedure TfrmMain.controlTimer(Sender: TObject);
var
I: Integer;
begin
for I := 0 to listAlerts.Count - 1 do
begin
if DateTimeToStr(Now) = listAlerts.Strings[I] then
begin
ShowMessage('Alert!');
end;
end;
end;
Of course this is simply thought out, you can develop it as you wish. Here I just tried to help with the codes. Maybe you can find a better technique. I added as an option.

Halil Han BADEM
- 208
- 1
- 15
-
3There are several issues with this code and A: (1) You shouldn't use `ProcessMessages`. (2) You forgot to specify the properties of the `TTimer` object. (3) `DateTimeToStr` will use the local date format, so the app will only work on some systems, and might suddenly stop working if the OS's national settings are changed. (4) Really no need to involve SQL in a Q that doesn't mention databases at all. (5) The line `if not (listAlerts.Count <= 0)` has no effect (can you see why?). (6) `not listAlerts.Count <= 0` is parsed as `(not listAlerts.Count) <= 0` which is very much NOT what you want. – Andreas Rejbrand Jul 02 '20 at 09:00
-
@AndreasRejbrand 1) I made an arrangement. It was a code snippet in my old application. 2) Since I have received the relevant parts, I did not receive the details. 3) This subject is based on my inexperience :) 4) I sent it only as an example. Codes are quoted from an old project. 5, 6) Yes, you are right. I sent the codes without checking. My fault. Thank you for your warnings. – Halil Han BADEM Jul 02 '20 at 19:47