如何识别发件人也是收件人的电子邮件?

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

How to identify emails where sender is also a recipient?

问题

我理解你想要的是代码部分的翻译。以下是代码部分的中文翻译:

选项 明确
子复制到Excel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim rCount As Long
Dim bXStarted As Boolean
Dim enviro As String
Dim strPath As String

Dim objOL As Outlook.Application
Dim objFolder As Outlook.MAPIFolder
Dim objItems As Outlook.Items
Dim obj As Object
Dim olItem '作为Outlook.MailItem
Dim strColA, strColB, strColC, strColD, strColE, strColF As String

' 获取Excel设置
enviro = CStr(Environ("USERPROFILE"))
'工作簿的路径
strPath = enviro & "\Documents\Book1.xlsx"
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
    Application.StatusBar = "请等待打开Excel源..."
    Set xlApp = CreateObject("Excel.Application")
    bXStarted = True
End If
On Error GoTo 0

On Error Resume Next
' 打开工作簿以输入数据
' 如果不存在则创建工作簿
Set xlWB = xlApp.Workbooks.Open(strPath)
If Err <> 0 Then
    Set xlWB = xlApp.Workbooks.Add
    xlWB.SaveAs 文件名:=strPath
End If
On Error GoTo 0
Set xlSheet = xlWB.Sheets("Sheet1")

On Error Resume Next
' 如果不存在,添加标题
If xlSheet.Range("A1") = "" Then
    xlSheet.Range("A1") = "发件人姓名"
    xlSheet.Range("B1") = "发件人电子邮件"
    xlSheet.Range("C1") = "主题"
    xlSheet.Range("D1") = "正文"
    xlSheet.Range("E1") = "发送给"
    xlSheet.Range("F1") = "日期"
End If

'查找工作表的下一个空行
rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(-4162).Row
'Exchange 2016所需。如果引起空行,则删除。
rCount = rCount + 1

' 从Outlook获取值
Set objOL = Outlook.Application
Set objFolder = objOL.ActiveExplorer.CurrentFolder
Set objItems = objFolder.Items
For Each obj In objItems

    Set olItem = obj
    
    '收集字段
    
    strColA = olItem.SenderName
    strColB = olItem.SenderEmailAddress
    strColC = olItem.Subject
    strColD = olItem.Body
    strColE = olItem.To
    strColF = olItem.ReceivedTime

    ' 获取Exchange地址
    ' 如果不使用Exchange,可以删除此块
    Dim olEU As Outlook.ExchangeUser
    Dim oEDL As Outlook.ExchangeDistributionList
    Dim recip As Outlook.Recipient
    Set recip = Application.Session.CreateRecipient(strColB)

    If InStr(1, strColB, "/") > 0 Then
        ' 如果是Exchange,获取SMTP地址
        Select Case recip.AddressEntry.AddressEntryUserType
            Case OlAddressEntryUserType.olExchangeUserAddressEntry
                Set olEU = recip.AddressEntry.GetExchangeUser
                If Not (olEU Is Nothing) Then
                    strColB = olEU.PrimarySmtpAddress
                End If
            Case OlAddressEntryUserType.olOutlookContactAddressEntry
                Set olEU = recip.AddressEntry.GetExchangeUser
                If Not (olEU Is Nothing) Then
                    strColB = olEU.PrimarySmtpAddress
                End If
            Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
                Set oEDL = recip.AddressEntry.GetExchangeDistributionList
                If Not (oEDL Is Nothing) Then
                    strColB = olEU.PrimarySmtpAddress
                End If
        End Select
    End If
    ' 结束Exchange部分

    ' 尝试获取收件人电子邮件地址
    Dim olEU2 As Outlook.ExchangeUser
    Dim oEDL2 As Outlook.ExchangeDistributionList
    Dim recip2 As Outlook.Recipient
    Set recip2 = Application.Session.CreateRecipient(strColE)

    Select Case recip2.AddressEntry.AddressEntryUserType
        Case OlAddressEntryUserType.olExchangeUserAddressEntry
            Set olEU2 = recip.AddressEntry.GetExchangeUser
            If Not (olEU2 Is Nothing) Then
                strColE = olEU2.PrimarySmtpAddress
            End If
        Case OlAddressEntryUserType.olOutlookContactAddressEntry
            Set olEU2 = recip.AddressEntry.GetExchangeUser
            If Not (olEU2 Is Nothing) Then
                strColE = olEU2.PrimarySmtpAddress
            End If
        Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
            Set oEDL2 = recip.AddressEntry.GetExchangeDistributionList
            If Not (oEDL2 Is Nothing) Then
                strColE = olEU2.PrimarySmtpAddress
            End If
    End Select

    '在Excel工作表中写入数据
    xlSheet.Range("A" & rCount) = strColA
    xlSheet.Range("B" & rCount) = strColB
    xlSheet.Range("C" & rCount) = strColC
    xlSheet.Range("D" & rCount) = strColD
    xlSheet.Range("E" & rCount) = strColE
    xlSheet.Range("F" & rCount) = strColF

    '下一行
    rCount = rCount + 1
    xlWB.Save

