如何为许多Outlook子文件夹实现ItemChange?

时间:2018-04-26 03:34:41

标签: outlook outlook-vba

在Outlook的VBA模块中,我目前的代码如下:

Private WithEvents AAInboxItems As Outlook.Items
Private WithEvents AASentItems As Outlook.Items
Private WithEvents AADoneItems As Outlook.Items

Private Sub AAInboxItems_ItemChange(ByVal Item As Object)
    'Do Something
End Sub
Private Sub AASentItems_ItemChange(ByVal Item As Object)
    'Do Something
End Sub
Private Sub AADoneItems_ItemChange(ByVal Item As Object)
    'Do Something
End Sub

上面不是完整的代码,只是为了说明原理。这适用于我实现此功能的几个文件夹。

我想为收件箱的所有子文件夹提供此类事件。这应该是动态的。如果用户创建了一个新的子文件夹,那么我不想更改代码。 我希望在任何Outlook收件箱子文件夹中更改项目时触发事件。

这可能吗?怎么样?

编辑:根据Dmitry Streblechenko的回答,我尝试了以下操作,但它没有按照我的意愿去做 - 也许我没有做错。 事件触发但仅针对最后分配的文件夹而不是所有文件夹。 这是我的预期,但也许我做错了或不明白答案是正确的。我把这些信息放在这个问题中,因为它不符合对德米特里答案的评论。

以下是代码中最重要的部分。我留下了很多细节,以缩短它。基本上它可以工作,但只适用于一个文件夹。

Option Explicit
Global gbl_FolderItems(3) As Outlook.Items
Private WithEvents FolderItems As Outlook.Items

Private Sub Application_Startup()
    For intI = 1 To 3
        'This works only with the last folder
        'Set gbl_FolderItems(intI) = objGetFolderItems("Folder" & intI)
        'Set FolderItems = gbl_FolderItems(intI)

        'This works only with the last folder
        Set FolderItems = objGetFolderItems("Folder" & intI)
        Set gbl_FolderItems(intI) = FolderItems
    Next
End Sub

Private Function objGetFolderItems(strFolderShortName As String) As Outlook.Items
    Dim olApp As Outlook.Application
    Set olApp = Outlook.Application
    Dim objNS As Outlook.NameSpace
    Set objNS = olApp.GetNamespace("MAPI")
    Dim obj As Outlook.Items

    Select Case strFolderShortName
    Case "Folder1"
        Set obj = objNS.Folders("MyAccount").Folders("Inbox").Folders("Folder1").Items
    Case "Folder2"
        Set obj = objNS.Folders("MyAccount").Folders("Inbox").Folders("Folder2").Items
    Case "Folder3"
        Set obj = objNS.Folders("MyAccount").Folders("Inbox").Folders("Folder1").Folders("Folder3").Items
    End Select
    Set objGetFolderItems = obj
End Function

Private Sub FolderItems_ItemChange(ByVal Item As Object)
    Debug.Print "FolderItems_ItemChange(" & Item.Subject & ")"
End Sub

Private Sub FolderItems_ItemAdd(ByVal Item As Object)
    Debug.Print "FolderItems_ItemAdd(" & Item.Subject & ")"
End Sub

2 个答案:

答案 0 :(得分:1)

您可以考虑创建一个COM加载项。在这种情况下,您将能够动态订阅文件夹事件。有关详细信息,请参阅Walkthrough: Creating Your First VSTO Add-In for Outlook

您也可以考虑使用低级API - 扩展MAPI。有关详细信息,请参阅MAPI Notification Events。或者只使用该API周围的任何第三方包装,例如Redemption。

答案 1 :(得分:1)

声明单个WithEvents Items变量,遍历要跟踪的文件夹,分配Items变量,并将其存储在全局数组中。即使变量将在每次迭代时被覆盖,但所有文件夹都将被监视,因为所有不同的Items对象仍处于活动状态并引发事件,因为它们被数组引用。