0

I mean to get all AppointmentItems in a Date range and return them as a Collection. This is the function I wrote

Function GetAppointmentItemsDatesRange(ByVal dstart As Date, ByVal dend As Date) As Outlook.Items
'=======================================================
' Get all AppointmentItem in a range of dates
'=======================================================

    Dim oCalendar As Outlook.Folder
    Set oCalendar = Application.Session.GetDefaultFolder(olFolderCalendar)
    
    Dim objItems As Outlook.Items
    Dim objRestrictedItems As Outlook.Items
    
    Set objItems = oCalendar.Items
    objItems.IncludeRecurrences = True
    'objItems.IncludeRecurrences = False
    objItems.Sort "[Start]"

    Dim filterRange As String
    filterRange = "[Start] >= " & Chr(34) & Format(dstart, "dd/mm/yyyy hh:mm AM/PM") & Chr(34) & " AND " & _
                  "[End] <= " & Chr(34) & Format(dend, "dd/mm/yyyy hh:mm AM/PM") & Chr(34)    ' <-- Line #1'
    Set objRestrictedItems = objItems.Restrict(filterRange)
    Debug.Print "Filter : " & filterRange
    
    Dim oItem As Outlook.AppointmentItem
    Dim iIt As Long
    Dim nItFilter As Long, nIt As Long
    nItFilter = objRestrictedItems.Count
    nIt = 0
    Debug.Print nItFilter & " total items"
    For Each oItem In objRestrictedItems
        If (Not (oItem Is Nothing)) Then
            nIt = nIt + 1
            Debug.Print oItem.Start & "-" & oItem.End    ' <-- Line #2'
        End If
    Next oItem
    Debug.Print nIt & " net items"

    Set GetAppointmentItemsDatesRange = objRestrictedItems

End Function

I tried with both .IncludeRecurrences = True and False. This is the output I get.

False:

Filter : [Start] >= "07/11/2020 05:30 PM" AND [End] <= "07/11/2020 06:15 PM"
9 total items
31/12/2015 9:00:00-31/12/2015 9:00:00
31/01/2017 15:30:00-31/01/2017 15:30:00
18/03/2020 12:00:00-18/03/2020 16:00:00
13/04/2020 8:45:00-13/04/2020 9:00:00
09/09/2020 11:00:00-09/09/2020 12:00:00
28/09/2020 14:45:00-28/09/2020 18:00:00
01/10/2020 13:30:00-01/10/2020 15:00:00
07/11/2020 17:30:00-07/11/2020 17:45:00
07/11/2020 17:45:00-07/11/2020 18:15:00
9 net items

True:

Filter : [Start] >= "07/11/2020 05:30 PM" AND [End] <= "07/11/2020 06:15 PM"
2147483647 total items
07/11/2020 17:30:00-07/11/2020 17:45:00
07/11/2020 17:45:00-07/11/2020 18:15:00
2 net items

So I identify two problems to get to my result:

  1. The outputs of Line #1 and Line #2 seem inconsistent, in both cases. I do not understand why are the first 7 items not filtered out in the False case, even if I can get rid of them with True. And I do not understand what are those too many Nothing items in the True case.
  2. I do not know hot to define a Collection where I can add the items that satisfy the If (Not (oItem Is Nothing)) condition, so I can return it upon exiting for the caller to use.

