Option Compare Database
Option Explicit
' http://www.regular-expressions.info/email.html
' http://regexlib.com/Search.aspx?k=email&c=-1&m=-1&ps=100
Private Const strRFC2822 = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!" & _
"#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:" & _
"[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:" & _
"[a-z0-9-]*[a-z0-9])?"
Public Function GetEmails(ByVal strFilePath As String) As String
Dim lngCounter As Long
Dim astrEmails() As String
Dim astrUnique() As String
Dim strEmails As String
astrEmails = Split(GetAllEmails(strFilePath), ";")
BubbleSortRecords astrEmails()
GetUnique astrEmails(), astrUnique()
For lngCounter = LBound(astrUnique()) To UBound(astrUnique())
strEmails = strEmails & astrUnique(lngCounter) & ";"
Next lngCounter
GetEmails = strEmails
End Function 'GetEmails
Private Sub GetUnique(ByRef astrEmails() As String, ByRef astrUnique() As String)
' Source: http://stackoverflow.com/questions/3017852/vba-get-unique-values-from-array
Dim lngCounter As Long
Dim var As Variant
Dim objDict As Object
Set objDict = CreateObject("Scripting.Dictionary")
For lngCounter = LBound(astrEmails()) To UBound(astrEmails())
objDict(astrEmails(lngCounter)) = 1
Next lngCounter
lngCounter = 0
For Each var In objDict.Keys()
ReDim Preserve astrUnique(lngCounter)
astrUnique(lngCounter) = var
lngCounter = lngCounter + 1
Next var
End Sub ' GetUnique
Private Sub BubbleSortRecords(ByRef astrText() As String)
' This will sort the email addresses in ascending alphabetical order
' Not the most efficient way - look up quick sort - but a quick win
Dim lngInner As Long
Dim lngOuter As Long
Dim strTemp As String
For lngOuter = LBound(astrText()) To (UBound(astrText()) - 1)
For lngInner = (lngOuter + 1) To UBound(astrText())
If astrText(lngOuter) > astrText(lngInner) Then
strTemp = astrText(lngOuter)
astrText(lngOuter) = astrText(lngInner)
astrText(lngInner) = strTemp
End If
Next lngInner
Next lngOuter
End Sub ' BubbleSortRecords
Private Function GetAllEmails(ByVal strFilePath As String) As String
Dim lngFileNumber As Integer
Dim strData As String
Dim strText As String
Dim strEmail As String
lngFileNumber = FreeFile()
Open strFilePath For Input As #lngFileNumber
While Not EOF(lngFileNumber)
Line Input #lngFileNumber, strData
strData = Replace(strData, "=", " ")
strData = Replace(strData, "<", " ")
strData = Replace(strData, ">", " ")
strData = Trim(strData)
strEmail = GetEmailFromLine(strData)
If strEmail <> vbNullString Then
strText = strText & strEmail & ";"
End If
Wend
Close #lngFileNumber
GetAllEmails = strText
End Function ' GetAllEmails
Private Function GetEmailFromLine(ByVal strText As String) As String
Dim astrTemp() As String
Dim lngCounter As Long
astrTemp() = Split(strText, " ")
For lngCounter = LBound(astrTemp()) To UBound(astrTemp())
If IsValidEmail(astrTemp(lngCounter)) Then
GetEmailFromLine = astrTemp(lngCounter)
Exit Function
End If
Next lngCounter
End Function ' GetEmailFromLine
Private Function IsValidEmail(ByVal strEmail As String) As Boolean
Dim objRegEx As Object
On Error GoTo Fin
Set objRegEx = CreateObject("Vbscript.Regexp")
With objRegEx
.Pattern = strRFC2822
.IgnoreCase = True
IsValidEmail = .Test(strEmail)
End With
Fin:
Set objRegEx = Nothing
If Err.Number <> 0 Then MsgBox "Error: " & _
Err.Number & " " & Err.Description
End Function ' IsEmailAddress