procedure TForm1.SearchMicrosoftOutlookCalendarMeetingsAndAppointments(Sender: TObject);
var
StartHour, StartMinute, StartSecond, StartMilliSecond, EndHour, EndMinute, EndSecond, EndMilliSecond: Word;
Count, R: Integer;
StartDate, EndDate, TargetDate: TDate;
StartDateString, EndDateString, OutlookFindString: String;
Found: Boolean;
OutlookApplication, OutlookNameSpace, OutlookFolder, OutlookFolderAppointmentItems, OutlookAppointmentItem: Variant;
begin
//be sure ComObj and Variants units are included in the "uses" clause
//be sure StrUtils is included in the "uses" clause
StartHour := 0;
StartMinute := 0;
StartSecond := 0;
StartMilliSecond := 0;
EndHour := 0;
EndMinute := 0;
EndSecond := 0;
EndMilliSecond := 0;
Count := 0;
R := 0;
StartDate := StrToDate('10/1/2022'); //start of date window
EndDate := StrToDate('10/31/2022'); //end date for search window
EndDate := EndDate + 1; //make the search inclusive for the specified window
TargetDate := 0;
Found := False;
StartDateString := FormatDateTime('ddddd h:nn AMPM', StartDate);
EndDateString := FormatDateTime('ddddd h:nn AMPM', EndDate);
OutlookFindString := '([Start] >= "' + StartDateString + '" and [End] <= "' + EndDateString + '") or ' +
'([Start] <= "' + StartDateString + '" and [End] >= "' + EndDateString + '") or ' +
'([Start] <= "' + StartDateString + '" and [End] >= "' + StartDateString + '" and [End] <= "' + EndDateString + '") or ' +
'([Start] >= "' + StartDateString + '" and [Start] <= "' + EndDateString + '" and [End] >= "' + EndDateString + '")';
OutlookApplication := Null;
OutlookNameSpace := Null;
OutlookFolder := Null;
OutlookFolderAppointmentItems := Null;
OutlookAppointmentItem := Null;
try
//create Outlook OLE
OutlookApplication := CreateOleObject('Outlook.Application');
except
OutlookApplication := Null;
//add error/exception handling code as desired
end;
If VarIsNull(OutlookApplication) = False then
begin
try
OutlookNameSpace := OutlookApplication.GetNameSpace('MAPI');
OutlookNameSpace.Logon('', '', False, True);
OutlookFolder := OutlookNameSpace.GetDefaultFolder(9); //olFolderCalendar = 9
OutlookFolderAppointmentItems := OutlookFolder.Items;
OutlookFolderAppointmentItems.IncludeRecurrences := True; //False (not recommended) returns master items, but not recurrences
OutlookFolderAppointmentItems.Sort('[Start]', False); //True = descending; False = ascending
//references
//https://docs.microsoft.com/en-us/office/vba/api/Outlook.Items.IncludeRecurrences
//https://docs.microsoft.com/en-us/office/vba/api/outlook.items.sort
try
OutlookAppointmentItem := Null;
OutlookAppointmentItem := OutlookFolderAppointmentItems.Find(OutlookFindString);
//reference
//https://docs.microsoft.com/en-us/office/vba/api/outlook.items.find
repeat
If (VarIsNull(OutlookAppointmentItem) = False) and (VarIsEmpty(OutlookAppointmentItem) = False) then
begin
//be sure a Memo1 VCL object exists
Found := False;
//search for appointment/meeting titles/subjects
If (AnsiContainsText(OutlookAppointmentItem.Subject, 'lunch') = True) then Found := True; //change search word/phrase as appropriate
//Note: AnsiContainsText is case insensitive, use AnsiContainsStr for case sensitive searches, be sure to include StrUtils in the "uses" clause
//search for words/phrases in body of appointments/meetings
If (AnsiContainsText(OutlookAppointmentItem.Body, 'please') = True) then Found := True; //change search word/phrase as appropriate
//Note: AnsiContainsText is case insensitive, use AnsiContainsStr for case sensitive searches, be sure to include StrUtils in the "uses" clause
//search for appointments/meetings on a particular date
TargetDate := StrToDate('10/27/2022'); //change target date as appropriate
If DateOf(OutlookAppointmentItem.Start) = TargetDate then Found := True;
//search for appointments/meetings within a time window
DecodeTime(OutlookAppointmentItem.Start, StartHour, StartMinute, StartSecond, StartMilliSecond);
DecodeTime(OutlookAppointmentItem.End, EndHour, EndMinute, EndSecond, EndMilliSecond);
If (StartHour >= 16) and (EndHour <= 17) then Found := True; //change start and end hours as appropriate
//Note:
//Hour = 0..23
//Minute = 0..59
//Second = 0..59
//MilliSecond = 0..999
//search for required attendees
If (AnsiContainsText(OutlookAppointmentItem.RequiredAttendees, 'dave') = True) then Found := True; //change search name as appropriate
//Note: AnsiContainsText is case insensitive, use AnsiContainsStr for case sensitive searches, be sure to include StrUtils in the "uses" clause
//search for optional attendees
If (AnsiContainsText(OutlookAppointmentItem.OptionalAttendees, 'susan') = True) then Found := True; //change search name as appropriate
//Note: AnsiContainsText is case insensitive, use AnsiContainsStr for case sensitive searches, be sure to include StrUtils in the "uses" clause
//search for recipients who have tentatively accepted the appointment/meeting invitation
For R := 1 to OutlookAppointmentItem.Recipients.Count do
begin
If OutlookAppointmentItem.Recipients.Item(R).MeetingResponseStatus = 2 then //olResponseTentative = 2
begin
Found := True;
Memo1.Lines.Add(OutlookAppointmentItem.Recipients.Item(R).Name);
end;
end;
//search for recipients who have accepted the appointment/meeting invitation
For R := 1 to OutlookAppointmentItem.Recipients.Count do
begin
If OutlookAppointmentItem.Recipients.Item(R).MeetingResponseStatus = 3 then //olResponseAccepted = 3
begin
Found := True;
Memo1.Lines.Add(OutlookAppointmentItem.Recipients.Item(R).Name);
end;
end;
//search for recipients who have declined the appointment/meeting invitation
For R := 1 to OutlookAppointmentItem.Recipients.Count do
begin
If OutlookAppointmentItem.Recipients.Item(R).MeetingResponseStatus = 4 then //olResponseDeclined = 4
begin
Found := True;
Memo1.Lines.Add(OutlookAppointmentItem.Recipients.Item(R).Name);
end;
end;
//search for recipients who have not responded to the appointment/meeting invitation
For R := 1 to OutlookAppointmentItem.Recipients.Count do
begin
If OutlookAppointmentItem.Recipients.Item(R).MeetingResponseStatus = 5 then //olResponseNotResponded = 5
begin
Found := True;
Memo1.Lines.Add(OutlookAppointmentItem.Recipients.Item(R).Name);
end;
end;
//search for appointment/meeting locations
If (AnsiContainsText(OutlookAppointmentItem.Location, 'conference room') = True) then Found := True; //change the location as appropriate
//Note: AnsiContainsText is case insensitive, use AnsiContainsStr for case sensitive searches, be sure to include StrUtils in the "uses" clause
//search for cancelled appointments/meetings
If (OutlookAppointmentItem.MeetingStatus = 5) or (OutlookAppointmentItem.MeetingStatus = 7) or (AnsiContainsText(OutlookAppointmentItem.Subject, 'canceled') = True) then Found := True;
//olMeetingCanceled = 5
//olMeetingReceivedAndCanceled = 7
//search for appointment items without attendees
If OutlookAppointmentItem.MeetingStatus = 0 then Found := True;
//olNonMeeting = 0
If Found = True then
begin
Count := Count + 1;
Memo1.Lines.Add(IntToStr(Count) + #9 + OutlookAppointmentItem.Subject + #9 + DateTimeToStr(OutlookAppointmentItem.Start) + #9 + DateTimeToStr(OutlookAppointmentItem.End) + #9 + OutlookAppointmentItem.Location + #9 + BooleanToString(OutlookAppointmentItem.IsRecurring) + #9 + IntToStr(OutlookAppointmentItem.RecurrenceState));
end;
//reference
//https://docs.microsoft.com/en-us/office/vba/api/outlook.appointmentitem
end;
OutlookAppointmentItem := Unassigned;
OutlookAppointmentItem := OutlookFolderAppointmentItems.FindNext;
//reference
//https://docs.microsoft.com/en-us/office/vba/api/outlook.items.findnext
until (VarIsNull(OutlookAppointmentItem) = True) or (VarIsEmpty(OutlookAppointmentItem) = True);
except
//add error/exception handling code as desired
end;
finally
OutlookAppointmentItem := Unassigned;
OutlookFolderAppointmentItems := Unassigned;
OutlookFolder := Unassigned;
OutlookNameSpace := Unassigned;
OutlookApplication := Unassigned;
end;
end;
end;