Next

' 不换行
xlSheet.Rows.WrapText = False

xlWB.Save
xlWB.Close 1
If bXStarted Then
    xlApp.Quit
End If

Set olItem = Nothing
Set obj = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
End Sub

希望这可以帮助你理解代码的中文翻译部分。如果你有任何进一步的问题,请随时提问。

英文:

I'm trying to export sender email address and recipient email addresses (to and cc) to Excel. I adapted code I found online. It does most of what I need but there are two problems:

  • It only works with a single recipient. If there are two or more recipients, it provides names (e.g. Jo Bloggs) instead of email addresses.
  • It only includes people in the 'To' field, not those in the 'CC' field.

I think the bit that needs fixing is:

&#39;trying to get recipient email address
 Dim olEU2 As Outlook.ExchangeUser
 Dim oEDL2 As Outlook.ExchangeDistributionList
 Dim recip2 As Outlook.Recipient
 Set recip2 = Application.Session.CreateRecipient(strColE)

     Select Case recip2.AddressEntry.AddressEntryUserType
       Case OlAddressEntryUserType.olExchangeUserAddressEntry
         Set olEU2 = recip.AddressEntry.GetExchangeUser
         If Not (olEU2 Is Nothing) Then
             strColE = olEU2.PrimarySmtpAddress
         End If
       Case OlAddressEntryUserType.olOutlookContactAddressEntry
         Set olEU2 = recip.AddressEntry.GetExchangeUser
         If Not (olEU2 Is Nothing) Then
            strColE = olEU2.PrimarySmtpAddress
         End If
       Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
         Set oEDL2 = recip.AddressEntry.GetExchangeDistributionList
         If Not (oEDL2 Is Nothing) Then
            strColE = olEU2.PrimarySmtpAddress
         End If
     End Select

Full code:

Option Explicit
 Sub CopyToExcel()
 Dim xlApp As Object
 Dim xlWB As Object
 Dim xlSheet As Object
 Dim rCount As Long
 Dim bXStarted As Boolean
 Dim enviro As String
 Dim strPath As String

Dim objOL As Outlook.Application
Dim objFolder As Outlook.MAPIFolder
Dim objItems As Outlook.Items
 Dim obj As Object
 Dim olItem &#39;As Outlook.MailItem
 Dim strColA, strColB, strColC, strColD, strColE, strColF As String
               
&#39; Get Excel set up
enviro = CStr(Environ(&quot;USERPROFILE&quot;))
&#39;the path of the workbook
strPath = enviro &amp; &quot;\Documents\Book1.xlsx&quot;
     On Error Resume Next
     Set xlApp = GetObject(, &quot;Excel.Application&quot;)
     If Err &lt;&gt; 0 Then
         Application.StatusBar = &quot;Please wait while Excel source is opened ... &quot;
         Set xlApp = CreateObject(&quot;Excel.Application&quot;)
         bXStarted = True
     End If
     On Error GoTo 0

On Error Resume Next
  &#39; Open the workbook to input the data
  &#39; Create workbook if doesn&#39;t exist
     Set xlWB = xlApp.Workbooks.Open(strPath)
If Err &lt;&gt; 0 Then
        Set xlWB = xlApp.Workbooks.Add
      xlWB.SaveAs FileName:=strPath
End If
   On Error GoTo 0
     Set xlSheet = xlWB.Sheets(&quot;Sheet1&quot;)
    
On Error Resume Next
&#39; add the headers if not present
If xlSheet.Range(&quot;A1&quot;) = &quot;&quot; Then
  xlSheet.Range(&quot;A1&quot;) = &quot;Sender Name&quot;
  xlSheet.Range(&quot;B1&quot;) = &quot;Sender Email&quot;
  xlSheet.Range(&quot;C1&quot;) = &quot;Subject&quot;
  xlSheet.Range(&quot;D1&quot;) = &quot;Body&quot;
  xlSheet.Range(&quot;E1&quot;) = &quot;Sent To&quot;
  xlSheet.Range(&quot;F1&quot;) = &quot;Date&quot;
