代码之家  ›  专栏  ›  技术社区  ›  segmentation_fault

通过Outlook VBA仅获取今天的约会

  •  0
  • segmentation_fault  · 技术社区  · 4 年前

    我正在提取今天所有Outlook帐户中的所有约会。

    我在这篇文章中遇到了同样的问题 here ,但我正试图通过VBA来实现这一点。

    最初我设法获得了今天的预约,但它也会返回今天没有举行的重复会议(如链接问题中所示)。

    我不明白答案中的Powershell代码是如何过滤掉重复出现的约会的,因为在我的VBA尝试中,我得到了整整一周的约会。

    这是我的尝试。我已经包含了一个过滤器,用于获取今天的约会以及今天没有发生的重复约会。

    Sub GetAllCalendarAppointmentsForToday()
    
        Dim olApplication As Outlook.Application
        Dim olNamespace As NameSpace
        Dim olAccounts As Accounts
        Dim olStore As Outlook.Store
        Dim olCalendarFolder As Outlook.Folder
        Dim olCalendarItems As Outlook.Items
        Dim olTodayCalendarItems As Outlook.Items
        Dim strFilter As String
        Dim strFilter2 As String
        
        Set olApplication = CreateObject("Outlook.Application")
        Set olNamespace = olApplication.Session
        Set olAccounts = olNamespace.Accounts
        
        Debug.Print olAccounts.Count
        
        For Each oAccount In olAccounts
            Debug.Print oAccount
            Set olStore = oAccount.DeliveryStore
            Set olCalendarFolder = olStore.GetDefaultFolder(olFolderCalendar)
            
            Set olCalendarItems = olCalendarFolder.Items
            
            olCalendarItems.Sort "[Start]", True
            olCalendarItems.IncludeRecurrences = True
        
            Debug.Print olCalendarItems.Count
            
            'Find your today's appointments
            strFilter = Format(Now, "ddddd")
            strFilter2 = Format(DateAdd("d", 7, Now), "ddddd")
            Debug.Print strFilter
            Debug.Print strFilter2
            
            'strFilter = "[Start] > " & Chr(34) & strFilter & " 00:00" & Chr(34) & " AND [Start] < " & Chr(34) & strFilter & " 00:00" & Chr(34)
            strFilter = "[Start] > " & Chr(34) & strFilter & " 00:00" & Chr(34) & " AND [Start] < " & Chr(34) & strFilter2 & " 00:00" & Chr(34)
            Debug.Print strFilter
            
            Set olTodayCalendarItems = olCalendarItems.Restrict(strFilter)
            
            Debug.Print olTodayCalendarItems.Count
            
            Debug.Print "Begin Print of Appointments"
            For Each objAppointment In olTodayCalendarItems
                Counter = Counter + 1
                Debug.Print Counter & ":" & objAppointment.Subject & " " & objAppointment.Location & " [" & objAppointment.Start & "|" & objAppointment.End & "]"
            Next
            
            Debug.Print vbNewLine
        Next
    
    End Sub
    

    编辑#1: 根据尤金的回答,我更新了strFilter,但无济于事

    strFilter = [Start] <= '07/15/2020 11:59 PM' AND [End] >= '07/15/2020 12:00 AM'
    

    此外,我把 IncludeReccurence 也是第一,结果没有变化

    编辑#2 已更换 for each 循环使用 GetFirst() GetNext() 无济于事

    Set olTodayCalendarItems = olCalendarItems.Restrict(strFilter)
    Set olItem = olTodayCalendarItems.GetFirst()
    Do While Not olItem Is Nothing
        Set olAppointment = olItem
        counter = counter + 1
        Debug.Print counter & ":" & olAppointment.Subject & " " & olAppointment.Location & " [" & olAppointment.Start & "|" & olAppointment.End & "]"
        Set olItem = olTodayCalendarItems.GetNext()
    Loop
    

    编辑#3: 我创建了一个VB.NET应用程序,在那里我逐字逐句地使用了答案中链接中提供的函数,它按预期工作。所以,也许VBA中存在问题(不太可能),或者我在VBA脚本中遗漏了一些小东西?

    编辑#4: 问题一直存在于我的逻辑中。需要按升序排序的项目。谢谢尤金和尼顿

    0 回复  |  直到 4 年前
        1
  •  1
  •   niton    4 年前

    OP留下了一条评论,表示 Restrict 是有效的。

    “…关于IncludeRecurrences的文档链接…提到 .Sort 需要按升序完成”


    这是可能的 .Restrict 不适合此任务。

    使用示例 .Find .

    项目。IncludeRecurrences属性(Outlook) https://learn.microsoft.com/en-us/office/vba/api/outlook.items.includerecurrences

    Sub DemoFindNext()
    
        ' https://learn.microsoft.com/en-us/office/vba/api/outlook.items.includerecurrences
    
        Dim myNameSpace As Outlook.NameSpace
        Dim tdystart As Date
        Dim tdyend As Date
        Dim myAppointments As Outlook.Items
        Dim currentAppointment As Outlook.AppointmentItem
     
        Set myNameSpace = Application.GetNamespace("MAPI")
        
        tdystart = VBA.Format(Now, "Short Date")
        tdyend = VBA.Format(Now + 1, "Short Date")
     
        Set myAppointments = myNameSpace.GetDefaultFolder(olFolderCalendar).Items
     
        myAppointments.Sort "[Start]"
     
        myAppointments.IncludeRecurrences = True
     
        Set currentAppointment = myAppointments.Find("[Start] >= """ & tdystart & """ and [Start] <= """ & tdyend & """")
     
        While TypeName(currentAppointment) <> "Nothing"
            Debug.Print currentAppointment.Subject
            ' MsgBox currentAppointment.Subject
            Set currentAppointment = myAppointments.FindNext
        Wend
    
    End Sub
    
        2
  •  1
  •   Eugene Astafiev    4 年前

    微软不建议使用 Count 如果您设置了 IncludeRecurrences 财产。这个 计数 属性可能会返回意外结果并导致无限循环。在 How To: Use Restrict method in Outlook to get calendar items 文章。

    这是一个VB.NET代码示例,您可以在其中看到如何正确过滤约会项目:

    Imports System.Text
    Imports System.Diagnostics
    ' ...
    Private Sub RestrictCalendarItems(folder As Outlook.MAPIFolder)
        Dim dtEnd As DateTime = New DateTime(DateTime.Now.Year, DateTime.Now.Month, _
                                             DateTime.Now.Day, 23, 59, 0, 0)
        Dim restrictCriteria As String = "[Start]<=""" + dtEnd.ToString("g") + """" + _
                                         " AND [End]>=""" + DateTime.Now.ToString("g") + """"
        Dim strBuilder As StringBuilder = Nothing
        Dim folderItems As Outlook.Items = Nothing
        Dim resultItems As Outlook.Items = Nothing
        Dim appItem As Outlook._AppointmentItem = Nothing
        Dim counter As Integer = 0
        Dim item As Object = Nothing
        Try
            strBuilder = New StringBuilder()
            folderItems = folder.Items
            folderItems.IncludeRecurrences = True
            folderItems.Sort("[Start]")
            resultItems = folderItems.Restrict(restrictCriteria)
            item = resultItems.GetFirst()
            Do
                If Not IsNothing(item) Then
                    If (TypeOf (item) Is Outlook._AppointmentItem) Then
                        counter = counter + 1
                        appItem = item
                        strBuilder.AppendLine("#" + counter.ToString() + _
                                              " Start: " + appItem.Start.ToString() + _
                                              " Subject: " + appItem.Subject + _
                                              " Location: " + appItem.Location)
                    End If
                    Marshal.ReleaseComObject(item)
                    item = resultItems.GetNext()
                End If
            Loop Until IsNothing(item)
            If (strBuilder.Length > 0) Then
                Debug.WriteLine(strBuilder.ToString())
            Else
                Debug.WriteLine("There is no match in the " _
                                 + folder.Name + " folder.")
            End If
        catch ex As Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        Finally
            If Not IsNothing(folderItems) Then Marshal.ReleaseComObject(folderItems)
            If Not IsNothing(resultItems) Then Marshal.ReleaseComObject(resultItems)
        End Try
    End Sub