What is the explanation for the questions? How can I achieve my goal?

  • Please, look [here](https://learn.microsoft.com/en-us/office/vba/outlook/how-to/search-and-filter/search-the-calendar-for-appointments-within-a-date-range-that-contain-a-specific) how Microsoft recommend something similar. Forget about 'a Specific Word in the Subject'... – FaneDuru Nov 11 '20 at 10:58
  • @FaneDuru - A few comments: 1) `dstart` and `dend` are `Date`s, as per the function prototype. I am not sure how to otherwise do what you suggest. 2) I guess that is immaterial anyway. VBA does not care about how I build `filterRange`, which is a `String`. It only cares about its contents. 3) I had read the source you linked. So, I do not understand what you are specifically suggesting. Would you care for posting some code to illustrate this? Thanks – sancho.s ReinstateMonicaCellio Nov 11 '20 at 11:21
  • Sorry, I did not see the two variable like the function arguments. I will delete the comment. – FaneDuru Nov 11 '20 at 11:34
  • Hi, try changing this line `objItems.IncludeRecurrences = False` to `objItems.IncludeRecurrences = True`. I think what might be happening is that recurrent calendar events are still included as they appeared in that time range, but, are showing with originally scheduled time. Also, the format expected for the date string I believe is `ddddd hh:nn AMPM`, I think that needs to be updated too. – Ryan Wildry Nov 11 '20 at 12:40
  • @RyanWildry - I had tried that before, and I expanded my question accordingly. It might be an option for my needs, still have to complete it. – sancho.s ReinstateMonicaCellio Nov 11 '20 at 15:28
  • @sancho.sReinstateMonicaCellio - It looks like with `objItems.IncludeRecurrences = True` is giving the correct output, is that correct? – Ryan Wildry Nov 11 '20 at 15:35
  • @RyanWildry - Not really. The resulting collection seems to have n=2147483647 items (or there might be some misinterpretation on my side, as n=2^31-1, and it likely isn't a coincidence). So I have to filter many items out with my `If (Not (oItem Is Nothing))`. That would be ok, if I could use that to put together a collection to be returned from the function and used by the caller, as mentioned in the question. – sancho.s ReinstateMonicaCellio Nov 11 '20 at 16:22

1 Answers1

1

Since you found a way to identify the required items, add them to a new collection. Pass that collection to the caller.

Option Explicit

Sub collNotNothingItems()

Dim dtSt As Date
Dim dtEn As Date

Dim notNothingItems As Collection

Dim i As Long

dtSt = Date - 7
dtEn = Date

Set notNothingItems = GetAppointmentItemsDatesRange(dtSt, dtEn)

Debug.Print notNothingItems.count & " in the collection passed to the caller"

For i = 1 To notNothingItems.count
    With notNothingItems(i)
        Debug.Print .Start & "-" & .End
    End With
Next

End Sub


Function GetAppointmentItemsDatesRange(ByVal dstart As Date, ByVal dend As Date) As Collection
'=======================================================
' Get all AppointmentItem in a range of dates
'=======================================================

    Dim oCalendar As Folder
    
    Dim objItems As Items
    Dim objRestrictedItems As Items
    
    Dim filterRange As String
    
    Dim myItems As Collection
    
    Dim oItem As AppointmentItem
    
    Dim iIt As Long
    Dim nItFilter As Long
    Dim nIt As Long
    
    Set oCalendar = Application.Session.GetDefaultFolder(olFolderCalendar)
       
    Set objItems = oCalendar.Items
    objItems.IncludeRecurrences = True
    objItems.Sort "[Start]"

    'filterRange = "[Start] >= " & Chr(34) & Format(dstart, "dd/mm/yyyy hh:mm AM/PM") & Chr(34) & " AND " & _
                  "[End] <= " & Chr(34) & Format(dend, "dd/mm/yyyy hh:mm AM/PM") & Chr(34)
                  
    filterRange = "[Start] >= " & Chr(34) & Format(dstart, "yyyy-mm-dd hh:mm AM/PM") & Chr(34) & " AND " & _
                  "[End] <= " & Chr(34) & Format(dend, "yyyy-mm-dd hh:mm AM/PM") & Chr(34)
    
    Debug.Print "filterRange: " & filterRange
    
    Set objRestrictedItems = objItems.Restrict(filterRange)
    
    nItFilter = objRestrictedItems.count
    Debug.Print nItFilter & " total items"
    
    nIt = 0
    
    Set myItems = New Collection
    
    For Each oItem In objRestrictedItems
        If (Not (oItem Is Nothing)) Then
            nIt = nIt + 1
            Debug.Print oItem.Start & "-" & oItem.End
            
            myItems.Add oItem
            
        End If
    Next oItem
    
    Debug.Print nIt & " net items"
    
    Set GetAppointmentItemsDatesRange = myItems

End Function
niton
  • 8,771
  • 21
  • 32
  • 52
  • So I was missing the `New Collection` sentence... I would like to have as a return type `Outlook.Items` (more specific). Would you say I can simply replace `Collection` with `Outlook.Items`? – sancho.s ReinstateMonicaCellio Nov 13 '20 at 09:52
  • You could post a separate question with example code showing why returning items is preferable. – niton Nov 13 '20 at 13:07
  • It seems that was asked before... and it is only possible via a cumbersome implementation. https://stackoverflow.com/questions/29071174/create-an-items-collection-containing-references-to-already-existing-items https://stackoverflow.com/questions/5695977/restrict-type-in-a-collection-inside-a-class-module – sancho.s ReinstateMonicaCellio Nov 13 '20 at 13:47