【问题标题】:How to uniquely identify an Outlook email as MailItem.EntryID changes when email is moved如何在移动电子邮件时将 Outlook 电子邮件唯一标识为 MailItem.EntryID 更改
【发布时间】:2015-04-28 04:36:27
【问题描述】:

我的公司使用一个电子邮件地址供客户发送请求和订单。我们创建了一个将电子邮件导入表的 Access 数据库。该表为导入的每封电子邮件创建自己的唯一标识符,但不应两次导入电子邮件。系统正常工作,因为我们只关心进入收件箱的电子邮件,不需要其他任何东西。

但是,我们现在需要知道该帐户所在的电子邮件池的“流量”、“流量”和“工作量”。进入收件箱的电子邮件被分类,然后移动到一个名为“my_tasks”的文件夹和一个子文件夹,该文件夹被命名为经理要处理的四个 CSR 之一。然后处理此电子邮件,CSR 将其移至另一个名为“已完成”的文件夹下的子文件夹。

因此,电子邮件进入收件箱,移至 my_tasks\joeblow 处理并移至 Completed\Canada。

目前我有代码可以遍历文件夹并找到每封电子邮件,获取我们要存储的字段,然后将它们插入表中。所有这些都是通过 VBA 代码在 Access 中完成的。

Private Sub ImportEmailItem(objMailItem As Outlook.MailItem)
On Error GoTo ImportEmailItem_Error

    ' Set up DAO objects
    Dim rstMB As DAO.Recordset
    Dim dskippedFolderMailCount As Double
    Dim strSQLrMB As String

    strSQLrMB = "SELECT * FROM tblMailBox WHERE OLID='" & objMailItem.EntryID & "'"

    Set rstMB = CurrentDb.OpenRecordset(strSQLrMB)

        With rstMB
            If Not .BOF And Not .EOF Then

                .MoveLast
                .MoveFirst
                While (Not .EOF)
                    If .Updatable Then
                        .Edit
                            rstMB!Subject = objMailItem.Subject
                            rstMB!Body = objMailItem.Body

                            Call subCategory(objMailItem)

                            rstMB!CSR = IIf(Len(objMailItem.Categories) = 0, "Unassigned", objMailItem.Categories)
                            rstMB!Importance = objMailItem.Importance
                            rstMB!Region = objMailItem.Parent
                            rstMB!DateModified = objMailItem.LastModificationTime
                            rstMB!FlagCompleted = objMailItem.FlagRequest
                            rstMB!folder = objMailItem.Parent
                            rstMB!Path = objMailItem
                        .Update
                    End If
                .MoveNext
                Wend
            Else
                rstMB.AddNew
                    rstMB!olid = objMailItem.EntryID
                    rstMB!ConversationIndex = objMailItem.ConversationIndex
                    rstMB!ConversationID = objMailItem.ConversationID
                    rstMB!Conversation = objMailItem.ConversationTopic
                    rstMB!To = Left(objMailItem.To, 250)
                    rstMB!CC = Left(objMailItem.CC, 250)
                    rstMB!Subject = objMailItem.Subject
                    rstMB!Body = objMailItem.Body

                    Call subCategory(objMailItem)

                    rstMB!CSR = IIf(Len(objMailItem.Categories) = 0, "Unassigned", objMailItem.Categories)
                    rstMB!Importance = objMailItem.Importance
                    rstMB!From = objMailItem.SenderEmailAddress
                    rstMB!Region = objMailItem.Parent
                    rstMB!DateReceived = objMailItem.ReceivedTime
                    rstMB!DateSent = objMailItem.SentOn
                    rstMB!DateCreated = objMailItem.CreationTime
                    rstMB!DateModified = objMailItem.LastModificationTime
                    rstMB!FlagCompleted = objMailItem.FlagRequest
                    rstMB!folder = objMailItem.Parent
                rstMB.Update
            End If
            .Close
        End With

ImportEmailItem_Exit:
    Set rstMB = Nothing
    Exit Sub

ImportEmailItem_Error:
    Debug.Print Err.Number & " " & Err.Description

    Select Case Err.Number
        Case 91
            Resume Next
        Case 3022
            Resume Next
        Case -2147221233
            MsgBox "Customer Care Account Name is incorrect, please enter the Mail box name as seen in your outlook client.", vbOKOnly, "Mail Folder Name Error"
            Me.txtMailAccountName.SetFocus
            Exit Sub
        Case Else
            MsgBox "Error #: " & Err.Number & "  " & Err.Description '& Chr(13) + Chr(10) & IIf(mail.Subject Is Null, "", mail.Subject) & " " & IIf(mail.ReceivedTime Is Null, "", mail.ReceivedTime)
'            DoCmd.RunSQL "INSERT INTO tblImportReport(ImportDate,ImportFolder,ImportResult,ImportEmailCount) VALUES (#" & Now() & "#,'" & mailFolder & "', 'Error " & Err.Number & "', " & dMailCount & ")"
            Resume Next 'cmdImportEmail_Exit
    End Select

