从Outlook收件箱文件夹提取数据到Excel。

huangapple go评论115阅读模式
英文:

Extracting data from outlook inbox folder into excel

问题

我有一个名为"Customer"的Excel文件。在其中,有一个"Name"列(列A)和一个"Email"列(列D)。"Email"列目前为空。

我想要通过将列A中的姓名与Outlook收件箱文件夹中的姓名进行匹配来填充"Email"列。当姓名匹配时,搜索该姓名的电子邮件地址,然后将其复制并粘贴回"Customer"表的Email列(列D)。是否可以使用VBA来实现这个目标?

我尝试了以下代码,但已经运行了4个小时,我不确定它是否正常工作。

Sub FillEmails()
    Dim customerSheet As Worksheet
    Dim customerLastRow As Long
    Dim customerName As String
    Dim customerEmail As String
    Dim olApp As Object
    Dim olNamespace As Object
    Dim olFolder As Object
    Dim olItems As Object
    Dim olItem As Object
    Dim i As Long

    Set customerSheet = ThisWorkbook.Sheets("Customer")

    ' 创建Outlook应用程序的实例并获取命名空间和文件夹对象
    Set olApp = CreateObject("Outlook.Application")
    Set olNamespace = olApp.GetNamespace("MAPI")
    Set olFolder = olNamespace.GetDefaultFolder(6) ' olFolderInbox
    Set olItems = olFolder.Items

    customerLastRow = customerSheet.Cells(Rows.Count, "A").End(xlUp).Row

    For i = 2 To customerLastRow
        customerName = customerSheet.Cells(i, "A").Value
        customerEmail = ""

        ' 在默认收件箱文件夹中搜索具有匹配发件人姓名的电子邮件
        For Each olItem In olItems
            If olItem.Class = 43 Then ' olMail
                If olItem.SenderName = customerName Then
                    customerEmail = olItem.SenderEmailAddress
                    Exit For
                End If
            End If
        Next

        customerSheet.Cells(i, "D").Value = customerEmail
    Next i

    ' 清理Outlook对象
    Set olItems = Nothing
    Set olFolder = Nothing
    Set olNamespace = Nothing
    Set olApp = Nothing
End Sub

希望这有所帮助。如果您有其他问题,请随时提出。

英文:

I have an excel file called Customer. Within it, it has column "Name" (Column A) and column "Email" (Column D). Column "Email" is currently empty.

I would like to fill the "Email" Column by matching the name in Column A with name in Outlook inbox folder. When the name match, search for the email address for that name, copy and paste it back to the Customer Sheet Email Column (Column D). Would it be possible to do so with vba?

I tried the following code but it's been running for 4 hours now, I am not sure it is working correctly.

Sub FillEmails()
    Dim customerSheet As Worksheet
    Dim customerLastRow As Long
    Dim customerName As String
    Dim customerEmail As String
    Dim olApp As Object
    Dim olNamespace As Object
    Dim olFolder As Object
    Dim olItems As Object
    Dim olItem As Object
    Dim i As Long

    Set customerSheet = ThisWorkbook.Sheets("Customer")
    
    ' Create an instance of the Outlook application and get the namespace and folder objects
    Set olApp = CreateObject("Outlook.Application")
    Set olNamespace = olApp.GetNamespace("MAPI")
    Set olFolder = olNamespace.GetDefaultFolder(6) ' olFolderInbox
    Set olItems = olFolder.Items

    customerLastRow = customerSheet.Cells(Rows.Count, "A").End(xlUp).Row

    For i = 2 To customerLastRow
        customerName = customerSheet.Cells(i, "A").Value
        customerEmail = ""

        ' Search for an email with a matching sender name in the default Inbox folder
        For Each olItem In olItems
            If olItem.Class = 43 Then ' olMail
                If olItem.SenderName = customerName Then
                    customerEmail = olItem.SenderEmailAddress
                    Exit For
                End If
            End If
        Next

        customerSheet.Cells(i, "D").Value = customerEmail
    Next i
    
    ' Clean up the Outlook objects
    Set olItems = Nothing
    Set olFolder = Nothing
    Set olNamespace = Nothing
    Set olApp = Nothing
End Sub

答案1

得分: 1

首先,遍历文件夹中的所有项目并不是一个好主意:

