将 ID 添加到行并使用相同的 ID 更新回复行?

Add ID To Row And Update Reply Rows With Same ID?

希望你一切都好。我制作了一个电子邮件报告工具,但我真的很苦恼。每行都有一个 ID 号(从 1 开始到 G 列的第 2 行)。当收到回复时,我需要回复有其原始 ID。尝试使用 entryid 但是当回复电子邮件返回时这个值会改变所以它不是很好。

下面是我的代码;

Option Explicit
Const fPath As String = "C:\Users\neo_s_000\Desktop\Emails\" 'The path to save the messages
Const sfName As String = "C:\Users\neo_s_000\Desktop\Message Log.xlsx"

Sub Download_Outlook_Mail_To_Excel()
Dim olApp As Object
Dim olFolder As Object
Dim olNS As Object
Dim xlBook As Workbook
Dim xlSheet As Worksheet
Dim NextRow As Long
Dim i As Long
Dim olItem As Object
    If FileExists(sfName) Then
        Set xlBook = Workbooks.Open(sfName)
        Set xlSheet = xlBook.Sheets(1)
    Else
        Set xlBook = Workbooks.Add
        Set xlSheet = xlBook.Sheets(1)
        With xlSheet
            .Cells(1, 1) = "Sender"
            .Cells(1, 2) = "Subject"
            .Cells(1, 3) = "Date"
            '.Cells(1, 4) = "Size"
            .Cells(1, 5) = "EmailID"
            .Cells(1, 6) = "Body"
            .Cells(1, 7) = "ID"
        End With
        xlBook.SaveAs sfName
    End If
    On Error Resume Next
    Set olApp = GetObject(, "Outlook.Application")
    If Err <> 0 Then
        Set olApp = CreateObject("Outlook.Application")
    End If
    On Error GoTo 0
    With xlSheet
        .Cells(1, 1) = "Sender"
        .Cells(1, 2) = "Subject"
        .Cells(1, 3) = "Date"
        '.Cells(1, 4) = "Size"
        .Cells(1, 5) = "EmailID"
        .Cells(1, 6) = "Body"
        .Cells(1, 7) = "ID"
        CreateFolders fPath
        Set olNS = olApp.GetNamespace("MAPI")
        olNS.Logon
        Set olFolder = olNS.PickFolder
        For Each olItem In olFolder.Items
            NextRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
            If olItem.Class = 43 Then
                .Cells(NextRow, 1) = olItem.Sender
                .Cells(NextRow, 2) = olItem.Subject
                .Cells(NextRow, 3) = olItem.SentOn
                '.Cells(NextRow, 4) =
                .Cells(NextRow, 5) = SaveMessage(olItem)
                .Cells(NextRow, 6) = olItem.Body
            End If
        Next olItem
        MsgBox "Outlook Mails Extracted to Excel"
    End With
    xlBook.Close SaveChanges:=True
lbl_Exit:
    Set olApp = Nothing
    Set olFolder = Nothing
    Set olItem = Nothing
    Set xlBook = Nothing
    Set xlSheet = Nothing
    Exit Sub
End Sub

Function SaveMessage(olItem As Object) As String
Dim Fname As String
    Fname = Format(olItem.ReceivedTime, "yyyymmdd") & Chr(32) & _
            Format(olItem.ReceivedTime, "HH.MM") & Chr(32) & olItem.sendername & " - " & olItem.Subject
    Fname = Replace(Fname, Chr(58) & Chr(41), "")
    Fname = Replace(Fname, Chr(58) & Chr(40), "")
    Fname = Replace(Fname, Chr(34), "-")
    Fname = Replace(Fname, Chr(42), "-")
    Fname = Replace(Fname, Chr(47), "-")
    Fname = Replace(Fname, Chr(58), "-")
    Fname = Replace(Fname, Chr(60), "-")
    Fname = Replace(Fname, Chr(62), "-")
    Fname = Replace(Fname, Chr(63), "-")
    Fname = Replace(Fname, Chr(124), "-")
    SaveMessage = SaveUnique(olItem, fPath, Fname)
lbl_Exit:
    Exit Function
End Function

Private Function SaveUnique(oItem As Object, _
                            strPath As String, _
                            strFileName As String) As String

