vba 移动电子邮件时,如何在 MailItem.EntryID 更改时唯一标识 Outlook 电子邮件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28731643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-12 06:21:32  来源:igfitidea点击:

How to uniquely identify an Outlook email as MailItem.EntryID changes when email is moved

vbaemailoutlook

提问by DawnTreader

My company uses a single email address for customers to send requests and orders to. we created an Access database that import emails into a table. The table creates it's own unique identifier for each email imported but is not supposed to import an email twice. The system was working as we were only concerned with emails coming into the inbox and didn't need anything more than that.

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

However we now need to know the "flow", "traffic" and "workload" of the email pool that this account is. The email that comes into the inbox is categorized and then moved to a folder called "my_tasks" and a subfolder the folder named as 1 of the four CSRs to be worked on by a manager. This email is then dealt with and the CSR moves it to a subfolder under another folder called "Completed".

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

So email comes into Inbox, gets moved to my_tasks\joeblow is dealt with and gets moved to Completed\Canada.

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

Currently I have code that iterates through the folders and finds each email, grabs the fields we want to store and then inserts them into the table. All of this is done in Access through VBA code.

目前我有代码遍历文件夹并查找每封电子邮件,获取我们想要存储的字段,然后将它们插入表中。所有这些都是通过 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

Is there a way to uniquely identify an email with a single field no matter whether it has been moved or not?

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

I have an idea of what I could do to make sure I have the right email and get the original entry in my database. If there was no other way I could concatenate fields together to form a unique field and then get the database table's primary key field value.

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

回答by Dmitry Streblechenko

You can use the PR_SEARCH_KEYproperty (DASL name http://schemas.microsoft.com/mapi/proptag/0x300B0102) - it does not change when a message is moved. It can be accessed through MailItem.PropertyAccessor.GetProperty, but unfortunately you cannot use PT_BINARY properties in Items.Find/Restrict.

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

You can also set your own named property using MailItem.UserProperties.

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

UPDATE:

更新:

For PR_SEARCH_KEY, see https://msdn.microsoft.com/en-us/library/office/cc815908.aspx.

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

MaillItem.UserProperties can be used from anywhere - Outlook Object Model is Outlook Object Model whether it is used from inside Outlook or externally from Excel. Keep in mind that setting a user property and daving the item will change its last modified date.

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

If you want to stick to PR_SEARCH_KEY, to be be able to sort on it, you might want to look at Redemption- its RDOFolder.Items.Find / Restrict methods allow PT_BINARY properties in its queries, e.g. "http://schemas.microsoft.com/mapi/proptag/0x300B0102" = '89F75D48972B384EB2C50266D1541099'

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

回答by Colin Carter

Here is VBA code tested in MS Access 2013 to extract the PR_SEARCH_KEY from an Outlook.MailItem and convert to a string:

这是在 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

回答by VAT

In Microsoft Outlook versions like 2007, 2010, Office 365 etc. there is a property Message-IDin the headers section of the email.

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

You can use this property to uniquely identify an email.

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

enter image description here

enter image description here