For i = 2 To customerLastRow
    customerName = customerSheet.Cells(i, "A").Value
    customerEmail = ""

    ' 在默认收件箱文件夹中搜索与发件人名称匹配的电子邮件
    For Each olItem In olItems
        If olItem.Class = 43 Then ' olMail
            If olItem.SenderName = customerName Then
                customerEmail = olItem.SenderEmailAddress
                Exit For
            End If
        End If
    Next

    customerSheet.Cells(i, "D").Value = customerEmail
Next i

相反,您需要使用Items类的Find/FindNextRestrict方法。它们允许根据指定的搜索条件获取项目,因此您不需要遍历文件夹中的所有项目。更多关于这些方法的信息,请参阅我为技术博客编写的文章:

DASL支持使用内容索引器关键字ci_startswithci_phrasematch以及关键字like在字符串属性中匹配前缀、短语和子字符串,所以您可以尝试以下方式查找关键字:

criteria = "@SQL=" & Chr(34) _
    & "urn:schemas:httpmail:sendername" & Chr(34) _
    & " ci_phrasematch 'sender_name'"

sendername属性返回消息发送者的显示名称。该字段对应于消息的RFC 822 Sender: header


其次,您可以尝试使用NameSpace.CreateRecipient方法来创建一个Recipient对象。它接受接收者的名称,可以是表示显示名称、别名或接收者的完整SMTP电子邮件地址的字符串。因此,在针对地址簿解析接收者之后,您可以尝试获取电子邮件地址(请参阅相应的属性)。

Recipient.Resolve方法尝试针对地址簿解析Recipient对象。Recipient.Resolved属性返回一个布尔值,如果接收者已针对地址簿进行验证,则返回true,例如:

Sub ResolveName() 
 Dim myNamespace As Outlook.NameSpace 
 Dim myRecipient As Outlook.Recipient 
 Dim CalendarFolder As Outlook.Folder 
 Set myNamespace = Application.GetNamespace("MAPI") 
 Set myRecipient = myNamespace.CreateRecipient("Eugene Astafiev") 
 
 myRecipient.Resolve 
 
 If myRecipient.Resolved Then 
   MsgBox myRecipient.Address 
 End If 
 
End Sub 
英文:

First of all, iterating over all items in the folder is not really a good idea:

For i = 2 To customerLastRow
        customerName = customerSheet.Cells(i, "A").Value
        customerEmail = ""

        ' Search for an email with a matching sender name in the default Inbox folder
        For Each olItem In olItems
            If olItem.Class = 43 Then ' olMail
                If olItem.SenderName = customerName Then
                    customerEmail = olItem.SenderEmailAddress
                    Exit For
                End If
            End If
        Next

        customerSheet.Cells(i, "D").Value = customerEmail
    Next i

Instead, you need to use the Find/FindNext or Restrict methods of the Items class. They allow getting items that correspond to the specified search criteria, so you don't need to iterate over all items in the folder. Read more about these methods in the articles that I wrote for the technical blog:

DASL supports the matching of prefixes, phrases, and substrings in a string property using content indexer keywords ci_startswith and ci_phrasematch, and the keyword like. So, you may try to find a keyword in the following way:

criteria = "@SQL=" & Chr(34) _ 
& "urn:schemas:httpmail:sendername" & Chr(34) _ 
& " ci_phrasematch 'sender_name'" 

The sendername property returns the display name of the message sender. This field corresponds to the RFC 822 Sender: header for a message.


Second, you may try using the NameSpace.CreateRecipient method which creates a Recipient object. It accepts the name of the recipient; it can be a string representing the display name, the alias, or the full SMTP email address of the recipient. So, after resolving the recipient against the address book you may try to get the email address (see the corresponding property).

The Recipient.Resolve method attempts to resolve a Recipient object against the Address Book. The Recipient.Resolved property returns a boolean that indicates true if the recipient has been validated against the Address Book, for example:

Sub ResolveName() 
 Dim myNamespace As Outlook.NameSpace 
 Dim myRecipient As Outlook.Recipient 
 Dim CalendarFolder As Outlook.Folder 
 Set myNamespace = Application.GetNamespace("MAPI") 
 Set myRecipient = myNamespace.CreateRecipient("Eugene Astafiev") 
 
 myRecipient.Resolve 
 
 If myRecipient.Resolved Then 
   MsgBox myRecipient.Address 
 End If 
 
End Sub 

huangapple
  • 本文由 发表于 2023年6月8日 18:24:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430898.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定