End If

&#39;Find the next empty line of the worksheet
rCount = xlSheet.Range(&quot;B&quot; &amp; xlSheet.Rows.Count).End(-4162).Row
&#39;needed for Exchange 2016. Remove if causing blank lines.
rCount = rCount + 1

&#39; get the values from outlook
Set objOL = Outlook.Application
Set objFolder = objOL.ActiveExplorer.CurrentFolder
    Set objItems = objFolder.Items
  For Each obj In objItems

    Set olItem = obj
    
 &#39;collect the fields
 
    strColA = olItem.SenderName
    strColB = olItem.SenderEmailAddress
    strColC = olItem.Subject
    strColD = olItem.Body
    strColE = olItem.To
    strColF = olItem.ReceivedTime
    
    
&#39; Get the Exchange address
&#39; if not using Exchange, this block can be removed
 Dim olEU As Outlook.ExchangeUser
 Dim oEDL As Outlook.ExchangeDistributionList
 Dim recip As Outlook.Recipient
 Set recip = Application.Session.CreateRecipient(strColB)

 If InStr(1, strColB, &quot;/&quot;) &gt; 0 Then
&#39; if exchange, get smtp address
     Select Case recip.AddressEntry.AddressEntryUserType
       Case OlAddressEntryUserType.olExchangeUserAddressEntry
         Set olEU = recip.AddressEntry.GetExchangeUser
         If Not (olEU Is Nothing) Then
             strColB = olEU.PrimarySmtpAddress
         End If
       Case OlAddressEntryUserType.olOutlookContactAddressEntry
         Set olEU = recip.AddressEntry.GetExchangeUser
         If Not (olEU Is Nothing) Then
            strColB = olEU.PrimarySmtpAddress
         End If
       Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
         Set oEDL = recip.AddressEntry.GetExchangeDistributionList
         If Not (oEDL Is Nothing) Then
            strColB = olEU.PrimarySmtpAddress
         End If
     End Select
End If
&#39; End Exchange section


&#39;trying to get recipient email address
 Dim olEU2 As Outlook.ExchangeUser
 Dim oEDL2 As Outlook.ExchangeDistributionList
 Dim recip2 As Outlook.Recipient
 Set recip2 = Application.Session.CreateRecipient(strColE)

     Select Case recip2.AddressEntry.AddressEntryUserType
       Case OlAddressEntryUserType.olExchangeUserAddressEntry
         Set olEU2 = recip.AddressEntry.GetExchangeUser
         If Not (olEU2 Is Nothing) Then
             strColE = olEU2.PrimarySmtpAddress
         End If
       Case OlAddressEntryUserType.olOutlookContactAddressEntry
         Set olEU2 = recip.AddressEntry.GetExchangeUser
         If Not (olEU2 Is Nothing) Then
            strColE = olEU2.PrimarySmtpAddress
         End If
       Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
         Set oEDL2 = recip.AddressEntry.GetExchangeDistributionList
         If Not (oEDL2 Is Nothing) Then
            strColE = olEU2.PrimarySmtpAddress
         End If
     End Select



&#39;write them in the excel sheet
  xlSheet.Range(&quot;A&quot; &amp; rCount) = strColA
  xlSheet.Range(&quot;B&quot; &amp; rCount) = strColB
  xlSheet.Range(&quot;c&quot; &amp; rCount) = strColC
  xlSheet.Range(&quot;d&quot; &amp; rCount) = strColD
  xlSheet.Range(&quot;e&quot; &amp; rCount) = strColE
  xlSheet.Range(&quot;f&quot; &amp; rCount) = strColF
 
&#39;Next row
  rCount = rCount + 1
xlWB.Save

 Next
 
&#39; don&#39;t wrap lines
xlSheet.Rows.WrapText = False

xlWB.Save
     xlWB.Close 1
     If bXStarted Then
         xlApp.Quit
     End If
    
     Set olItem = Nothing
     Set obj = Nothing
     Set xlApp = Nothing
     Set xlWB = Nothing
     Set xlSheet = Nothing
End Sub

答案1

得分: 1

遍历文件夹中的所有项目并不是一个好主意。我建议从Find/FindNextRestrict方法开始。请注意,有一些项目属性不能用于筛选条件。您可以在MSDN上了解有关不允许在筛选字符串和搜索条件中使用的属性的更多信息。

