我试图扩展一些Outlook电子邮件删除VBA代码的功能。我定期收到回弹电子邮件,并希望通过将上述电子邮件地址导出到MS来跟踪这些邮件(以供删除)。
代码在某种程度上是有效的。我只能刮第一个电子邮件地址在一个典型的回弹通知电子邮件使用RegEx。我为公司工作的邮件服务器将来自同一个域的电子邮件聚合成一个通知电子邮件。因此,我得到多个通知电子邮件,其中包含多个反弹的电子邮件。
如何让RegEx循环通过整个通知电子邮件来收集所有的电子邮件地址?我现在有点卡住了,因为--诚然--我对RegEx不太了解,并且“采用”了这段代码的大部分.
谢谢你的帮助,斯塔克溢出!
Sub Extract_Invalid_To_Excel()
Dim olApp As Outlook.Application
Dim olExp As Outlook.Explorer
Dim olFolder As Outlook.MAPIFolder
Dim obj As Object
Dim stremBody As String
Dim stremSubject As String
Dim i As Long
Dim x As Long
Dim count As Long
Dim RegEx As Object
Set RegEx = CreateObject("VBScript.RegExp")
Dim xlApp As Object 'Excel.Application
Dim xlwkbk As Object 'Excel.Workbook
Dim xlwksht As Object 'Excel.Worksheet
Dim xlRng As Object 'Excel.Range
Set olApp = Outlook.Application
Set olExp = olApp.ActiveExplorer
Set olFolder = olExp.CurrentFolder
'Open Excel
Set xlApp = GetExcelApp
xlApp.Visible = True
If xlApp Is Nothing Then GoTo ExitProc
Set xlwkbk = xlApp.Workbooks.Add
Set xlwksht = xlwkbk.Sheets(1)
Set xlRng = xlwksht.Range("A1")
xlRng.Value = "Bounced email addresses"
'Set count of email objects
count = olFolder.Items.count
'counter for excel sheet
i = 0
'counter for emails
x = 1
For Each obj In olFolder.Items '**Loops through selected Outlook folder**
xlApp.StatusBar = x & " of " & count & " emails completed"
stremBody = obj.Body
stremSubject = obj.Subject
If checkEmail(stremBody) = True Then '**Checks email for keywords in email
'MsgBox ("finding email: " & stremBody)
'**RegEx to find email addresses within message body
With RegEx
.Pattern = "\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b"
.IgnoreCase = True
.MultiLine = True
.Global = False
Set olMatches = .Execute(stremBody) 'Executes RegEx function
'Loop through RegEx matches
For Each match In olMatches
xlwksht.Cells(i + 2, 1).Value = match
i = i + 1
Next match
End With
'TODO: move or mark the email that had the address extracted
Else
'**To view the items that aren't being parsed uncomment the following line
'MsgBox (stremBody)
End If
x = x + 1
Next obj
xlApp.ScreenUpdating = True
MsgBox ("Invalid Email addresses are done being extracted")
ExitProc:
Set xlRng = Nothing
Set xlwksht = Nothing
Set xlwkbk = Nothing
Set xlApp = Nothing
Set emItm = Nothing
Set olFolder = Nothing
Set olNS = Nothing
Set olApp = Nothing
End Sub
Function GetExcelApp() As Object
' always create new instance
On Error Resume Next
Set GetExcelApp = CreateObject("Excel.Application")
On Error GoTo 0
End Function
Function checkEmail(ByVal Body As String) As Boolean
Dim keywords(3) As String
keywords(0) = "recipient's e-mail address was not found"
keywords(1) = "error occurred while trying to deliver this message"
keywords(2) = "message wasn't delivered"
'Default value
checkEmail = False
For Each word In keywords
If InStr(1, Body, word, vbTextCompare) > 1 Then
checkEmail = True
Exit For
End If
Next word
End Function
提供更多细节。我会收到数百封包含以下文字的电子邮件:
Delivery has failed to these recipients or distribution lists:
John.Doe@abc.com
The recipient's e-mail address was not found in the recipient's e-mail system. Microsoft Exchange will not try to redeliver this message for you. Please check the e-mail address and try resending this message, or provide the following diagnostic text to your system administrator.
Morgan.Freedman@abc.com
The recipient's e-mail address was not found in the recipient's e-mail system. Microsoft Exchange will not try to redeliver this message for you. Please check the e-mail address and try resending this message, or provide the following diagnostic text to your system administrator.
Michael.Jordan@abc.com
The recipient's e-mail address was not found in the recipient's e-mail system. Microsoft Exchange will not try to redeliver this message for you. Please check the e-mail address and try resending this message, or provide the following diagnostic text to your system administrator.
上面的代码能够获取电子邮件正文文本中的第一个电子邮件地址(即John.Doe@abc.com),但是看不到其他两个电子邮件地址.
其余的代码运行得完美无缺。它将找到的电子邮件地址导出到Excel中。
发布于 2014-08-22 14:55:48
虽然RegEx函数仍然是新的,但我盲目地稍微修改了代码。
我将RegEx.Global布尔值更改为True,此代码将完美无缺地工作。
With RegEx
yadda yadda yadda
.Global = True
End With
不管怎样,谢谢你。希望这对其他人有帮助!
发布于 2018-09-21 07:09:51
我收到多达200个反弹的电子邮件通知,其中每一个大型电子邮件分发。通过不断的联系,这很容易,因为该工具处理所有反弹的地址和代码到一个很好的文件。有了Outlook,我就只能靠自己了,但出于其他原因,我更喜欢这样做。因此,我想出了一个过程和VBA宏来完成任务。首先,我把所有的电子邮件,我希望处理到一个文件夹,并让它选择。使用Outlook 2010,我转到文件-> OPTIONS ->高级->导出。然后选择导出到文件 (Next),然后选择最后一个选项TAB分隔值(Windows)。然后选择名称和文件夹位置来存储一个合并了文件夹中所有电子邮件的单一TXT文件。将文件打开到Msft并运行以下VBA宏:
Sub Bounced_Email_Harvester()
'
' Bounced-Email Text-Process Macro
'
Dim flag As Boolean
' DocLen is to maintain Document length in characters
Dim DocLen As Long
' Try to speed up Word by suspending unnecessary tasks
ActiveDocument.ActiveWindow.View.Draft = True
Options.Pagination = False
Options.CheckGrammarAsYouType = False
Options.CheckSpellingAsYouType = False
Application.ScreenUpdating = False
' Remove extraneous bracket characters < & >
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = ">>>"
.Replacement.Text = "###"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
.Text = "<<<"
.Replacement.Text = "VVV"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
Selection.WholeStory
DocLen = Len(Selection)
Application.DisplayStatusBar = True
Selection.HomeKey Unit:=wdStory
' CORE OF MACRO IS WITHIN THIS LOOP
Do While DocLen > 800
' Selects text until next @ sign is reached - locating email addresses
flag = True
While flag = True
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
DocLen = DocLen - 1
If Strings.Right(Selection.Range.Text, 1) = "@" Or DocLen < 2 Then flag = False
Wend
flag = True
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
DocLen = DocLen + 1
While flag = True
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
DocLen = DocLen + 1
'Locate the Beginning of email seeking demarkations (brackets, space, tab, paragraph)
If Strings.Right(Selection.Range.Text, 1) = "<" Or Strings.Right(Selection.Range.Text, 1) = "[" Or Strings.Right(Selection.Range.Text, 1) = "(" Or Strings.Right(Selection.Range.Text, 1) = " " _
Or Strings.Right(Selection.Range.Text, 1) = Chr$(9) Or Strings.Right(Selection.Range.Text, 1) = Chr$(13) Or DocLen < 2 Then flag = False
Wend
Selection.TypeParagraph
flag = True
While flag = True
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
DocLen = DocLen - 1
'Locate the End of email seeking demarkations (brackets, space, tab, paragraph)
If Strings.Right(Selection.Range.Text, 1) = ">" Or Strings.Right(Selection.Range.Text, 1) = "]" Or Strings.Right(Selection.Range.Text, 1) = ")" Or Strings.Right(Selection.Range.Text, 1) = " " _
Or Strings.Right(Selection.Range.Text, 1) = Chr$(9) Or Strings.Right(Selection.Range.Text, 1) = Chr$(13) Or DocLen < 2 Then flag = False
Wend
Selection.Collapse Direction:=wdCollapseEnd
Selection.Previous(Unit:=wdCharacter, Count:=1).Select
DocLen = DocLen + 1
Selection.TypeParagraph
Loop
' END OF CORE MACRO LOOP
Selection.Collapse Direction:=wdCollapseEnd
Selection.Previous(Unit:=wdCharacter, Count:=1).Select
Selection.TypeParagraph
' Major work done - now some pesky house cleaning....
Selection.Find.ClearFormatting
With Selection.Find
.Text = "mailto:"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
.Text = ":550^p"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
.Text = "<^p"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
.Text = ";^p"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
.Text = "...^p"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
.Text = ".^p"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
Selection.Find.Execute Replace:=wdReplaceAll
Selection.Find.Execute Replace:=wdReplaceAll
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
.Text = "^p^p"
.Replacement.Text = "^p"
.Forward = True
.Wrap = wdFindContinue
End With
Selection.Find.Execute Replace:=wdReplaceAll
Selection.Find.Execute Replace:=wdReplaceAll
Selection.Find.Execute Replace:=wdReplaceAll
Selection.Find.Execute Replace:=wdReplaceAll
MsgBox ("Count: " & DocLen)
End Sub
可能会有10到15分钟的口碑传开,似乎被关起来了。我点击另一个应用程序,有时看任务管理器,以确认它仍然工作的基础上的性能监视器。早上开始后我去煮咖啡。它最终将以提供一个无意义的数字的msg框结束。点击它就可以走了。现在已经完成了,您将有一长列段落分隔的电子邮件地址。它似乎能够可靠地提取100%以上的电子邮件;例如,一些邮件服务器响应电子邮件域的派生,例如@us.att.com和@att.com,或者针对同一用户的@jpmogan.com和@jpchase.com。
复制整个过程,然后放到Excel列中。从这里开始,对列表进行排序并删除最明显的部分,所有的前20%都是以数字开头的电子邮件地址,以信封、标头、邮件、邮局、SMTP、X-发件人和大量重复发送电子邮件地址开始的电子邮件地址。然后在上面运行一个枢轴表以消除所有的重复。您现在有您的电子邮件列表导入到您的dB标记为弹出的电子邮件地址。在单词宏完成后的整个后处理只需要10到15分钟。我可能花了比需要更多的时间,因为无效的电子邮件地址将被我的dB链接忽略。
宏不提取弹跳代码,因此您不知道它是软弹跳(邮箱已满)或硬弹跳(未找到收件人)。在将它们放入文件夹之前,您可以尝试识别它们,或者您可以采取一种策略,在永久删除之前,需要在一段时间内进行两次反弹。你说了算。
我应该注意,我不是一个VBA程序员。40年前,我在一台商品电脑上学习了基本语言,有时还会接触到一些Msft访问功能。我使用VBA for Word的大部分经验仅限于记录宏,然后使用自动生成的代码自动执行一些重复任务。知道自己在做什么的人很可能会大大改进我的代码,但这对我来说是一个很大的节省时间。
发布于 2015-06-01 02:50:28
经过多次狩猎,我想出了以下的功能。一些正文文本仍然包含无效字符(不知道为什么),但总的来说,它是90%的正确。此函数解析传递的Outlook项集合,并将所有唯一的电子邮件地址(在ReportItem的正文中找到)添加到字符串列表中,该字符串列表被写入后面的“立即”窗口。
Private Sub ListEmailAddresses(outlookItems As Outlook.Items)
Dim folder As Outlook.MAPIFolder = Nothing
Try
Dim emailAddresses As New List(Of String)
If TypeOf outlookItems.Parent Is Outlook.MAPIFolder Then
folder = CType(outlookItems.Parent, Outlook.MAPIFolder)
End If
For i = 1 To outlookItems.Count
Dim objItem As Object = outlookItems(i)
Try
If TypeOf objItem Is Outlook.ReportItem Then
Dim rpt As Outlook.ReportItem = TryCast(objItem, Outlook.ReportItem)
Dim temp() As Byte = System.Text.Encoding.Unicode.GetBytes(rpt.Body.ToArray())
Dim sb As New System.Text.StringBuilder
For z As Integer = 0 To temp.Length - 1
sb.Append(Chr(temp(z)))
Next
Dim rptBody As String = sb.ToString
Dim mc As MatchCollection = Regex.Matches(rptBody, _
"([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})")
Dim results(mc.Count - 1) As String
For x As Integer = 0 To results.Length - 1
Dim emailAddr As String = ValueIfNull(mc(x).Value, "").ToLower
If Not String.IsNullOrWhiteSpace(emailAddr) Then
If Not emailAddresses.Contains(emailAddr) Then
emailAddresses.Add(emailAddr)
End If
End If
Next
End If
Catch ex As Exception
' Do Something if you care.
Finally
Marshal.ReleaseComObject(objItem)
End Try
Next
emailAddresses.Sort()
Debug.WriteLine(emailAddresses.ToSeparatedString(Environment.NewLine))
Catch ex As Exception
' Do Something if you care.
Finally
If folder IsNot Nothing Then Marshal.ReleaseComObject(folder)
End Try
End Sub
https://stackoverflow.com/questions/25447867
复制相似问题