Dim lngF As Long
Dim lngName As Long
    lngF = 1
    lngName = Len(strFileName)
    Do While FileExists(strPath & strFileName & ".msg") = True
        strFileName = Left(strFileName, lngName) & "(" & lngF & ")"
        lngF = lngF + 1
    Loop
    oItem.SaveAs strPath & strFileName & ".msg"
    SaveUnique = strPath & strFileName & ".msg"
lbl_Exit:
    Exit Function
End Function

Private Sub CreateFolders(strPath As String)
Dim strTempPath As String
Dim iPath As Long
Dim vPath As Variant
    vPath = Split(strPath, "\")
    strPath = vPath(0) & "\"
    For iPath = 1 To UBound(vPath)
        strPath = strPath & vPath(iPath) & "\"
        If Not FolderExists(strPath) Then MkDir strPath
    Next iPath
End Sub

Private Function FolderExists(ByVal PathName As String) As Boolean
   Dim nAttr As Long
   On Error GoTo NoFolder
   nAttr = GetAttr(PathName)
   If (nAttr And vbDirectory) = vbDirectory Then
      FolderExists = True
   End If
NoFolder:
End Function

Private Function FileExists(filespec) As Boolean
Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    If fso.FileExists(filespec) Then
        FileExists = True
    Else
        FileExists = False
    End If
lbl_Exit:
    Exit Function
End Function

有什么想法吗?

好的,很抱歉这么久才给您答复。我会尽量给你 运行 我在评论中所说的内容。


早绑定与晚绑定
OOP all of the objects we interact with have a Type (aka Class).
我们通过访问与它们关联的成员来使用这些对象,这些成员由它们的类型定义。 为了访问这些成员,运行time 环境需要知道类型是什么。

我们可以在执行代码之前(因此在编译时)告诉运行时间环境类型是什么,这称为早期绑定。或者,我们可以让 RTE 在执行时(因此在 运行 时间)计算出来,这称为后期绑定。

在编译时定义类型是通过将对象声明为预期类型来完成的。例如:

Dim xlApp as Excel.Application

在 运行 时定义它是通过将对象声明为基类型然后将其转换为继承基类型的另一种类型来完成的。最常见的是使用 Object 的基类型,因为所有类型都派生自 Object 类型。 (或者 Variant 在 VBA 中很常见,因为它可以表示任何数据类型)。例如:

Dim xlApp as Object

使用早期绑定对您(程序员)的主要优势是 Intellisense,但使用早期绑定还有很多优势,例如程序优化、调试、错误捕获等。

您可以阅读有关这些概念的更多信息 here,但仅此而已。


类型库

为了将对象声明为我们想要的类型,我们需要确保该类型对 IDE 可用。类型包含在库(通常是 .DLL 文件)中,我们可以添加对这些库的引用以使用其中定义的类型。在 VBA 中,我们通过 "adding a reference" 执行此操作,可从 Tools 菜单中获得。


所有这些都在我 link 昨天写的 reference 中进行了解释。


实施早期绑定:

要使用早期绑定,请按照上面 link 中的描述设置引用,然后更改变量声明以从 Outlook 命名空间中调出适当的类型,如下所示:

Dim olApp As Outlook.Application
Dim olFolder As Outlook.Folder
Dim olNS As Outlook.Namespace
Dim xlBook As Workbook  'This is the same as Excel.Workbook... Excel is the default namespace and a reference is automatically included in your VBA project when you enter VBA from Excel (e.g. using AL+F11 or macro-recorder)
Dim xlSheet As Worksheet  'Same as Excel.Worksheet...
Dim NextRow As Long
Dim i As Long
Dim olItem As Object  'Here we have to use late binding because the return from Folder.Items collection can contain objects of multiple types (e.g. MailItem, MeetingItem, AppointmentItem, etc.)

实现 ID 字段:

就填充 ID 字段而言,您可能可以使用 Conversation.ConversationID 属性 获得所需内容。

例如

For Each olItem In olFolder.Items
    NextRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
    If olItem.Class = 43 Then
        .Cells(NextRow, 1) = olItem.Sender
        .Cells(NextRow, 2) = olItem.Subject
        .Cells(NextRow, 3) = olItem.SentOn
        '.Cells(NextRow, 4) =
        .Cells(NextRow, 5) = SaveMessage(olItem)
        .Cells(NextRow, 6) = olItem.Body

        Dim Convo as Outlook.Conversation
        Set Convo = olItem.GetConversation()
        .Cells(NextRow, 7) = convo.conversationID
    End If
Next olItem