Working off of my existing demo and previous posts:


I wanted to share 2 routines I’ve created for searching/listing events in a calendar.
Events Between 2 Dates
My first curiosity was to be able to retrieve a listing of events for a day, week, …
It didn’t take long for me to discover Microsoft had planned for this need with a URL just for that need
https://graph.microsoft.com/v1.0/me/calendar/calendarView
With that we needed only to apply the necessary filter and it resulted in:
'---------------------------------------------------------------------------------------
' Procedure : Outlook_Calendar_ListEvents
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Find events between 2 date/times
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: None required
' References:
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' dtStart
' dtEnd
'
' Usage:
' ~~~~~~
' ? Outlook_Calendar_ListEvents(#2023-05-28#, #2023-05-28#)
'
' ? Outlook_Calendar_ListEvents(#2024-05-28 8:00:00#, #2024-05-31 11:59:59#)
'
' Revision History:
' Rev Date(yyyy-mm-dd) Description
' **************************************************************************************
' 1 2024-05-30
'---------------------------------------------------------------------------------------
Public Function Outlook_Calendar_ListEvents(ByVal dtStart As Date, _
ByVal dtEnd As Date)
On Error GoTo Error_Handler
Dim sContentType As String
Dim sURL As String
Dim Parsed As Dictionary
Dim Values As Variant
Dim Value As Dictionary
Dim varKey As Variant
Dim i As Long
Dim sFilter As String
If OAuth2.access_token = "" Then OAuth2_StoredCredentials_Load 'Make sure we have credential before proceeding
If OAuth2_CheckToken = False Then DoCmd.OpenForm sAuthenticationForm, , , , , acDialog 'Force authentication if req'd
sContentType = "application/json"
sURL = "https://graph.microsoft.com/v1.0/me/calendar/calendarView" '?startDateTime={start_datetime}&endDateTime={end_datetime}
If sFilter <> "" Then sFilter = sFilter & " and "
sURL = sURL & "?startDateTime="
sURL = sURL & Format(SC_GetUTCComponent(dtStart), "yyyy-mm-ddThh:nn:ssZ") '"2024-04-28T23:02:33.922Z"
sURL = sURL & "&endDateTime="
sURL = sURL & Format(SC_GetUTCComponent(dtEnd), "yyyy-mm-ddThh:nn:ssZ") '"2024-06-04T23:02:33.922Z"
'Debug.Print sURL
'Call HTTP_SendRequest(sURL, "GET", sContentType, , True)
Call HTTPServer_SendRequest(sURL, "GET", sContentType, , True)
'Call WinHttp_SendRequest(sURL, "GET", sContentType, , True)
If lHTTP_Status = 200 Then
Set Parsed = JsonConverter.ParseJson(sHTTP_ResponseText)
If Parsed("value").Count = 0 Then
MsgBox "No matching events found."
GoTo Error_Handler_Exit
End If
ReDim Values(Parsed("value").Count, Parsed("value")(1).Count)
For Each Value In Parsed("value")
i = i + 1
Debug.Print "Event " & i, Parsed("value")(i)("subject"), ParseIso(Parsed("value")(i)("start")("dateTime")), ParseIso(Parsed("value")(i)("end")("dateTime")), Parsed("value")(i)("id")
Next Value
'Debug.Print sHTTP_ResponseText
Else
Debug.Print lHTTP_Status
Debug.Print "--------"
Debug.Print sHTTP_ResponseText
End If
Error_Handler_Exit:
On Error Resume Next
Set Parsed = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Source: Outlook_Calendar_ListEvents" & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
Calling by doing something like:
? Outlook_Calendar_ListEvents(#2024-05-28 8:00:00#, #2024-05-31 23:59:59#)
will result in an output in the immediate window like:
Event 1 Test 01 5/29/2024 8:00:00 AM 5/29/2024 8:30:00 AM AQMkADhmYTcwNWQ3LTVmYjYtNGZiYS1iMTA4LTYzNWRmOGY5YmZkZgBGAAADfxvXFvzp9UCXYhIfD_cZSAcALSyIhh6NNE2r2i-iLd5VAwAAAgEOAAAALSyIhh6NNE2r2i-iLd57VAwAJKpvtgAAAA== Event 2 Test 02 5/31/2024 10:00:00 AM 5/31/2024 12:00:00 PM AQMkADhmYTcwNWQ3LTVmYjYtNGZiYS1iMTA4LTYzNWRmOGY5YmZkZgBGAAADfxvXFvzp9UCXYhIfD_cZSAcALSyIhh6NNE2r2i-iLd5VAwAAAgEOAAAALSyIhh6NNE2r2i-iLd57VAwAJKpvtQAAAA==
Searching Beyond Just Dates
But what if I wanted to search for something else that just the date/time? What if I wanted to search the Subjects for a Term and retrieve those events?
Sadly, the above does not provide for that, but we do still have options! We can revert back to the default events URL:
https://graph.microsoft.com/v1.0/me/events
and apply a filter on it. Thus, resulting in a procedure like:
'---------------------------------------------------------------------------------------
' Procedure : Outlook_Calendar_FindAll
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Retrieve event(s) matching the search criteria
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: None required
' References:
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sSubject :
' dtStart :
' dtEnd :
' sReturnedColumns :
'
' Usage:
' ~~~~~~
' ? Outlook_Calendar_FindAll( , #5/31/2024 10:00:00 AM#, #5/31/2024 12:00:00 PM#)
'
' ? Outlook_Calendar_FindAll("Test")
'
' Revision History:
' Rev Date(yyyy-mm-dd) Description
' **************************************************************************************
' 1 2024-05-30
'---------------------------------------------------------------------------------------
Public Function Outlook_Calendar_FindAll(Optional ByVal sSubject As String, _
Optional ByVal dtStart As Date, _
Optional ByVal dtEnd As Date, _
Optional sReturnedColumns As String)
'$search is not supported!
On Error GoTo Error_Handler
Dim sContentType As String
Dim sURL As String
Dim Parsed As Dictionary
Dim Values As Variant
Dim Value As Dictionary
Dim varKey As Variant
Dim i As Long
Dim sFilter As String
If OAuth2.access_token = "" Then OAuth2_StoredCredentials_Load 'Make sure we have credential before proceeding
If OAuth2_CheckToken = False Then DoCmd.OpenForm sAuthenticationForm, , , , , acDialog 'Force authentication if req'd
sContentType = "application/json"
sURL = "https://graph.microsoft.com/v1.0/me/events"
If sSubject <> "" Then
If sFilter <> "" Then sFilter = sFilter & " and "
'sFilter = sFilter & "subject eq '" & sSubject & "'" 'Exact match
sFilter = sFilter & "contains(subject,'" & sSubject & "')" 'includes the specified term
End If
' '*********************** NOT SUPPORTED!!! *******************************
' If sBody <> "" Then
' If sFilter <> "" Then sFilter = sFilter & " and "
' sFilter = sFilter & "contains(body/content,'" & sBody & "')"
' End If
If dtStart <> #12:00:00 AM# Then
If sFilter <> "" Then sFilter = sFilter & " and "
sFilter = sFilter & "start/dateTime ge '" & Format(SC_GetUTCComponent(dtStart), "yyyy-mm-ddThh:nn:ssZ") & "'"
End If
If dtEnd <> #12:00:00 AM# Then
If sFilter <> "" Then sFilter = sFilter & " and "
sFilter = sFilter & "end/dateTime le '" & Format(SC_GetUTCComponent(dtEnd), "yyyy-mm-ddThh:nn:ssZ") & "'"
End If
sURL = sURL & "?$filter=" & sFilter
If sReturnedColumns = "" Then
sURL = sURL & "&$select=id,subject,start,end"
Else
sURL = sURL & "&$select=" & sReturnedColumns
End If
'Debug.Print sURL
'Call HTTP_SendRequest(sURL, "GET", sContentType, , True)
Call HTTPServer_SendRequest(sURL, "GET", sContentType, , True)
'Call WinHttp_SendRequest(sURL, "GET", sContentType, , True)
If lHTTP_Status = 200 Then
Set Parsed = JsonConverter.ParseJson(sHTTP_ResponseText)
If Parsed("value").Count = 0 Then
MsgBox "No matching events found."
GoTo Error_Handler_Exit
End If
ReDim Values(Parsed("value").Count, Parsed("value")(1).Count)
For Each Value In Parsed("value")
i = i + 1
Debug.Print "Event " & i, Parsed("value")(i)("subject"), ParseIso(Parsed("value")(i)("start")("dateTime")), ParseIso(Parsed("value")(i)("end")("dateTime")), Parsed("value")(i)("id")
Next Value
'Debug.Print sHTTP_ResponseText
Else
Debug.Print lHTTP_Status
Debug.Print "--------"
Debug.Print sHTTP_ResponseText
End If
Error_Handler_Exit:
On Error Resume Next
Set Parsed = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Source: Outlook_Calendar_FindAll" & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
With the above, you can:
- Search for events within a date/time range
- Search for events with a term in the Subject
- Both
I also wanted to provide the means to search for terms in the event body, but sadly this is not currently possible with the Graph API at this time.
This procedure can easily be further expanded to permit searching other columns (location, attendees, …) something I will explore further, time permitting, but I did want to share with you the basic principle.