End Sub

有没有办法用单个字段唯一标识一封电子邮件,无论它是否已被移动?

我知道我可以做些什么来确保我拥有正确的电子邮件并在我的数据库中获取原始条目。如果没有其他方法,我可以将字段连接在一起形成一个唯一字段,然后获取数据库表的主键字段值。

【问题讨论】:

    标签: vba email outlook


    【解决方案1】:

    您可以使用PR_SEARCH_KEY 属性(DASL 名称http://schemas.microsoft.com/mapi/proptag/0x300B0102)- 移动消息时它不会改变。可以通过MailItem.PropertyAccessor.GetProperty来访问,可惜不能在Items.Find/Restrict中使用PT_BINARY属性。

    您还可以使用 MailItem.UserProperties 设置自己的命名属性。

    更新:

    对于PR_SEARCH_KEY,请参阅https://msdn.microsoft.com/en-us/library/office/cc815908.aspx

    MaillItem.UserProperties 可以在任何地方使用 - Outlook 对象模型是 Outlook 对象模型,无论它是从 Outlook 内部使用还是从 Excel 外部使用。请记住,设置用户属性和更改项目将更改其上次修改日期。

    如果您想坚持使用 PR_SEARCH_KEY,以便能够对其进行排序,您可能需要查看 Redemption - 它的 RDOFolder.Items.Find / Restrict 方法允许在其查询中使用 PT_BINARY 属性,例如"http://schemas.microsoft.com/mapi/proptag/0x300B0102" = '89F75D48972B384EB2C50266D1541099'

    【讨论】:

    • 我在其他论坛和帖子中找到了这些架构属性,但我找不到一个明确的列表,该列表可以为我提供用于我想要的属性的属性。它们是否在某个地方有完整的文档记录,或者 Microsoft 是否希望我们自己找出它们?
    • Rats... 编辑之前的评论花费了太长时间。 mailitem.userproperties 将设置在哪里?是否可以从 Access 添加我自己的属性,还是需要在 Outlook 中完成?此报告实用程序都在 Access 中。 objMailItem.PropertyAccessor.GetProperty("Http://schemas.microsoft.com/mapi/proptag/0x300b0102") 是否可以在 Access 中使用?或者该代码仅在 Outlook 中有效?如果我从 Access 向 objMailItem 添加了一个属性,无论如何它都会坚持使用电子邮件吗?如果是从一个文件夹移动到另一个文件夹会丢失该属性吗?
    • 在寻找解决我的问题的最快方法时,我想知道是否有办法在交换服务器上设置一些东西来创建一个不可更改的唯一 ID?如果不是,那么创建一个在 Outlook 客户端中所有收到的电子邮件上运行的“宏”会有所帮助,该“宏”将添加一个存储不可更改的唯一标识符的字段,然后我可以将其导入 Access。我们有一个 AD 帐户,该帐户在 24/7 全天候运行的计算机上登录,并打开了 Outlook 客户端,以使规则在传入的电子邮件上运行。我可以在那里添加宏并让它“标记”每封传入的电子邮件。
    • 不,没有这样的 Exchaneg 服务器设置。用户属性或 PR_SEARCH_KEY 有什么问题?
    • 没什么,虽然我不确定如何使用它,但我希望避免在不需要时编写代码。查看链接,“复制后可由客户更改”是什么意思?我的感觉是,如果电子邮件从一个文件夹移动到另一个文件夹,这个属性并不比 entryid 或 recordkey 更可靠......我需要一个坚如磐石的始终相同的 ID 字段。让我感到困惑的是,Outlook 中没有这样的东西。
    【解决方案2】:

    这是在 MS Access 2013 中测试的 VBA 代码,用于从 Outlook.MailItem 中提取 PR_SEARCH_KEY 并转换为字符串:

    Public Function strGetMailItemUniqueId( _
        olMailItem As Outlook.MailItem _
    ) As String
        Dim PR_SEARCH_KEY As String
        PR_SEARCH_KEY = "http://schemas.microsoft.com/mapi/proptag/0x300B0102"
    
        Dim olPA As Outlook.PropertyAccessor
        Set olPA = olMailItem.PropertyAccessor
    
        Dim vBinary As Variant
        vBinary = olPA.GetProperty(PR_SEARCH_KEY)
    
        strGetMailItemUniqueId = olPA.BinaryToString(vBinary)
    End Function
    

    【讨论】:

      【解决方案3】:

      在 Microsoft Outlook 版本(如 2007、2010、Office 365 等)中,电子邮件的标题部分有一个属性 Message-ID

      您可以使用此属性来唯一标识一封电子邮件。

      【讨论】:

        猜你喜欢
        • 2016-03-29
        • 1970-01-01
        • 2011-12-22
        • 2011-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多