Есть несколько способов поиска определённого текста в теле письма с помощью VBA. Можно воспользоваться функциями InStr, Len, Left или Right, чтобы найти и извлечь текст, а можно воспользоваться регулярными выражениями. Именно о применении регулярных выражений в коде VBA пойдёт речь в данной статье.

Например, требуется извлечь код отслеживания посылки UPS, отправленной с Amazon.com. Такой код имеет формат как на скриншете ниже:

tracking-code-sample-regexp

Нужно находить в тексте слова «Carrier Tracking ID», затем, возможно, пробел и двоеточие.

.Pattern = "(Carrier Tracking ID\s*[:]+\s*(\w*)\s*)"

Такое выражение извлечёт из текста из примера цифро-буквенный код 1Z2V37F8YW51233715.

Используйте \s* для определения неизвестного количества пробелов (пробелы, символы табуляции, перевода строки и т.д.)
Используйте \d* для определения только цифр
Используйте \w* для определения цифро-буквенных символов, как используются в кодах отслеживания посылок UPS.

Чтобы использовать этот образец кода откройте редактор VBA с помощью комбинации Alt+F11. Правой кнопкой мыши нажмите на Проекте и выберите Insert > Module. Скопируйте и вставьте код макроса в модуль. Для работы макроса нужно задействовать библиотеку Microsoft VBScript Regular Expressions 5.5 в меню Tools -> References… VBA-редактора:

tools-references-regexp

Если включена библиотека VBScript Expressions 1, то отключите её сняв соответствующую галочку. Невозможно одновременно использовать v1 и v5.5.

Sub GetValueUsingRegEx()
 ' Подключите библиотеку VB Script
 ' Microsoft VBScript Regular Expressions 5.5
 
    Dim olMail As Outlook.MailItem
    Dim Reg1 As RegExp
    Dim M1 As MatchCollection
    Dim M As Match
 
    Set olMail = Application.ActiveExplorer().Selection(1)
   ' Debug.Print olMail.Body
 
    Set Reg1 = New RegExp
 
    ' \s* = скрытые пробелы
    ' \d* = цифры
    ' \w* = цифро-буквенные выражения
 
    With Reg1
        .Pattern = "Carrier Tracking ID\s*[:]+\s*(\w*)\s*"
        .Global = True
    End With
    If Reg1.test(olMail.Body) Then
 
        Set M1 = Reg1.Execute(olMail.Body)
        For Each M In M1
            ' M.SubMatches(1) is the (\w*) in the pattern
            ' use M.SubMatches(2) for the second one if you have two (\w*)
            Debug.Print M.SubMatches(1)
 
        Next
    End If
 
End Sub

Если будем искать только двоеточие .Pattern ="([:]+\s*(\w*)\s*)", тогда код вернёт только первое слово после двоеточия из каждой строки:

UPS
May
Standard
1Z2V37F8YW51233715
Diane

Это потому, что (\w*) указывает, что нужно получить следующую после двоеточия цифро-буквенную строку, не всю строку, и не включать пробелы.

Получение двух и более значений из сообщения

Если вам требуется использовать два или несколько шаблонов, то можно повторить часть c With Reg1 до End If, для каждого из шаблонов или воспользоваться оператором Case.

Код ниже осуществляет поиск по трём шаблонам, создает строку и добавляет ее в поле темы сообщения. Каждый Case представляет свой шаблон. В этом примере отыскивается только первое вхождение каждого шаблона. .Global = False указывает, что нужно остановиться, когда находится первое совпадение.

Данные, которые мы ищем имеют следующий формат:

Order ID : VBNSA-123456
Order Date: 09 AUG 2013
Total $54.65

/n в конце шаблона соответствует концу строки, а strSubject = Replace(strSubject, Chr(13), "") удаляет любые переносы строки.

Sub GetValueUsingRegEx()
    Dim olMail As Outlook.MailItem
    Dim Reg1 As RegExp
    Dim M1 As MatchCollection
    Dim M As Match
    Dim strSubject As String
    Dim testSubject As String
 
    Set olMail = Application.ActiveExplorer().Selection(1)
 
    Set Reg1 = New RegExp
 
For i = 1 To 3
 
With Reg1
    Select Case i
    Case 1
        .Pattern = "(Order ID\s[:]([\w-\s]*)\s*)\n"
        .Global = False
 
    Case 2
       .Pattern = "(Date[:]([\w-\s]*)\s*)\n"
       .Global = False
 
    Case 3
        .Pattern = "(([\d]*\.[\d]*))\s*\n"
        .Global = False
    End Select
 
End With
 
 
    If Reg1.test(olMail.Body) Then
 
        Set M1 = Reg1.Execute(olMail.Body)
        For Each M In M1
            Debug.Print M.SubMatches(1)
            strSubject = M.SubMatches(1)
 
         strSubject = Replace(strSubject, Chr(13), "")
         testSubject = testSubject & "; " & Trim(strSubject)
         Debug.Print i & testSubject
 
         Next
    End If
 
Next i
 
Debug.Print olMail.Subject & testSubject
olMail.Subject = olMail.Subject & testSubject
olMail.Save
 
Set Reg1 = Nothing
 
End Sub

Использование функции RegEx

Эта функция позволяет использовать регулярное выражение в более чем одном макросе.

Если вам нужно использовать более чем один шаблон с функцией, задайте для шаблон в макросе regPattern = "([0-9]{4})" и используйте это в функции: regEx.Pattern = regPattern. Не забудьте добавить Dim regPattern As String в верхней части модуля.

Function ExtractText(Str As String) ' As String
 Dim regEx As New RegExp
 Dim NumMatches As MatchCollection
 Dim M As Match
 
'этот шаблон ищет 4 подряд идущие цифры в теме письма
 regEx.Pattern = "([0-9]{4})"
 
' используейте это, если нужно задвать разные шаблоны
' regEx.Pattern = regPattern
 
 Set NumMatches = regEx.Execute(Str)
 If NumMatches.Count = 0 Then
      ExtractText = ""
 Else
 Set M = NumMatches(0)
     ExtractText = M.SubMatches(0)
 End If
 code = ExtractText
 End Function

Этот макрос показывает, как использовать функцию Regex. Если в теме письма есть соответствующая шаблону комбинация (в пример функции, 4-х значное число), то будет создан ответ. Если нет, то появляется окно с сообщением. Чтобы использовать функцию с разными макросами, раскомментируйте строки, содержащие regPattern.

Dim code As String
'Dim regPattern As String
 
Sub RegexTest()
 
Dim Item As MailItem
Set Item = Application.ActiveExplorer.Selection.Item(1)
 
' используйте для передачи шаблона в функцию
'regPattern = "([0-9]{4})"
 
ExtractText (Item.Subject)
 
If Not code = "" Then
Set myReply = Item.Reply
myReply.Display
 
Else
MsgBox "Тема не содержит 4-х значного числа"
End If
 
End Sub

Источник

Полезные ссылки

Order_macros

Теги:
 

1 Комментарий » в “Использование регулярных выражений в VBA для извлечения текста из сообщений Outlook”

  1. Virtual Private Servers:

    Теперь к Visual Basic добавился объект RegExp, который содержит в себе все, что нужно для работы с регулярными выражениями.

Комментировать