以下示例使用Restrict方法获取所有Business类别的收件箱项目,并将它们移动到Business文件夹。要运行此示例,请创建或确保在Inbox下存在名为'Business'的子文件夹:

Sub MoveItems()
    Dim myNamespace As Outlook.NameSpace
    Dim myFolder As Outlook.Folder
    Dim myItems As Outlook.Items
    Dim myRestrictItems As Outlook.Items
    Dim myItem As Outlook.MailItem

    Set myNamespace = Application.GetNamespace("MAPI")
    Set myFolder = myNamespace.GetDefaultFolder(olFolderInbox)
    Set myItems = myFolder.Items
    Set myRestrictItems = myItems.Restrict("[Categories] = 'Business'")
    For i = myRestrictItems.Count To 1 Step -1
        myRestrictItems(i).Move myFolder.Folders("Business")
    Next
End Sub

另外,您可能会发现Application类的AdvancedSearch方法有帮助。在Outlook中使用AdvancedSearch方法的主要优点包括:

  • 搜索在另一个线程中执行。您不需要手动运行另一个线程,因为AdvancedSearch方法会在后台自动运行。
  • 可以搜索任何项目类型:邮件、约会、日历、笔记等,位于任何位置,即超出特定文件夹的范围。RestrictFind/FindNext方法可以应用于特定的Items集合(请参阅Outlook中Folder类的Items属性)。
  • 完全支持DASL查询(也可以用于搜索自定义属性)。您可以在MSDN的Filtering文章中了解更多信息。为了提高搜索性能,如果为存储启用了即时搜索,请使用即时搜索关键字(请参阅Store类的IsInstantSearchEnabled属性)。
  • 您可以使用Search类的Stop方法随时停止搜索过程。

请记住,您可以在文件夹上设置适当的筛选器(视图 | 视图设置 | 筛选器),并在“筛选器”对话框的SQL选项卡上查看筛选器字符串。然后,您可以在代码中构建任何所需的筛选器字符串。

英文:

Iterating through all items in the folder is not really a good idea. I'd recommend starting from the Find/FindNext or Restrict methods instead. Please note that there are some item properties that you can’t use for the filter. You can read more about the properties not allowed in the filter string and string formats used for the search criterion on MSDN.

The following example uses the Restrict method to get all Inbox items of Business category and moves them to the Business folder. To run this example, create or make sure a subfolder called 'Business' exists under Inbox:

Sub MoveItems()  
    Dim myNamespace As Outlook.NameSpace  
    Dim myFolder As Outlook.Folder  
    Dim myItems As Outlook.Items  
    Dim myRestrictItems As Outlook.Items  
    Dim myItem As Outlook.MailItem  
  
    Set myNamespace = Application.GetNamespace(&quot;MAPI&quot;)  
    Set myFolder = _  
        myNamespace.GetDefaultFolder(olFolderInbox)  
    Set myItems = myFolder.Items  
    Set myRestrictItems = myItems.Restrict(&quot;[Categories] = &#39;Business&#39;&quot;)  
    For i =  myRestrictItems.Count To 1 Step -1  
        myRestrictItems(i).Move myFolder.Folders(&quot;Business&quot;)  
    Next  
End Sub

Also, you may find the AdvancedSearch method of the Application class helpful. The key benefits of using the AdvancedSearch method in Outlook are:

  • The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
  • Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
  • Full support for DASL queries (custom properties can be used for searching too). You can read more about this in the Filtering article in MSDN. To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
  • You can stop the search process at any moment using the Stop method of the Search class.

Please remember that you can set a suitable filter (View | View Settings |filter) on a folder and study the filter string on the SQL tab of the Filter dialog. Then you can construct any required filter string in the code.

答案2

得分: 0

如果可以使用Items.Find/FindNextItems.Restrict,那将是很好的,但我无法想到一个可以让你实现你想要的功能的查询。如果这只是一次性的需求,那么你只能循环遍历文件夹中的所有项目,对于每个项目,循环遍历所有收件人,并将每个收件人的记录ID(Recipient.EntryID)与发件人的记录ID(MailItem.Sender.EntryId)进行比较。

英文:

If woudl be nice to use Items.Find/FindNext or Items.Restrict, but I cannot think of a query that would let you do what you want. If it is a one time thing, you have no choice but to loop through all items in a folder and for each item loop through all recipients and compare each recipient's entry id (Recipient.EntryID) with the sender entry id (MailItem.Sender.EntryId).

huangapple
  • 本文由 发表于 2020年1月6日 16:24:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/59608816.html
匿名

发表评论

匿名网友

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

确定