• Outlook User
  • New Outlook app
  • Outlook.com
  • Outlook Mac
  • Outlook & iCloud
  • Developer
  • Microsoft 365 Admin
    • Common Problems
    • Microsoft 365
    • Outlook BCM
    • Utilities & Addins

Use RegEx to extract text from an Outlook email message

Slipstick Systems

› Developer › Use RegEx to extract text from an Outlook email message

Last reviewed on May 1, 2019     199 Comments

Getting text out of a message body isn't as hard as it sounds, provided there is something in the body to search on. For example, if you are looking for a tracking code in an email and it's always identified as "Tracking code:" you can use InStr, Len, Left or Right functions to find and extract the tracking code.

Or you can use Regular Expressions.
Extract codes from email messages

For example, to extract the UPS tracking numbers for packages sent by Amazon.com and formatted as shown in the screenshot, I need to look for the words "Carrier Tracking ID", followed by possible white space and a colon (:).

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

This returns the next alphanumeric string, or in my example, 1Z2V37F8YW51233715. (There are two tracking numbers in the email message and both are returned.)

Use \s* to match an unknown number of white spaces (spaces, tabs, line feeds, etc)
Use \d* to match only digits
Use \w* to match alphanumeric characters, such as are used in UPS tracking codes.

To use this code sample, open the VBA Editor using Alt+F11. Right-click on Project1 and choose Insert > Module. Paste the following code into the module.
 

You'll need to set a reference to the Microsoft VBScript Regular Expressions 5.5 library in Tools, References.
Set a reference to VBScript Expressions

Note: if VBScript Expressions 1 is selected, deselect it. You can't use both v1 and v5.5.

Don't forget, macro security needs to be set to low during testing.

Sample macros using regex are at the following links. Use Copy to Excel code sample to copy a row of text to a row of cells in Excel and Select a name in a Word document then create a Contact to create a contact from a resume or similar file.

Sub GetValueUsingRegEx()
 ' Set reference to VB Script library
 ' 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* = invisible spaces
    ' \d* = match digits
    ' \w* = match alphanumeric
    
    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

If we look for just the colon (.Pattern ="([:]+\s*(\w*)\s*)" ), we get just the first word in the results:

UPS
May
Standard
1Z2V37F8YW51233715
Diane

This is because (\w*) tells the code to get the next alphanumeric string, not the entire line, and strings do not include spaces.

Get two (or more) values from a message

If you need to use 2 or more patterns, you can repeat the With Reg1 through End if for each pattern or you can use Case statements.

This sample code looks for 3 patterns, creates a string and adds it to the subject field of a message.

Each case represents a different pattern. In this sample, we want just the first occurrence of each pattern; .Global = False instructs the code to stop when it finds the first match.

The data we are looking for is formatted like this:

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

\n at the end of the pattern matches a line break, and strSubject = Replace(strSubject, Chr(13), "") cleans any line breaks from the string.

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

 

Use a RegEx Function

This function allows you to use the regex in more than one macro.

If you need to use more than one pattern with the function, set the pattern in the macro regPattern = "([0-9]{4})" and use this in the function: regEx.Pattern = regPattern. Don't forget to add Dim regPattern As String at the top of the module.

Function ExtractText(Str As String) ' As String
 Dim regEx As New RegExp
 Dim NumMatches As MatchCollection
 Dim M As Match
 
'this pattern looks for 4 digits in the subject
 regEx.Pattern = "([0-9]{4})"

' use this if you need to use different patterns. 
' 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

This simple macro shows how to use the Regex Function. If the subject matches the regex pattern (in function example, a 4-digit number), a reply is created; if it does not contain a 4 digit number, a message box comes up. To use the function with different macros, uncomment the lines containing regPattern.

Dim code As String
'Dim regPattern As String

Sub RegexTest()

Dim Item As MailItem
Set Item = Application.ActiveExplorer.Selection.Item(1)

' use this to pass a pattern to the function
'regPattern = "([0-9]{4})"

ExtractText (Item.Subject)
 
If Not code = "" Then
Set myReply = Item.Reply
myReply.Display

Else
MsgBox "The subject does not contain a 4 digit number"
End If

End Sub

More Information

RegExLib.com Regular Expression Cheat Sheet (.NET)
Introduction to Regular Expressions (Scripting)
Regular Expressions Quick Start
Usage samples at OutlookForums:
Script to use in a rule when a message arrives to send to email in the message
VB Script, remove text from subject line when forwarding
rule to change subject, pull email addresses from body, and forward with template
Usage samples at Slipstick.com:
Create Appointment From Email Automatically
Use RegEx to extract text from an Outlook email message
View the CC or BCC Addresses in a Sent Message
Use RegEx to extract text from an Outlook email message was last modified: May 1st, 2019 by Diane Poremsky
Post Views: 77

Related Posts:

  • Open Hyperlinks in an Outlook Email Message
  • Run a Script Rule: Forwarding Messages
  • Parsing text fields in Outlook
  • Create Appointment From Email Automatically

About Diane Poremsky

A Microsoft Outlook Most Valuable Professional (MVP) since 1999, Diane is the author of several books, including Outlook 2013 Absolute Beginners Book. She also created video training CDs and online training classes for Microsoft Outlook. You can find her helping people online in Outlook Forums as well as in the Microsoft Answers and TechNet forums.

Comments

  1. Damian says

    February 23, 2022 at 2:09 am

    Hi Diane, I have some code that formats .Subject lines, and I have been asked to add a check that if there's a date in the subject line, remove it and prefix the .Subject line with .ReceivedTime. before passing it on to the next If statement.

    GetValueUsingRegEx() using your Date Pattern is working however due to my lack of knowledge I'm not sure how to remove the date.

    Any assistance is greatly appreciated.

    Damian

    Reply
  2. Melvin says

    January 28, 2021 at 1:04 pm

    Hi Diane,

    Hope you are doing well and keeping safe.

    I need your help with below situation.

    I am looking for a macro that can find Matching Keywords from an excel cell within a Saved Outlook email in a windows folder and Copy such matching emails to different folder.

    For example, I have 3 texts in excel in Column A.

    Tom
    Dick
    Harry

    And I got 300 outlook emails saved in a windows folder. I would like a VBA macro that would search for these 3 texts within these 300 emails and if found a match, copy such matching emails to a different windows folder for my further review.

    Not sure if you can assist.

    Reply
  3. Frank says

    September 20, 2019 at 11:50 pm

    I use an application called email templates (emailtemplates.com) that installs on Outlook 2000. It uses RegEx to parse a highlighted email, rewrite parts of it to a new email, that is ready to send. When I upgraded to Outlook 2003, my templates broke since 2003 changed the CSS engine from IE to Word.

    The problem I am having is that the company website is dormant and they seem to have gone out of business, but I will be forced to upgrade to a later Outlook as 2000 will not run on later windows. I upgraded to windows 10 and Outlook 2010. The templates install without error, but they do not appear on the Ribbon.

    Do you know if there is a way to install an Outlook 2000 application on Outlook 2010? any suggestions?

    I purchased a couple of your books and hope that they may help solve my issue. Expect them at month end.

    Reply
  4. Showrya Krovvidi says

    August 22, 2019 at 2:30 am

    Hi Diane, Thanks for all your commendable work with respect to VBscript.

    I have been searching for a solution since the past two weeks for one of my critical projects. We have configured emails to be triggered for multiple instances and we receive approximately 1000 emails alerts a day stating the configured URLs are down. Most of them are false positives and it has become a tedious job for me to check all the urls manually. I am a novice in writing macros, but I have tried multiple ways for my problem and no luck.

    I need a macro that will open the first url from all the selected emails in an excel and then checks for the http status of the same and return the status in the excel. I was able to find few solutions to check the http status automatically, but getting all the first urls from a set of emails is the toughest part where I have been stuck since the past 2 weeks. Could you please let me know if this can be ever achieved through a macro. If yes, how?

    Thanks in advance.

    Reply
  5. Prakhar Goyal says

    February 14, 2019 at 3:53 am

    Hi Diane,
    My data in body is like -
    Survey ID
    123456
    Ticket No
    1234
    Entered
    08-Feb-19 03:45 PM
    How to extract this data in excel so that under survey Id, ticket no, entered column I get respective data.

    Reply
    • Diane Poremsky says

      April 2, 2019 at 9:27 pm

      Are the values under the labels or to the right of the label? If they are on the line above, this format should work:
      .Pattern = "Survey ID\s*\r(\d*)\s*"

      if \r doesn't work, try \n.

      Reply
  6. Deepak says

    June 14, 2017 at 6:14 am

    Hi ,
    I would like to extract the E-mail Content ( Subject and Message) as input & pass this to some other variable through VB script , Do you have any sample code for this ?

    Deeps

    Reply
    • Diane Poremsky says

      October 18, 2017 at 10:21 am

      sorry I missed this earlier. There are several macros here that do basically this - you need to use something like
      strSubject = objectname.subject
      strBody = objectname.body
      then pass those two strings along.

      Reply
  7. Vicky Kr says

    May 8, 2017 at 12:06 pm

    Just to add : My aim is to create a rule which will run the script on arrival of a new email
    and extract a text (ticket number) from the email body and pass it to a batch script/js script for further action.
    I simple question.
    how can i pass the variable to a batch script or command line.
    MsgBox var - prints its value
    but when i try to send it to batch script the value is not transferred but the variable name
    eg
    shell.Run "C:UsersjsDesktopcreateIndexcreateindex.bat var"

    Reply
    • Diane Poremsky says

      May 8, 2017 at 11:55 pm

      is the shell run line in the same macro where msgbox var is? if not, you need to dim var outside of the macro so its global.

      Try this - you may be able to drop the strArgument lines and use var in the shell command.
      Dim strBat As String
      Dim strArgument As String
      strBat = "C:\Users\jsDesktop\createIndex\createindex.bat"
      strArgument = "/" & var
      Call Shell("""" & strBat & """ """ & strArgument & """", vbNormalFocus)

      Reply
  8. Vicky Kr says

    May 8, 2017 at 11:55 am

    Hi Diane,
    I am using this for extracting a ticket number from the email body. For this I have created a rule which runs the script on arrival of a new email. But
    Set olMail = Application.ActiveExplorer().Selection(1)
    this line often shows the body of old email and not the current one. (I have added MsgBox to display the email body) Am i missing out something. I am new to this and any guidance would be very helpful to me.

    Apart from setting the reference to Microsoft VBScript Regular Expressions 5.5, do we need to do anything else as set up?
    As my requirement is exactly same but somehow this is not working for me.
    Please help.

    Reply
    • Diane Poremsky says

      May 8, 2017 at 11:44 pm

      if you are using run a script rules, you won't use Set olMail = Application.ActiveExplorer().Selection(1) to identify the message - the rule chooses the message that matches the condition and "item as outlook.mailitem" (item can be changed to olmail) passes it to the script.

      change the top part of the first macro to this to use it in a rule -
      Sub GetValueUsingRegEx(olMail as outlook.mailitem)
      ' Set reference to VB Script library
      ' Microsoft VBScript Regular Expressions 5.5

      Dim Reg1 As RegExp
      Dim M1 As MatchCollection
      Dim M As Match

      ' Debug.Print olMail.Body

      Reply
    • Michael Krueger says

      April 2, 2019 at 5:40 pm

      Dear Diane,

      I have tried the code you have posted to Get two (or more) values from a message and it fails on, Set olMail = Application.ActiveExplorer().Selection(1).

      I get a run-time error 438:
      Object doesn't support this property or method..

      I am completely stuck Can you help?

      Michael

      Reply
      • Diane Poremsky says

        April 2, 2019 at 10:53 pm

        Do you have an email message selected when you run the macro?

      • Shar says

        December 30, 2020 at 4:36 am

        same 438 error for me as well

  9. Larry MC says

    April 10, 2017 at 2:17 pm

    We created a rule that all incoming email from external sources prepends the message in the body with ****EXTERNAL EMAIL***** so that if someone spoofs our CEO's email, they can tell immediately it is not truly from him. We are running a hybrid set up with EXCH 2010 on prem. What users are wanting to do is if they forward or reply to anyone, the text we added by rule is automatically removed. Can a button in the toolbar be created using this so it removes the unwanted text only?

    Reply
    • Diane Poremsky says

      April 17, 2017 at 7:51 am

      Dang, i must be losing it - I swear I replied to this last week. :( This:
      https://www.slipstick.com/developer/vba-when-reply-is-clicked/

      and using oresponse.body = oresponse.body = replace(responses.body, "****EXTERNAL EMAIL*****", "") (You may need to use htmlbody instead of body)

      Reply
  10. Hattori Hanzo says

    February 14, 2017 at 7:31 pm

    I have been trying to match all IP addresses in the body of the message but unfortunately have had no success using example regex expressions that I have found online.

    I would like the macro to match all IP address in the body of the message. Any ideas of how to achieve this?

    Thank you so much.

    Reply
    • Diane Poremsky says

      February 15, 2017 at 12:41 am

      What code were you using? This should work - ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})

      Reply
      • Hattori Hanzo says

        February 16, 2017 at 6:25 pm

        I've ended up using this which seems to work but only matches the first IP address in the message.

        `((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))

        There may be more than 1 IP address in the message, and I need to match all of them and write to excel.

        Thank you in advance.

      • Diane Poremsky says

        February 16, 2017 at 10:02 pm

        Are you using .Global = True ? That keeps looking for more matches. you'll need to 'save' each match, either to one string (strIP = strIP & "; " & M.SubMatches(1)) or to new variables (best if there will always be a specific # of matches).

  11. Jjayson says

    February 7, 2017 at 9:52 pm

    Hi! Loving the seeming possibilities here!

    I'm a DJ who would LOVE to be able to send an auto-reply to prospective clients from whom I receive lead information, which comes to me via a "do not reply to this email address" account, in the following form in the body:

    Lead Information
    Event Date: Saturday mm/dd/yyyy
    Type of Event: Not Provided
    Prospect's Name: Firstname Lastname
    Email Address: email@domain.com
    Phone Number: xxx-xxx-xxxx
    Location: Not Provided

    I would want to auto-send a reply to email@domain.com which contains a basic invitation to discuss needs and wants and an inquiry into what days/times might be good to do so.

    I hope this isn't terribly complicated. I've taken a number of your tips and have loved the results! Hoping to see this come to life!

    Thanks so very much!

    Reply
    • Diane Poremsky says

      February 15, 2017 at 12:49 am

      If you need more than the address, use the sample at https://www.slipstick.com/developer/regex-parse-message-text/#2
      if you just need the address, there is a sample here - https://www.slipstick.com/developer/run-a-script-rule-autoreply-using-a-template/ under 'Reply to a web form generated message'

      Reply
  12. Cristian Villegas says

    October 17, 2016 at 4:59 pm

    Hi Diane, I'm kinda new to VBA and I just want to know if I can use the RegEx function to extract two rows from a generic email and then "paste" them into a oft template I made. Thanks for your help.

    Reply
    • Diane Poremsky says

      October 17, 2016 at 10:05 pm

      As long as there is a pattern you can use to identify the parts you want, yes, you can.
      This will bring up the template as a new message - Set objMsg = Application.CreateItemFromTemplate("C:\path\to\test-rule.oft") - if there is content in the body, you'll need to do something like .body = .body & strText to insert the text.

      Reply
      • Cristian Villegas says

        October 18, 2016 at 10:29 am

        Thanks for replying Diane, I'll try it out.

  13. Darren McGettigan says

    September 21, 2016 at 4:22 pm

    I think this is exactly what I am looking for, but I don't have Microsoft VBScript Regular Expressions 5.5 as an option under "References", using Outlook 2016. Am I doing something wrong?

    Reply
    • Diane Poremsky says

      September 21, 2016 at 8:23 pm

      Type N in the list so it jumps down the N's then scroll up a little. if its really not there, see if c:\windows\syswoe64\vbscript.dll exists.
      references dialog

      Reply
  14. JOSE ANGULO says

    September 20, 2016 at 6:49 pm

    I mean, a table that is into the body of an incoming mail

    Reply
  15. JOSE ANGULO says

    September 20, 2016 at 12:47 pm

    How to select and copy each row in a table?

    Reply
    • Diane Poremsky says

      September 20, 2016 at 10:09 pm

      remove the ' from in front of debug.print omail.body so you can see how it looks to the regex engine. You'll need to make a pattern that can find that.

      Reply
      • JOSE ANGULO says

        September 22, 2016 at 8:46 am

        Ok. Thank you Diane.

  16. Kaijer H says

    September 1, 2016 at 6:38 pm

    Thank you Diane, you are an angel to mankind. This post and the codes are awesome and you don't even charge for this awesomeness. And answering each comments for so long time, I mean who does that ! You truly deserve a salute. God bless you.

    Reply
  17. Phil Reinemann says

    August 24, 2016 at 7:01 pm

    That is some good information, Diane.

    Can it work for multi-paragraphs (blank lines between), multi-line text per paragraph containing URLs, ampersands, tabs, spaces, hyphens, commas, periods and open/close parentheses?
    My intent is within the body of an email message to replace all occurrences of the above with null (or a new-line or a space if easier) for each occurrence.

    There is known text at the start and end of the paragraph "set". (One use is to remove standard corporate signatures from the internal part of multiply forwarded or replied emails so that there is a single signature at the end - the one at the end is later added by Exchange.)

    Reply
    • Diane Poremsky says

      August 26, 2016 at 8:13 pm

      It can, if the pattern is correct.

      Reply
  18. Xavier says

    August 24, 2016 at 5:39 am

    Hi Diane,
    This has been really useful for me!

    Can I ask you for another case?
    I would like to read an email and detect if there are more lines with EQUIPMENT word in each line, and then separate every line.

    For example:
    EQUIPMENT 1: Television
    EQUIPMENT 2: USB Keyboard

    Every mail can have different number of equipment in it.
    I would like to keep Televison and USB Keyboard in this case.

    Thanks!
    Xavier

    Reply
    • Diane Poremsky says

      August 25, 2016 at 10:43 am

      This should work -
      "(EQUIPMENT (\d)*: (\w*))"
      you'd use this to get the # and words separately
      Debug.Print M.SubMatches(1)
      Debug.Print M.SubMatches(2)

      or M.SubMatches(0) if you wanted the entire phrase. You could also get the # and words together by wrapping both in ().
      (0 = what is inside the first set of (), 1 = second set etc.)

      Reply
  19. Patrick says

    July 29, 2016 at 12:27 pm

    I've been working a a macro which for a selected email will extract certain data from the selected email and uses that for the body text (plus subject). I have found a solution for most (3 out of 4) of the texts I need to extract and reuse. However, not for one of them. I'm wondering if I can use this RegEx for issue I'm having, but I wouldn't know how start. I've tried to attach my img, to show you where I'm having difficulty with, but I can only enter an URL, where the image is on my PC. Could I load the img to my slipstick 'profile' and use it then?

    Reply
    • Diane Poremsky says

      August 25, 2016 at 10:31 am

      It would probably be easier to post the question in our forum at forums.slipstick.com

      Reply
  20. Riaz says

    July 19, 2016 at 10:04 am

    Hi Diane, Firstly.. Thanks a bunch for posting the above codes. Its been very helpful. I have been trying to use the code provided to check for a date, but cant seem to get it right. can you please assist.

    I am using .Pattern = "(Certificate Date[:]([\d]*/[\d]*/[\d]*)\s*)\n" to check for Certificate Date: 30/06/2016. But it aint working.

    Furthermore I am using

    .Pattern = "(Amount of Tax withheld (Ksh)[:]([\d]*,[\d]*\.[\d]*))\s*\n"

    to also check and retrieve the amount from the line

    Amount of Tax withheld (Ksh): 4,319

    Please assist on the above two lines.

    Reply
    • Diane Poremsky says

      July 20, 2016 at 12:04 am

      the date looks valid. Try using .Pattern = "(Certificate Date[:]\s*(\d\d?/\d\d?/20\d\d))"

      try his for the cost: .Pattern = "(Amount of Tax withheld (Ksh)[:]([\d]*,?[\d]*\.?[\d]*))" - this should match 4,319 or 4,319.00 or 4319

      Reply
      • Riaz says

        July 20, 2016 at 4:47 am

        Hi Diane, Thanks alot for your prompt response. The Pattern for the date worked very well, but the one for the amount did not.

      • Diane Poremsky says

        August 25, 2016 at 10:28 am

        This should work as long as you don't reuse the phrase in the message -
        "(Amount of Tax withheld (Ksh)[:](.*) )"

  21. Timothy says

    June 20, 2016 at 12:38 pm

    Using your code above, how would I check for
    Date: 6/17/16
    Thanks in advance.

    Reply
    • Diane Poremsky says

      June 21, 2016 at 10:05 am

      This pattern should work -
      .Pattern = "([\d]*/[\d]*/[\d]*)\s"
      With one set of (), you'd use
      Debug.Print M.SubMatches(0) - if you need to use M.SubMatches(1), wrap it in another set of ().

      Reply
  22. Mark says

    May 24, 2016 at 2:37 pm

    I am very new to VB and am trying to auto-assign a "Forward To" email based on contents of an undeliverable message. Does anyone have a full macro that I could use?

    Reply
    • Diane Poremsky says

      June 21, 2016 at 11:25 am

      I have this - https://www.slipstick.com/outlook/rules/run-script-rule-change-subject-message/ - change the pattern to look for email addresses then use M.SubMatches(1) as the email address instead of writing it out.

      Reply
  23. Glenn Sampson says

    April 21, 2016 at 2:44 am

    Great post it's helped me on a couple of task now however this time round I'm stumped why this pattern fails.

    This is in the text in my olMail.body
    Settlement Date: 09-Aug-2013

    This is my .Pattern
    .Pattern = "^(Settlement Date)\:([\w-\s]*)(([0-9])|([0-2][0-9])|([3][0-1]))\-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\-\d{4}$"

    using Regex Testers the .pattern passed....

    Any ideas welcome
    Thanks
    Glenn

    Reply
  24. Larry Marks says

    March 22, 2016 at 3:34 pm

    Trying to use the code to extract a line from email (draft) body and replace the subject. Using a .pattern of SUBJECT (which is in the body), I only get the first word of a multiword line--how do I extract the full line? Thanks.

    Reply
    • Diane Poremsky says

      March 22, 2016 at 8:59 pm

      This works to get 2 lines - .Pattern = "Subject[:](((.*)\n(.*)))"

      i used replace function to merge the two lines into one line:
      Debug.Print Replace(M.SubMatches(1), vbCrLf, " ")

      Reply
      • Larry Marks says

        March 23, 2016 at 10:31 am

        When I use that code, I get "run time error: 5020". Debugs to the "If Reg.1test (olMail.Body) Then" line.

      • Diane Poremsky says

        March 23, 2016 at 10:53 am

        replace can trigger that error code but then it should die on the debug print line. I'd try removing it anyway... but it's more likely the pattern. See if it errors if you remove the \n.

      • Larry Marks says

        March 25, 2016 at 9:36 am

        Still getting error after removing /n. Dialog says Method 'Test" of object 'IRegExp2' failed

      • Diane Poremsky says

        March 27, 2016 at 11:08 pm

        do you get the error if you use .Pattern = "Subject[:]((.*))"

      • Larry Marks says

        March 28, 2016 at 2:28 pm

        For the moment-- it worked-- getting the correct M.Submatches(1) to replace the subject line--thanks for bearing with me--

      • Glenn Gutmacher says

        October 17, 2017 at 8:46 am

        Diane, my situation is somewhat reminiscent of Larry's, but adapting your solution doesn't seem to work, so hope you have an idea. I have a big Outlook folder of HTML-formatted messages in a consistent pattern (relevant snippet of one such message appended below). I have no problem grabbing the person's name out of a preceding section of the email that looks like "Great news! Glenn Gutmacher has just applied..." using: .Pattern = "(news![\s]([\w-\s]*)[\s]has)" but we would like to grab the metro location and degree/major in the section following Applicant which is immediately followed by 2 line returns before the name, then there's 1 space after the name, a line return, then 2 tab chars, then the
        tag, city name, a comma, line return, another tab, then the 2-letter state abbreviation, a space, line return, 2 tabs,
        , line return, 2 tabs, the degree data we want, a space, 2 line returns, and (if needed) a consistent Message From Applicant end marker. I was hoping "(Applicant([.]*)\n\n([\w-\s]*))\n" would be the pattern, but it grabs absolutely nothing whether I do .Global = True or False. Help!

        Applicant

        Glenn Gutmacher

        Minneapolis,
        MN

        MBA and MS Data Science Candidate

        Message From Applicant

      • Diane Poremsky says

        October 18, 2017 at 11:51 am

        Hmmm. That is a tough one, because picking up multiple lines doesn't always work. Rather than global (which looks for additional matches after finding the first), you need to make sure multiline is enabled.
        .MultiLine = True

        This worked in my test:
        .Pattern = "(Applicant\s*\n*\t*([\w ]*)\n*\s*\t*([\w ,]*)\s*\n*\t*([\w]*)\s*\n*\t*([\w ]*)\s*\n*\t*(.*))"

  25. Ralph Moran says

    March 15, 2016 at 5:33 pm

    Hello Diane, I need your help with Outlook 2010.

    I need to export all addresses from the emails to make a data analysis. I have a TON, literally, folders inside my Inbox. When I go to Export/Import section to export CVS file, I select Inbox folder and just the emails that are into this folder are exported. How can I export the emails that are inside the Inbox folder?

    Reply
    • Diane Poremsky says

      March 15, 2016 at 10:30 pm

      CSV files are one per folder. You just need the sender name & address? The macro at https://www.slipstick.com/developer/code-samples/macro-export-outlook-fields-excel/ can do that but it needs tweaked to walk the folders.

      Reply
      • Ralph Moran says

        March 16, 2016 at 6:13 pm

        Thanks Diane for quick reply. What I need is take names, emails and addresses from mails in all subfolders.

        I'm going to check this out.

        I'll appreciate if you can share the way to walk into all subfolders.

        Thanks again

      • Diane Poremsky says

        March 22, 2016 at 5:34 pm

        I see you figured the multifolder issue out before I got a chance to post -
        https://www.slipstick.com/developer/code-samples/macro-export-outlook-fields-excel/#comment-197327

  26. Isa says

    March 6, 2016 at 2:57 pm

    Hello Diane,
    Thank you so much for all those tools, codes, and explanations. I learned so much!
    I am trying to extract last names that include an apostrophe (i.e. O'Connor or Leclec'h). I searched the web and came up with this pattern :
    .Pattern = "(Name[:]\s([\w*-éïãüçè ]*)\s*)|([\w*\'\w?]\s*)$\n"
    It includes the characters "éïãüçè" and spaces which I need to be found. Then there is the alternation sign | as in "OR find alphanumeric strings that have an apostrophe in between".
    BUT in case of apostrophe, this gives me only the "O" in "O'Connor" or "Leclec" in "Leclec'h" and not the apostrophe or the rest of the name.
    Would you be so kind as to help me with this? Thank you!

    Reply
    • Diane Poremsky says

      March 6, 2016 at 11:20 pm

      Did you try .Pattern = "(Name[:]\s([\w*-éïãüçè\' ]*)\s*)$\n" ?

      Reply
  27. satya gujjari says

    January 22, 2016 at 2:10 am

    I want to extract website names from body of the email. How do i do it and where will that date be copied....like clipboard or to an excel sheet.

    Reply
    • Diane Poremsky says

      February 29, 2016 at 2:01 am

      You would use a regex pattern and extract it to a string. Then you can put the string on the clipboard, in notepad, or in Excel. Sorry, I don't have a pattern handy for websites, but "http?://(.*)" might work if there is nothing else on the line after the web address.

      Reply
  28. Hani Eshack says

    December 15, 2015 at 5:09 pm

    This is very helpful Diane, Thank you. I get daily emails from a real estate site and I am trying to parse specific information from the emails as they come in and insert them into an excel sheet. I am able to do most of the steps except of the RegExp patterns. But when I try to get the Contact ID using .pattern = "(Contact ID ([w-s]*)s*)n", I am getting a lot more text that I want. Also, when I use the following to get the email, I only get the first part and nothing after the @. .pattern = "(Agent Email s*.*(w*)(w*)$*)". The same with the Agent Name, I only get the first name using .pattern = "(Agent Names*.*(w*)(w*)$*)". I am sure I am missing something with the pattern here. Any help will be greatly appreciated. Thank you.

    Reply
    • Diane Poremsky says

      December 16, 2015 at 12:40 am

      Try this for the address - .Pattern = "(([\w-\.]*\@[\w-\.]*)\s*)"- M.SubMatches(1) will get the stuff inside the second set of () - it basically reads like "any letters, numbers, dash, or dot then @ then more letters and numbers then a space".

      Is the contact ID the only thing on the line? If not, you can't use \s* or space - it will count every space. If it is the only thing on the line, you need to look for the EOL character - try \n and if that doesn't work, use \r.
      (Contact ID ([\w]* [\w])*\n) - will get 2 word names.

      Reply
      • Hani Eshack says

        December 18, 2015 at 5:02 pm

        This worked perfectly. Thank you, Diane!!!

    • Hani Eshack says

      December 23, 2015 at 11:04 am

      Diane, everything worked here except one item that keeps returning more text that I need. When I looked at the HTML source, I get this: Samer Kuraishi Group Agent Email

      All I need is the Agent Name "Samer Kuraishi", but I get his name, a line break, then I get the following text "Agent Email".

      Here is the pattern that I am using: .pattern = "(Agent Name ([w-s]*))n". I have also tried to use r but nothing worked.

      Any ideas? I appreciate your help.

      Thanks,
      Hani

      Reply
      • Diane Poremsky says

        December 28, 2015 at 12:21 pm

        You need to use \
        .pattern = "(Agent Name ([\w-\s]*))\n"

        if that still get the next line, you'll need to try something like this:
        .pattern = "(Agent Name ([\w-\s]*)Agent Email)"

  29. simon says

    October 23, 2015 at 5:17 am

    hello,
    i need to extract from 1200 email "postmaster this 3 phrase in this format in one folder called "error mail" :

    xxxxxxxxxxx@domain.fr
    [212.3.242.103]
    Remote Server returned ''

    or

    xxxxxxxxxxx@domain.fr
    Remote Server returned '..................ERROR MESSAGE.............'

    and copy to Excel what is code for make this

    Reply
    • Diane Poremsky says

      October 23, 2015 at 9:43 am

      i think you might need two (or more) different patterns, but try a pattern like this - if \n doesn't work, try \r
      "\n(([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})(.*)Remote Server(.*) \n)

      and use M.SubMatches(0)
      if you need to use multiple patterns, try these patterns -
      email:
      ([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})
      IP:
      (\[[0-9.]*\])
      Text:
      (Remote Server(.*)\n)

      Reply
      • simon says

        October 24, 2015 at 9:58 am

        hello,
        sorry but i don't have any knowledge in VB
        i try every script in the page and doesn't work, any of script have a problem i work with outlook 2010

      • Diane Poremsky says

        October 25, 2015 at 9:18 pm

        The scripts work, but you need to get the pattern right and i can't do that for you as i don't have email in that format. It will be easier if you learn a little about VBA so you can understand how it works.

        Try this on the selected message - you'll need to show the Immediate window (View menu of VBA editor) and can see if it finds a match.
        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 4

        With Reg1
        Select Case i
        Case 1
        .Pattern = "\n(([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})(.*)Remote Server(.*) \n)"
        .Global = False
        .IgnoreCase = True
        Case 2
        .Pattern = "([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})"
        .Global = False
        .IgnoreCase = True
        Case 3
        .Pattern = "([\d]*\.[\d]*)\s*\n"
        .Global = False
        .IgnoreCase = True
        Case 4
        .Pattern = "(Remote Server(.*)\n)"
        .Global = False
        .IgnoreCase = True
        End Select

        End With

        If Reg1.Test(olMail.Body) Then

        Set M1 = Reg1.Execute(olMail.Body)
        For Each M In M1

        strSubject = M.SubMatches(0)
        Debug.Print i & " " & strSubject
        Next
        End If

        Next i

        Set Reg1 = Nothing

        End Sub

      • simon says

        October 26, 2015 at 8:00 am

        sorry but that don't work
        error 13 "type incompatible"
        this code is mark in yellow :
        Set olMail = Application.ActiveExplorer().Selection(1)

      • Diane Poremsky says

        October 26, 2015 at 8:47 am

        the selected message was an email message? You'll get that message if it's not an email message.

      • simon says

        October 26, 2015 at 12:20 pm

        this is a mail from exchange server for error address or unknown address

      • Diane Poremsky says

        October 27, 2015 at 11:19 pm

        An NDR. Change the dim olmail line to this: Dim olMail As Object

      • simon says

        October 28, 2015 at 6:32 am

        no result the script don't do anything

      • Diane Poremsky says

        October 28, 2015 at 8:34 am

        No errors? If it's running but not finding the patterns then the patterns aren't quite right. Show the Immediate window (View menu) - if it's finding patterns the results will be in the immediate window. If not, try changing the second pattern to .Pattern = "([A-Z0-9._%+-]*@[A-Z0-9.-]*\.[A-Z]{2,})"

        oh, and this macro only finds the stuff - you'll need to change it (after the debug.print line) to do something with it.

      • simon says

        October 30, 2015 at 7:59 am

        i try this script but is don't work this line "If Err 0 Then" don't work
        i don't know if the rest work
        Option Explicit
        Sub CopyToExcel()

        [snip]

        enviro = CStr(Environ("USERPROFILE"))
        'the path of the workbook
        strPath = enviro & "\Documents\test.xlsx"
        On Error Resume Next
        Set xlApp = GetObject(, "Excel.Application")
        If Err 0 Then
        Application.StatusBar = "Please wait while Excel source is opened ... "
        Set xlApp = CreateObject("Excel.Application")
        bXStarted = True
        End If
        On Error GoTo 0
        'Open the workbook to input the data
        Set xlWB = xlApp.Workbooks.Open(strPath)
        Set xlSheet = xlWB.Sheets("Test")
        [snip]

      • Diane Poremsky says

        October 30, 2015 at 9:35 am

        In what way doesn't it work? As long as the workbook path is correct and it can open Excel object, Err should = 0.

      • simon says

        October 30, 2015 at 10:31 am

        sorry but that don't work
        error 13 "type incompatible
        on the line :
        rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(xlUp).Row

      • Diane Poremsky says

        October 30, 2015 at 11:10 am

        what version of office are you using?

      • simon says

        October 30, 2015 at 8:11 am

        i try the script "CopyToExcel" but after change
        "olItem As Outlook.MailItem" to "olItem As Object" this line don't work :
        rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(xlUp).Row
        the script don't understand "xlUp" i try to declare like this "Dim xlUp As Object" but don't work too

      • Diane Poremsky says

        October 30, 2015 at 9:32 am

        That problem came up in the comments in the copy to excel macro - Setting a reference to Excel in Tools, References fixed one error and then i got another error - i said "if i don't use option explicit, i get the 1004 error. Add this line to the (top of the) code -
        Private Const xlUp As Long = -4162

  30. Josh says

    September 22, 2015 at 3:58 pm

    How would I run this on a shared mailbox and subfolder

    shared mailbox is called "\\Test, Mail\Inbox"
    subfolder is called "Team 54"

    Option Explicit
    Sub CopyToExcel()
    Dim olItem As Outlook.MailItem
    Dim xlApp As Object
    Dim xlWB As Object
    Dim xlSheet As Object
    Dim vText, vText2, vText3, vText4, vText5 As Variant
    Dim sText As String
    Dim rCount As Long
    Dim bXStarted As Boolean
    Dim enviro As String
    Dim strPath As String
    Dim Reg1 As Object
    Dim M1 As Object
    Dim M As Object
    Dim i As Long

    enviro = CStr(Environ("USERPROFILE"))
    'the path of the workbook
    strPath = enviro & "\Documents\test.xlsx"
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application")
    If Err 0 Then
    Application.StatusBar = "Please wait while Excel source is opened ... "
    Set xlApp = CreateObject("Excel.Application")
    bXStarted = True
    End If
    On Error GoTo 0
    'Open the workbook to input the data
    Set xlWB = xlApp.Workbooks.Open(strPath)
    Set xlSheet = xlWB.Sheets("Test")
    Set olItem = Application.ActiveExplorer().Selection(1)

    'Find the next empty line of the worksheet
    rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(xlUp).Row
    rCount = rCount + 1

    sText = olItem.Body

    Set Reg1 = CreateObject("VBScript.RegExp")
    ' \s* = invisible spaces
    ' \d* = match digits
    ' \w* = match alphanumeric
    For i = 1 To 3

    With Reg1
    Select Case i
    Case 1
    .Pattern = "Team\s*[:]+(.*)"
    Case 2
    .Pattern = "Date\s*[:]+(.*)"
    Case 3
    .Pattern = "Issue\s*[:]+(.*)"
    End Select
    End With

    If Reg1.Test(sText) Then
    Set M1 = Reg1.Execute(sText)
    For Each M In M1
    Select Case i
    Case 1
    vText = Trim(M.SubMatches(0))
    Case 2
    vText2 = Trim(M.SubMatches(0))
    Case 3
    vText3 = Trim(M.SubMatches(0))
    End Select
    Next
    End If

    Next i
    xlSheet.Range("b" & rCount) = vText
    xlSheet.Range("c" & rCount) = vText2
    xlSheet.Range("d" & rCount) = vText3

    xlWB.Close 1
    If bXStarted Then
    xlApp.Quit
    End If
    Set M = Nothing
    Set M1 = Nothing
    Set Reg1 = Nothing
    Set xlApp = Nothing
    Set xlWB = Nothing
    Set xlSheet = Nothing
    End Sub

    Reply
    • Josh says

      September 22, 2015 at 4:11 pm

      Oh and I want to run this manually and not automatically so that it pulls all the emails in the box that match. It seems that it is failing to pull all the emails and just pulls the most recent one!

      Reply
      • Diane Poremsky says

        September 22, 2015 at 9:22 pm

        The copy to Excel macro runs manually; only macros with sub macroname(item as outlook.mailitem) style names are automatic.

        This line: Set olItem = Application.ActiveExplorer().Selection(1) tells outlook to use the selected message. The macro at https://www.slipstick.com/developer/code-samples/working-items-folder-selected-items/ shows how to work with selected items or all items in a folder.

    • Diane Poremsky says

      September 22, 2015 at 9:27 pm

      The macro, as written, works on the selected message in any folder. This tells it to use the selected message:
      Set olItem = Application.ActiveExplorer().Selection(1)

      Reply
  31. Steve O. says

    September 21, 2015 at 4:51 am

    Thanks Diane.

    I had tried what you suggested before posting (substituting references to olMail and Item) but it didn't work, which I couldn't understand.
    However, I have just revisited this and now it is working with references to olMail replaced with Item.
    I have also removed the Alert in the Rule and replaced with a MsgBox in the script.
    Lastly, I have added code to the script to move the email to a subfolder.
    So all the Rule does (during Testing) is check the Subject, search for a string the body text, and run the script. When I am happy I will add a check for the real Sender.

    I need to do a little more tweaking, but I have a question on deploying the script to recipients of the emails (outside our email system).
    Since I have had to enable VBScript in Developer in order to include Regular Expressions, does this mean that the end user will need to do the same in order to run the script containing RegExp, as well as look at Macro security settings?

    Time allowing, I may try to code this as an add-in, or somehow execute a script on Send rather than Receive but we are a way off at the moment.

    Thanks for all the help.
    Regards
    Steve O.

    Reply
    • Diane Poremsky says

      September 22, 2015 at 9:34 pm

      >> Since I have had to enable VBScript in Developer in order to include Regular Expressions, does this mean that the end user will need to do the same in order to run the script containing RegExp, as well as look at Macro security settings?

      Yes, they will. If you use late binding the users won't need to set a reference that way.
      Dim the regex stuff as objects instead of as regex (Dim Reg1 As RegExp, Dim M1 As MatchCollection, Dim M As Match)

      Dim Reg1 As Object
      Dim M1 As Object
      Dim M As Object

      Then create the objects
      Set Reg1 = CreateObject("VBScript.RegExp")

      Reply
  32. Steve O says

    September 19, 2015 at 4:14 pm

    Hello Diane.

    I eventually added these two lines at the bottom

    Item.Subject = testSubject
    Item.Save

    after the lines copied from the sample and it now fires and changes the subject of yje email on arrival.

    My code is a mixture for various samples plus changes to make it work as a script rather than a Macro - so I now seem to have some redundancy in the code - Item vs olMail = but if I try to remove or change anything (between olMail and Item) I get errors.

    Here is the full script as it stands:

    Public Sub GetValueUsingRegEx(Item As Outlook.MailItem)
    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 = "(Workorder Number[:]([\w-\s]*)\s*)\n"
    .Global = False

    Case 2
    .Pattern = "(Workorder Account[:]\s*(\S+)\s*(\S+)\s*(\S+)\s*-\s*(\S+)\s*(\S+)\s*)\n"
    ' .Pattern = "(Workorder Account[:]([\w-\s]*)\s*)\n"
    .Global = False

    Case 3
    .Pattern = "(Receipt Data[:]([\w-\s]*)\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
    If i = 1 Then StrSubject = M.SubMatches(1)
    If i = 2 Then StrSubject = M.SubMatches(4)
    If i = 3 Then StrSubject = M.SubMatches(1)

    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 testSubject
    olMail.Subject = testSubject
    olMail.Save
    Item.Subject = testSubject
    Item.Save

    Set Reg1 = Nothing

    End Sub

    Reply
    • Diane Poremsky says

      September 19, 2015 at 11:28 pm

      This>> Public Sub GetValueUsingRegEx(Item As Outlook.MailItem) sets the variable as Item and applies to messages as they arrive. "Item" can be changed to oMail if you want to avoid editing the rest of the macro.

      This>> Dim olMail As Outlook.MailItem sets the variable as olMail and would be used if running a macro manually. You don't need this and Item As Outlook.MailItem in the macro.
      This>> Set olMail = Application.ActiveExplorer().Selection(1) sets the object assigned to the variable as the selected item. You'd only use this if you run a macro manually.

      This works>> Item.Subject = testSubject because you set testsubject earlier.

      Reply
  33. Steve O. says

    September 18, 2015 at 6:44 am

    Hello Diane.

    I have modified the rule that uses Regex after scanning web pages and removed a couple of lines.

    Originally the Rule moved the email to a Folder - I have removed this.
    Originally the Rule automatically inserted On this Computer Only - I have removed this.

    Now the rule does this :
    Looks for a Specific Subject Line
    Looks for a Specific string in the email body text
    Displays a New Item Alert Window (I added this to facilitate monitoring it makes no difference).
    Runs the Script.

    Same result with email subjects not changing until after the email is forwarded -Except.....

    Another Oddity today - the Subject Line did not change when the email arrived - but it did 10 minutes later when another email arrived with the same Subject Line (but the string in the body text didn't match - so the script wouldn't have run?).
    It is almost as if something is forcing some kind of asynchronous processing - not had this before.

    Anyhow, now I know from my basic script that Email Subject lines can be changed without forwarding, I have binned that code (which I don't require but was using for testing) and will revert to building up the basic script a piece at a time until it fails.

    Incidentally, if I get to the bottom of this, I may still put the emails into a folder via the Rule - subject to reviewing something I found about Subject line changes not 'sticking' when moving email to folders (if I can find it again).

    Regards
    Steve O.

    Reply
    • Diane Poremsky says

      September 19, 2015 at 10:59 pm

      You shouldn't use this >> Displays a New Item Alert Window. Run a scripts should only have one action - the script - and anything you want to do should be in the script.

      >> Another Oddity today - the Subject Line did not change when the email arrived - but it did 10 minutes later when another email arrived with the same Subject Line
      Are you using conversation view? The group headers will show the original subject, the changed subject will be in the preview pane or open message. This can't be changed.

      >> I may still put the emails into a folder via the Rule
      Don't use the rule, move the messages in the script after you change the subject.
      omail.move folder-to-move-to

      Reply
  34. Steve O says

    September 17, 2015 at 5:37 pm

    Hello Diane.

    This code works - I actually see the email hit the Inbox and the Subject changes as I am watching.

    Sub Test1(Item As Outlook.MailItem)
    Set oItem = ActiveExplorer.Selection.Item(1)

    Item.Subject = "[ChangedNow]"
    Item.Save
    End Sub

    However, the Regex code only changes the Subject when the email is forwarded as before.
    I am going to try adding the code back in a little at a time to see when it stops working

    Reply
    • Diane Poremsky says

      September 17, 2015 at 6:50 pm

      How does the rule read? Are all the conditions in the rule and the only action is run the script?

      Reply
  35. Steve O says

    September 15, 2015 at 4:07 am

    Hello Diane.
    I didn't want updates to cross over, so didn't update yesterday in case you were working on a reply.
    After reading about issues with code needing to be self-signed, macro settings, and exiting and re-starting Outlook, the script is working again - as it was before - after forwarding an email.
    I will try adding the forward (but delete don't send) to the script to see what that does.
    I will also try removing the bits from the rule that make the rule run client-side (likely the move to folder) - to see if that makes a difference.

    Regards
    Steve O.

    Reply
    • Diane Poremsky says

      September 15, 2015 at 7:27 am

      It sounds like the macro security was changed (or never changed to begin with - macros will often work the first time without changing security settings. I don't recommend signing the macro until you are finished because you'll need to remove the signature and add it back every time you edit the macro.

      Reply
  36. Steve O says

    September 14, 2015 at 10:00 am

    Hello Diane. Thanks for the reply.

    I sort of understand the spaces bit - this is my first foray into VBA and Outlook.

    Here is the format of my string of text:

    Text1 Text2 Text3 - Text4 (Text5\Text6)

    i.e. 3 words, a hyphen and then 2 words in brackets separated by a backslash

    Ideally I would pull out the bit in brackets but using the following and your code I do get the contents of Text1, or if I remove .SubMatches(1) from your code I can get the whole line of Text :

    .Pattern = "(Workorder Account[:]\s*(\S+)\s*(\S+) (\S+) - (\S+) (\S+)\s*)\n"

    I think given time I can code around to what I want - if not I can get away without this text.

    However, for some reason the code has stopped working even when I forward the message on - now the Subject line doesn't ever change.

    I disabled conversation view some while ago as it caused other issues.
    Whatever way I looked at the email, even if I opened it, the subject did not change until I forwarded it on.

    I found some other code of yours that I was going to try - it seems to forward the email but delete it without sending it and wondered if I need to do this bit for the Subject to change.
    I don't understand that code otherwise?

    Majorly puzzled now as to why this doesn't work even as it did last night.

    Regards
    Steve O.

    Reply
    • Diane Poremsky says

      September 15, 2015 at 7:24 am

      On this:
      >>
      remove .SubMatches(1) from your code I can get the whole line of Text :
      .Pattern = "(Workorder Account[:]\s*(\S+)\s*(\S+) (\S+) - (\S+) (\S+)\s*)\n""
      >>

      Each set of () = a number, starting with 0. The 0 is around the whole string. When you have 6 groups of numbers you need to use a submatches(n) for number. You can either do it using a loop (n = 1 to 6) or as separate lines with .submatches(1), .submatches(2) etc. In your case, since it's all one string, I would probably use separate submatches here.

      Reply
  37. Steve O. says

    September 13, 2015 at 2:11 pm

    Hello Diane.

    I need to read 3 variables from an incoming email, overwrite the email Subject with a concatenation of the 3 variables, and then file it to a folder based on text in the email.
    There is an example on this page that seems to do exactly that, but I am having issues with it.
    First and foremost, the Subject line is not updated - until I forward the email on - and then everything is correct once I have forwarded it (manually).
    Secondly, I would like to pick up one string (in brackets) from a 3rd line but there are spaces in the line (it is a line of text) and I cannot get it to pick up this line even in it's entirety using the regular expressions.

    Hope you can help.

    Regards
    Steve O.

    Reply
    • Diane Poremsky says

      September 13, 2015 at 11:14 pm

      For the spaces one, try "[(.*)]" as the pattern. You could also use (a-zA-Z )*

      Are you saving the original message after changing the subject? Also, it won't change the conversation subject, so you'll see the original conversation if you use conversation groups.

      Reply
  38. Darren says

    August 7, 2015 at 8:18 am

    Hi Dianne,

    This is really helpful, thank you. I receive two type of email containing data from potential customers.

    I have used other VBA codes from here to automatically reply to the reply to address, which have been amazing. I need to get this data from an email into salesforce. I plan to firstly extract the information from the email into excel then use a salesforce data loader. Would you have a better suggestion?

    Anyway the two emails are as follows, which need to have data extracted into excel.

    Email 1
    You have received a new lead from realestate.com.au for

    Property id: 123467
    Property address: STREET, SUBURB, STATE POSTCODE
    Property URL: http://www.realestate.com.au/12346

    User Details:
    Name: FIRSTNAME LASTNAME
    Email: EMAIL
    Phone: PHONE
    About me: STRING
    I would like to: STRING
    Comments: PARAGRAPH OF TEXT

    Email 2 (I think this may be a HTML email)

    The enquiry has been sent from a user on http://www.domain.com.au

    Property: STREET SUBURB STATE POSTCODE - FIRSTNAME LASTNAME SUBURB

    From: FIRSTNAME LASTNAME
    Email: EMAIL
    Phone: PHONE
    Message: STRING

    This data would be organised into excel with the following columns

    FIRSTNAME
    LASTNAME
    EMAIL
    PHONE
    PROPERTY

    for email 1, it would need to remove the , and just capture STREET SUBURB
    for email 2, it would need to only capture STREET SUBURB

    Reply
    • Diane Poremsky says

      August 8, 2015 at 9:25 am

      It's certainly doable using the regex Except that keeping only the street and suburb might be difficult if people use commas in the first (so we can't break at the second comma) and in thee second one, you need something to identify the break point - street names and suburbs might have spaces so we can't just count spaces. if state is abbreviated and always the same # of letters (or you are in one state) we could use that to break in both emails, as long as street and suburb is one record in Excel. Putting it into Excel won't be hard - I have samples here that do it.

      Reply
  39. viraj21viraj says

    July 12, 2015 at 5:26 pm

    hi
    i need help in using vba
    so vba can read my email subject and body and reply to the email and add an atachment from my desktop by doing a key word search
    inform me anout what actions have been taken
    which emails have been left out
    regards
    if any body does feel like helping me with the code please email me at reolite2012@gmail.com
    thanks in advance

    Reply
    • Diane Poremsky says

      July 12, 2015 at 10:25 pm

      I have a bunch of samples that could be put together to do that - but nothing that does exactly that, as it's pretty complicated.
      These are two of several pages here that might be helpful to you.
      https://www.slipstick.com/outlook/rules/run-script-rule-reply-message/
      https://www.slipstick.com/developer/fun-arrays-one-macro-many-replies/

      Reply
  40. Uday says

    July 6, 2015 at 9:33 am

    Hi,

    I am using the following code in debug mode and see how it works so that later I can modify it as per my requirement but it throws "Object doesn't support this property...." at Set olMail = Application.ActiveExplorer().Selection(1) line, I guess I am doing something wrong, please help me. Will it not run if I use in debug mode?

    Sub GetValueUsingRegEx()
    ' Set reference to VB Script library
    ' 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* = invisible spaces
    ' \d* = match digits
    ' \w* = match alphanumeric

    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

    Reply
    • Diane Poremsky says

      July 12, 2015 at 10:15 pm

      Are you running it on messages? This references the selected item: Set olMail = Application.ActiveExplorer().Selection(1) and this Dim olMail As Outlook.mailItem says its a mailitem.

      Reply
    • Uday says

      July 21, 2015 at 12:18 am

      I keep the message selected and run the macro in debug mode to see whats happening.
      Can you please provide me steps to go about it if im not doing it right?

      Reply
  41. Eli Lancry says

    June 29, 2015 at 2:50 am

    Hi Diane,

    Thanks for great article!
    Is it possible to capture the hyperlink of a string in a message?
    Usually I save attachments in incoming messages to my computer with a vba code that I found elsewhere that removes the attachment from the message and saves it to a prefered folder leaving the following text:
    "The attachment file(s) were saved to:
    image002.png
    image001.png
    ATT00001.txt"
    Each file name has a hyperlink. I am interested with capturing the hyperlink of each file name.
    Is it possible?

    Thanks in advance

    Eli

    Reply
    • Diane Poremsky says

      June 29, 2015 at 8:48 am

      Should be able to - i added Debug.Print olMail.Body right after the set olmail line and the results in the immediate window (turn it on in the View menu) included the underlying links. Using If Reg1.test(olMail.HTMLBody) would get you the raw HTML but as long as .Body works, I'd use it instead.

      Reply
  42. jonathandire says

    June 24, 2015 at 2:35 am

    Thanks Diane, I'll give it a shot!

    Reply
  43. jonathandire says

    June 24, 2015 at 12:18 am

    Howdy Diane,

    As always, love your work. Your Slipstick knowledge has taught me so much, making me excel beyond that of most Outlook Experts in the company I work for.

    People are now coming to be in droves to use my macros I adopted and modified off you.

    I have one last request regarding Regular Expressions.

    For the last 6 months I've been trying to figure it out by myself, how to extract expressions from the body of an email and change the subject line. Unfortunately, I get stuck with the result always just adding "; 2015." at the end of the subject line (rather than replace the subject.

    The email I've been working with:

    Shock Case Recipient: Awesometeam
    Correspondence Date (DD/MM/YYYY): 15/06/2015
    Customer concern(s): Pain
    Correspondence type: Phone
    Customer confirm Date (DD/MM/YYYY): 15/06/2015
    Due Date: 06/07/2015

    Customer's details:
    Name: PETER PETRELLI

    Address:
    123 Road Rd
    SUBURB, QLD, 6000

    Please review.

    Resources:
    Case Id 123456789

    What I am looking for is regex to extract the following fields and replace the subject line in capitals:

    Due date - Case recipient - Customer Concern - Name - Suburb (Case Id)

    So if the code were to work, the subject line would look like:

    06/07/2015 - SHOCK - PAIN - PETER PETRELLI - SUBURB (Case 123456789)

    As you can see, the 'Shock' Case recipient is before the actual field.

    I can paste the code I've made, however it is currently full of errors.

    Can you pretty please assist?

    Reply
    • Diane Poremsky says

      June 24, 2015 at 1:48 am

      Replacing the subject would use .Subject = testSubjectformat. The sample under the Get two (or more) values from a message heading shows how put the string together - you just need the right patterns to get the values you need. The cases will be in the order you want the values to appear in the subject. (Reverse order would work too.) If you want everything in caps, use UCase(testSubject). If you don't want Case capitalized, it's a little more difficult as you need to assign each pattern to a string then put them together.

      Reply
      • Diane Poremsky says

        June 24, 2015 at 9:32 am

        Use something like this to add the results to different strings then you can merge the strings .subject = UCase(strOne) & " - " & strTwo...

        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)
        If i = 1 Then strOne = strSubject
        If i = 2 Then strTwo = strSubject
        If i = 3 Then strThree = strSubject
        Debug.Print i & " " & strSubject
        Next
        End If

        you could make the subject less confusing by setting the case & adding the dashes when you assign the result to the variable
        If i = 1 Then strOne = ucase(strSubject) & " - "

        then the subject would be
        .subject = strOne & strTwo

  44. Sandy says

    May 21, 2015 at 5:42 am

    Hi Ms Diane,

    Can you suggest a patter with with the info below:

    Shipping Line’s Cut-off Date/Time :
    20/05 (17:00H)

    For ESI submission?
    N

    For SI submission to SS/Line Website?
    Y

    For AMS? If yes, Last Port of call:
    N

    That is what my outlookitem.body have when I display it using the messagebox.
    I need to get the "Shipping Line’s Cut-off Date/Time" which is "20/05 (17:00H)"
    can you help me sort it out? here is the pattern I tried so far:
    .pattern = "Shipping Line’s Cut-off Date/Time\s*[:]+\s*(\w*)"

    Reply
    • Sandy says

      May 21, 2015 at 10:04 am

      I tried this but no luck

      Case 1
      .Pattern = "(Shipping Line's Cut-off Date/Time\s[:]\s(\w*))\n"
      .Global = False
      Case 2
      .Pattern = "(SHIPPING LINE'S CUT-OFF DATE/TIME\s[:]\s(\w*))\n"
      .Global = False
      Case 3
      .Pattern = "(DRAFT SHIPPING LINE CUT-OFF\s[-]\s(\w*))\n"
      .Global = False
      Case 4
      .Pattern = "(Shipping Line's Cut-off Date/Time[:]\s(\w*))\n"
      .Global = False
      End Select

      Reply
    • Diane Poremsky says

      June 24, 2015 at 1:31 am

      Is the text you want on a second line or the same line? Something like this should work. \s matches white space - including line breaks. If not, try \r or \n.
      .pattern = "Shipping Line’s Cut-off Date/Time"\s[:]\s(.*)"

      Reply
  45. Bill Castoro says

    May 20, 2015 at 12:14 am

    Diane, I am wondering if you can help. I receive order confirmations and the email address of my customer is in the body of the e-mail, I wanted to setup a rule that outlook will than email them back with a link to a specific website to go to. I am sure it can be done, I am just not that good with this stuff. The email address is always in the same place in the email. Instead of changing my whole ordering system to have autoresponders, I rather just have outlook send the messages.

    Reply
    • Diane Poremsky says

      June 24, 2015 at 1:23 am

      As long as its either the only email address or always either the first or last, you can use regex to find it. .Global = True tells the code to keep looking after the first instance is found; false tells it to stop.
      This page in my forum has a similar example. This edit of that code should do what you need it to do.

      Sub SendLink(Item As Outlook.MailItem)
      Dim Reg1 As RegExp
      Dim M1 As MatchCollection
      Dim M As Match
      Set Reg1 = New RegExp

      With Reg1
      .Pattern = "([a-z0-9.]*)@([a-z0-9.]*)"
      .Global = False
      End With

      If Reg1.test(Item.Body) Then
      Set M1 = Reg1.Execute(Item.Body)
      For Each M In M1
      strAlias = M
      Next
      End If

      Dim objMsg As MailItem

      Set objMsg = Application.CreateItem(olMailItem)

      With objMsg
      .Recipients.Add strAlias
      .Subject = "New Subject Title"
      .Display '.Send

      End With

      Set objMsg = Nothing

      End Sub

      Reply
  46. Suhail Shaikh says

    May 18, 2015 at 11:41 am

    Many thanks for your prompt response.
    But when we search for the words in the searchbox, it also checks the attachment. Is there a way to do the same via a macros?

    Reply
    • Diane Poremsky says

      May 18, 2015 at 1:49 pm

      No, not to my knowledge. Instant search using the Windows search index - the methods used in the macro search the folder or items directly.

      Reply
  47. Suhail Shaikh says

    May 15, 2015 at 11:52 am

    Hi,
    I am trying to search for specific words in the attachement in an email & then move the email with those specific words in a folder. I tried Rules however it does not search the attachment but only the body of the email.

    Is RegEx an option to do this?

    Regards,

    Reply
    • Diane Poremsky says

      May 15, 2015 at 12:59 pm

      No, not really - you need to open and search the attachment - once it's open, you could use other methods to search for the words.

      Reply
  48. Dan says

    April 11, 2015 at 2:04 pm

    Dear Diana,

    I am trying to locate a function to extract only 1st paragraph of email body. It seems I cannot locate the proper function. Here is the macro I was able to locate at Internet, however I need to modify the code sot that "strColG = olItem.Body" is something like that "strColG = olItem.Body.1st paragraph" text only

    Option Explicit
    Sub ExportToExcel()
    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 currentExplorer As Explorer
    Dim Selection As Selection
    Dim olItem As Outlook.MailItem
    Dim obj As Object
    Dim strColB, strColC, strColD, strColE, strColF, strColG As String

    ' Get Excel set up
    enviro = CStr(Environ("USERPROFILE"))
    'the path of the workbook
    strPath = enviro & "\Documents\test.xlsx"
    On Error Resume Next
    Set xlApp = GetObject(, "Excel.Application")
    If Err 0 Then
    Application.StatusBar = "Please wait while Excel source is opened ... "
    Set xlApp = CreateObject("Excel.Application")
    bXStarted = True
    End If
    On Error GoTo 0
    'Open the workbook to input the data
    Set xlWB = xlApp.Workbooks.Open(strPath)
    Set xlSheet = xlWB.Sheets("Test1")
    ' Process the message record

    On Error Resume Next
    'Find the next empty line of the worksheet
    rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(-4162).Row

    ' get the values from outlook
    Set currentExplorer = Application.ActiveExplorer
    Set Selection = currentExplorer.Selection
    For Each obj In Selection

    Set olItem = obj

    'collect the fields
    strColB = olItem.senderName
    strColC = olItem.Application.ActiveExplorer.Caption
    strColD = olItem.Subject
    strColE = olItem.To
    strColF = olItem.ReceivedTime
    strColG = olItem.Body

    'write them in the excel sheet
    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
    xlSheet.Range("G" & rCount) = strColG

    'Next row
    rCount = rCount + 1

    Next

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

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

    Reply
    • Diane Poremsky says

      April 15, 2015 at 9:28 pm

      It's hard to get the first paragraph, especially if you want the first real paragraph and not the first line.. well, not that hard, but you need to use word vba code to get it, which means you need to open the message. It'll flash on the screen for a split second as the macro opens it, reads the paragraph and closes it. The macro here: https://www.slipstick.com/developer/word-macro-apply-formatting-outlook-email/ has the basics for using word objects.

      if you just wanted the first nn number of characters, you could do that using the Left function. It's definitely easier. Find function might work too - then you could find the first line break.

      Reply
      • Diane Poremsky says

        April 15, 2015 at 9:41 pm

        Ok.. the Find function is not supported in Outlook. I'm not sure it would help much anyway - instr and len would be better to find the position of the first line break and get the text preceding it. This would avoid the need to open the message and eliminate the screen flash.

  49. Nick Syrax says

    February 19, 2015 at 2:10 pm

    I have a case where I need to search for particular text, then copy the entire line of text where the search found a result. Can this accomplish that?

    Reply
    • Diane Poremsky says

      March 18, 2015 at 12:27 am

      As long as the search term is either always the same or fits a pattern, it will work.

      Reply
  50. Neal says

    December 12, 2014 at 5:12 pm

    Hi Diane, very helpful article! My question is how can I turn this into a script to run as a part of a rule for forwarding messages and use the multiple cases of text as information to populate a form email?

    Reply
    • Diane Poremsky says

      December 12, 2014 at 6:04 pm

      to use the first macro in a rule, change this:
      Sub GetValueUsingRegEx()
      ' Set reference to VB Script library
      ' Microsoft VBScript Regular Expressions 5.5
      Dim olMail As Outlook.MailItem
      to
      Sub GetValueUsingRegEx(olMail As Outlook.MailItem)
      ' Set reference to VB Script library
      ' Microsoft VBScript Regular Expressions 5.5

      and delete Set olMail = Application.ActiveExplorer().Selection(1)

      Or you could use something like this with the original macro
      Public Sub ForwardSomething(Item As Outlook.MailItem)
      GetValueUsingRegEx olmail
      End Sub
      the regex macro would need a little tweaking, beginning with removing the line that sets olmail. The advantage of this method is you use several short macros with rules rules and can pass different patterns to it. I thought I had an example somewhere either in comments or at outlookforums - i'll see if i can find it.

      Reply
      • Neal says

        December 15, 2014 at 11:40 am

        Very helpful for using in a rule. When using the two or more values macro above, how can I insert the results in a formatted email? For example, "The Order ID XXXXX was placed on XXXXX for a total of XXXXX" where the values are pulled from an email using the macro?

  51. Kiara says

    December 7, 2014 at 5:42 pm

    Hi Diane,

    Thank you so much for this wonderful tutorial. I'm trying to modify your code to match URLs, but am having a hard time with the Regex for this. Are you aware of any good regex url matchers? Or do you think another method would be better?

    Thank you!

    Reply
    • Diane Poremsky says

      December 7, 2014 at 8:59 pm

      RegEx should work fine. Assuming you are matching any https:// url and there is no other text on the line, the pattern should be something like "(https?(.*))" (s? in the pattern matches http or https.. If the url is within text, this pattern should work - .pattern = "(https?\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*))?>"

      Oh, and use 0 in the m.submatches: Debug.Print M.SubMatches(0)

      Reply
  52. Mitch says

    November 28, 2014 at 5:07 pm

    To provide more information of what I am looking for. I believe an IRM might prevent a forward. I actually want to track my emails forwarded to another employee of who the email is not intended.

    Reply
    • Diane Poremsky says

      December 12, 2014 at 5:48 pm

      IRM will prevent forwarding.

      Reply
  53. Mitch says

    November 28, 2014 at 3:56 pm

    What about a native_foward?

    Reply
    • Diane Poremsky says

      December 12, 2014 at 5:50 pm

      Not sure what you mean by native_forward - outlook won't block forwarding on its own.

      Reply
  54. Mitch says

    November 28, 2014 at 10:36 am

    Hi Diane,

    Is there a code I can use to track if someone forwards my email to another person?

    Tracking_beacon????

    Thanks

    Reply
    • Diane Poremsky says

      November 28, 2014 at 3:27 pm

      Well unless you use IRM, the only option would be to use a tracking beacon. But, its not going to tell you a lot - it wont show who it was forwarded to, or guarantee it was forwarded. It will only show the IP addresses that opened it, and even then, only if they aren't blocking downloads.

      Reply
  55. Ainsley says

    November 18, 2014 at 7:51 pm

    Hi Diane,

    How would I be able to use this RegEx to read a few different patterns and if the subject satisfy one of the pattern, then a code will be execute (e,g, auto reply code). For example, if the email subject is "ABCD" OR "1234" OR "AB12" then the code to autoreply will run.

    Would looping with IF....ELSE...ELSE...ELSE...END IF helps?

    Reply
    • Diane Poremsky says

      November 18, 2014 at 10:56 pm

      You can use | (pipe character) as an OR. ([A-D]{4}|[0-9]{4}|[A-Z]{2}[0-9]{2})

      Reply
  56. Pranab says

    November 17, 2014 at 2:32 am

    I want a code for the following information which i receive in my outlook mail box to be extracted to a excel file in
    Zebra/Orion Printer: 10
    Account no.: 517626023
    Company: Jeanne d'Arc Living ApS
    First Name: Rasmus
    Last Name: Olsen
    Address 1: Houmarksvej 92
    City: Randers NV
    Postal Code: 8920
    Country: Denmark
    Phone no.: 36 93 20 14
    E-Mail: rasmus@jeannedarcliving.dk

    Reply
    • Diane Poremsky says

      November 19, 2014 at 12:24 am

      Use a case statement to get the values and use the method here - https://www.slipstick.com/developer/vba-copy-outlook-email-excel-workbook/ - to write it to excel.

      Reply
  57. Nathan says

    October 24, 2014 at 5:26 am

    Hi,

    I have successfully written a script that can insert a new line to an existing email, change the subject and then forward to a new recipient.
    My current script is as such
    Set FwdMsg = item.Forward
    With FwdMsg
    NewLine = "Dear users,Please note that data is also affected by the incident below and will be corrected after systems recovers. Please email the team for more information. Thank you."

    FwdMsg.HTMLBody = NewLine & FwdMsg.HTMLBody
    FwdMsg.Recipients.Add "john@gmail.com"
    FwdMsg.Subject = "Incident affecting you" & Format$(Now, " dd-mm-yyyy hh.mmam/pm")

    FwdMsg.sEnd

    However I now need to remove certain sentences in the email and replace them with " plase call me with this number.

    This is my email body

    Impact:
    ABCD EFG
    RSTUV

    Corrective Action

    I need to remove the ABCD EFG and RSTUV and replace with a sentence "contact me" such that the new email body is
    Impact:

    please call me with this number

    Corrective Action

    How do I do that with regex?

    I tried this but it doesnt seem to work

    Dim pattern As String = "(\p{Sc}\s?)?(\d+\.?((?<=\.)\d+)?)(?(1)|\s?\p{Sc})?"
    Dim input As String = FwdMSg.HTMLBody
    Dim replacement As String = " please call me with this number
    Dim rgx As New Regex(pattern)
    Dim result As String = rgx.Replace(input, replacement)

    Reply
    • Diane Poremsky says

      November 18, 2014 at 11:35 pm

      To replace using regex, the replace line goes in the block with the pattern. It's not very good with HTML messages though.

      With Reg1
      .Pattern = "([a-z]{6})"
      .Global = True
      text1 = .Replace(oReply.Body, "hello")
      End With
      If Reg1.Test(oReply.Body) Then

      Set M1 = Reg1.Execute(oReply.Body)
      For Each M In M1
      Debug.Print M.SubMatches(0)
      Debug.Print text1
      oReply.Body = text1
      Next
      End If

      You can also use Word VBA to select and replace the lines. The code sample at https://www.slipstick.com/developer/word-macro-apply-formatting-outlook-email/ shows how to do something with the selection.

      Reply
  58. Ryan says

    October 22, 2014 at 5:07 pm

    Diane,
    Your post is amazing and if I can get this to work for a project I'm involved with, it can save me many hours of manual entry.

    I have never used VBA before, but I'm not afraid to try. I receive +200 emails that are formatted exactly the same as below example. I want to parse the info that follows Vehicle, Event, Time and Coordinates. I would assume the same logic would be used as in your code using the colon, but what would this do for the date/time field which contains a colon.

    I really don't know where to begin, but I would appreciate any help! Thank you.

    Actual Email:

    GEOSERVICES EVENT NOTIFICATION

    EQUIPMENT
    Vehicle: 11848

    EVENT
    Event: Departure
    Time: 10/22/2014 16:00 EDT
    Landmark Type: Port
    Landmark: Georgia Ports Authority
    Address: 2 Main St
    Garden City, GA 31408

    EQUIPMENT POSITION @ EVENT
    Coordinates: 32.126296,-81.158426
    Nearest City: 5.70 miles NW of Savannah, GA Nearest Town: 1.32 miles N of Garden City, GA

    Reply
    • Diane Poremsky says

      October 22, 2014 at 9:03 pm

      Use the second macro and change the case statements:

      At the top:
      Dim strResult(4) As String ' use # of cases
      Dim strVehicle, strEvent, strTime, strCoord As String

      Replace the case statements:

      For i = 1 To 4 ' # of cases
      With Reg1
      Select Case i
      Case 1
      .Pattern = "(Vehicle[:]\s*([\d]+))\n"
      .Global = False

      Case 2
      .Pattern = "(Event[:]\s*([\w-\s]*))\n"
      .Global = False

      Case 3
      .Pattern = "(Time[:](.*))\n"
      .Global = False

      Case 4
      .Pattern = "(Coordinates[:](.*))\n"
      .Global = False
      End Select

      End With

      In the Matches chunk:
      strResult(i) = M.SubMatches(1)

      ' put the values in strings, which can be pushed into excel or whatever
      strVehicle = strResult(1) 'match # to case
      strEvent = strResult(2)
      strTime = strResult(3)
      strCoord = strResult(4)

      A code sample that sends the data to Excel is here - https://www.slipstick.com/developer/vba-copy-outlook-email-excel-workbook/

      Reply
  59. Andrew says

    October 20, 2014 at 8:30 pm

    Hello Diane,

    I'm trying to use this code to pull from a selection of Excel cells, and move the acquired data into cells on a new sheet.

    For example, all of the data I want to parse is located in column C on Sheet 1. I want to search for two things, "Name:" and "Position:" and put the values that come after the colon into Cells D2 and D3 respectively on Sheet2.

    How would you advise I do this?

    Thanks!

    Reply
    • Diane Poremsky says

      October 20, 2014 at 9:48 pm

      Excel is not my area of expertise (and I don't work with Excel VBA too much these days so I'm a bit rusty), but you'll get the values then pass them to a cell, something like this:
      You'll need to set the range to be on sheet2.
      xlSheet.Range("d" & rCount) = StrName
      xlSheet.Range("d" & rCount+1) = StrPos

      I think you could use Sheets("Sheet2").Cells("d", rCount) too.

      This macro shows how to pass values in Outlook to Excel: https://www.slipstick.com/developer/vba-copy-outlook-email-excel-workbook/

      Reply
      • Andrew says

        October 20, 2014 at 10:19 pm

        Thanks Diane!

        I was just using Excel because I'm slightly more familiar with it. There's probably an easier way to do what I'd like using just Outlook. I'm trying to schedule a meeting invite in reference to information that appears in the body of a separate email. Like so:

        Receive request to schedule a meeting.
        Open outlook meeting with subject "Name - Position"
        Body of meeting message says:
        Name: First Last
        Position: President

        I want to pull the Name and Position out of the initial request, and then have it show up in the subject line and body of the new meeting invite.

        I'm using the following code to create the Outlook meeting, and this part has no problem. It's just getting the actual values of Name and Position to populate automatically and remove the need for manual copy/paste.

        Sub SendMeetingRequest()
        Dim objOL 'As Outlook.Application
        Dim objAppt 'As Outlook.AppointmentItem
        Const olAppointmentItem = 1
        Const olMeeting = 1

        Set objOL = CreateObject("Outlook.Application")
        Set objAppt = objOL.CreateItem(olAppointmentItem)
        With objAppt
        .Subject = "NAME - " + "POSITION"
        .Location = "Location"
        .Body = "Hello," & Chr(13) & Chr(13) & "This is an invite for a meeting with the person listed below." & Chr(13) & Chr(13) & "Person: " + "NAME" & Chr(13) & "Title: " + "POSITION" & Chr(13) & "Location: Your Office"
        .Start = Now + 1
        .End = DateAdd("h", 1, .Start)

        ' make it a meeting request
        .MeetingStatus = olMeeting
        .RequiredAttendees = ""
        .Display
        End With

        Set objAppt = Nothing
        Set objOL = Nothing
        End Sub

        Do you know how I can combine the RegEx code with this meeting invite code so that I can pull the person's NAME and POSITION out of the body of an email?

      • Diane Poremsky says

        October 20, 2014 at 11:35 pm

        The regex code on this page (or one of the other regex code pages I have) should do it. (THis is outlook vba)

        Dim strName As String
        Dim strPos As String

        Sub GetValueUsingRegEx()
        Dim olMail As Outlook.MailItem
        Dim Reg1 As RegExp
        Dim M1 As MatchCollection
        Dim M As Match
        Dim strResult(2) As String

        Set olMail = Application.ActiveExplorer().Selection(1)

        Set Reg1 = New RegExp
        For i = 1 To 2

        With Reg1
        Select Case i
        Case 1
        .Pattern = "(Name[:]([\w-\s]+))\s*\r"
        .Global = False

        Case 2
        .Pattern = "(Position[:]([\w-\s]+))\s*\r"
        .Global = False
        End Select

        End With

        If Reg1.test(olMail.Body) Then

        Set M1 = Reg1.Execute(olMail.Body)
        For Each M In M1

        strResult(i) = Trim(M.SubMatches(1))
        Debug.Print strResult(i)

        strName = Replace(strResult(1), vbCrLf, "")
        strPos = Replace(strResult(2), vbCrLf, "")

        Next
        End If

        Next i

        Set Reg1 = Nothing
        SendMeetingRequest
        End Sub

        in the meeting macro, use strName and strPos for the name and position fields -
        .Body = "Hello," & Chr(13) & Chr(13) & "This is an invite for a meeting with the person listed below." & Chr(13) & Chr(13) & "Person: " + strName & Chr(13) & "Title: " + strPos & Chr(13) & "Location: Your Office"

      • Andrew says

        October 21, 2014 at 3:55 pm

        Hi Diane,

        That worked great, thanks! Now, since the object is an appointment, is there any way to set the body to accept HTML?

        If not, is there any other way to set the formatting of specific text in the body, and could I add a table as well?

        Thanks!

      • Diane Poremsky says

        November 24, 2014 at 1:37 am

        No, you can't use HTML in appointments. You can use Word VBA to format - record a macro in Word to get the code that is used ot create the elements you want then put it into outlook. The macro at https://www.slipstick.com/developer/word-macro-apply-formatting-outlook-email/ shows how to use Word code in Outlook.

  60. Dave Upston says

    September 29, 2014 at 3:41 am

    Hi Diane, this article has helped me learn a lot, thanks for putting it together.

    I'm trying to play around with the "Get two (or more) values from a message".

    I've got emails coming in with content like:

    Fax received from TSID: 0297346529
    Line CallerID: 297346529
    Date and Time Received: Mon, 29 Sep 2014 12:42:09 EST
    Number of Pages: 3
    Send to: T1100555
    Connect Time: 1:12
    Date and Time Processed:
    Telstra Job Number: 1718432594

    My perfect end result, would be changing the subject on arrival to:

    Fax from CustomerName - 3 Pages

    Where CustomerName is determined by the number in Line CallerID

    I have a full list of CallerID = CustomerName that can be referenced (somewhere)

    how possible is this?

    Reply
    • Diane Poremsky says

      October 20, 2014 at 9:16 pm

      you'll need to do a lookup in the file to get the name. how many names/numbers are in the list? does it change much? you can use an array within the macro - if it is large or changes you can use a macro to load the array each time it runs.

      Reply
      • Dave Upston says

        October 21, 2014 at 7:38 pm

        I have about 100 customers to list at the moment, and the list will increase as more come on board.

        I've had an issue with the code i was playing with and nothing seems to work at all now. Are you able to help out? Happy to pay/donate somewhere for your time.

      • Diane Poremsky says

        November 24, 2014 at 1:41 am

        Finally getting through oodles and oodles of comments after a few trips this falls. I am available for small projects if you are still stuck on this.

  61. Ramaswamy Ramalingam says

    August 5, 2014 at 10:47 pm

    Hi Diane,

    Thanks for the wonderful article.
    Is it possible that we extract the details from the message and automatically create and save a contact in outlook.

    Thanks,
    Ramaswamy

    Reply
    • Diane Poremsky says

      August 5, 2014 at 11:19 pm

      It is possible, as long as the fields are the same - if the formats are different in each message, a commercial product that grabs details is cost effective. Basically, grab the values and put them in variables then create a contact using those variables in the fields.

      Set oContact = Application.CreateItem(olContactItem)
      With oContact
      .Email1Address = strEmail
      .Email1DisplayName = strName
      .FullName = strName
      .Body = strNotes
      .Save
      End With

      Reply
  62. sun says

    July 10, 2014 at 2:39 pm

    HI Diane,

    I have a requirement like identifying a particular tag in xml and replace it with default text

    ex- 123

    i need to replace 123 with xxx.

    Can we achieve it using regex? Can you please advice?

    Thanks
    Sun

    Reply
    • Diane Poremsky says

      July 11, 2014 at 8:50 pm

      Yes, i believe you can. I don't have any samples that do it though. Will you always be replacing 123 with xxx or some other value.

      Reply
  63. David says

    May 14, 2014 at 7:17 pm

    I was wondering if there is a way to save emails as names from data you parse from inside the email. We have a very generic email that is sent from the same address for user management. I would like to be able to parse each email for the users nt id and in turn save each email as a text file as the nt id. Is this possible? I have scripts that are currently working that save each one with a generic name from a shared folder.

    Reply
    • Diane Poremsky says

      May 15, 2014 at 10:09 pm

      if the NT id is in the message and easily identifiable (so regex can find it), yes, you can grab it and use it in a file name.

      Reply
      • Saurabh says

        June 16, 2014 at 8:07 am

        Hi Diane,

        I am not able to get the pattern for below:
        File_name Count
        ABCDEFGH_1_1_20140615014004.dat.gz:302548
        ABCDEFGH_2_1_20140513084790.dat.gz:168749
        ABCDEFGH_3_4_20140613098489.dat.gz:500023

        I am receiving these kind of records in mail body.
        I want to get these in excel, but I am able to get only File_name.
        Please help me on this.

        I am using this :
        .Pattern = "((ABCDEFGH(.*))([:]+\s*))"

        and what I received in excel is this:
        FILE_NAME Record Count
        ABCDEFGH_1_1_20140615014004.dat.gz _20140615014004.dat.gz

        Also, each time i run this rule, it fetches only 1 record in excel.
        I have more then 500 records in each mail body to be loaded in excel.

        Thanks and Regards
        Saurabh

      • Diane Poremsky says

        June 17, 2014 at 12:46 am

        to get the count as a separate value, try something like
        .Pattern = "(ABCDEFGH(.*)[:](.*)+\s*)"
        If the values will always be numerical, you can use ([0-9]+) instead of (.*)

      • Diane Poremsky says

        June 17, 2014 at 12:48 am

        Oh, and for retrieving each value, you need to use global=true and write the value within the loop (which the example does). Global=False quits as soon as it finds a match.

  64. Alex says

    April 8, 2014 at 11:13 am

    Thanks a lot, Diane. It did not work for some reason but at least pointed me in the right direction. This is what worked for me
    .Pattern = "(Last\s*[:]\s*(\d+\.\d+)\s*)"

    .Pattern = "(At\s*[:]\s*(\d*[-/.]\d*)\s*)"

    Reply
  65. Alex says

    April 7, 2014 at 12:12 pm

    Hi Diane,

    Run into a problem with capturing a date and a decimal:

    At: 4/04 12:20:17
    Last: 105.9805

    Cannot figure out how to do the slash. Dicimal does not work either.

    I tried

    .Pattern = "(At\s*[:]\s*(\w*)\s*)"

    but it captures only the 4, not the rest. Played with several ways but nothing works.

    With the decimal tried

    .Pattern = "(Last\s*[:]\s*(\d*)\s*)"

    but again it only captures 105, not the rest.

    Could you probably give me some tips how to make it work?

    Many thanks in advance,
    Alex

    Reply
    • Diane Poremsky says

      April 7, 2014 at 12:30 pm

      decimals (periods) need to use \. because . is used in regex to signify any character.
      Last: 105.9805 - try .Pattern = "(Last\s*[:]\s*(\d-\.*)\s*)" that should get you 105...555 too, so if you want to look for just digits decimal digits, try something like ([\d*]\.[\d*])
      At: 4/04 12:20:17 - try .Pattern = "(At\s*[:]\s*(\d*-/:)\s*)"
      They might not be correct - I can't test them right now and I'm not a regex expert by any means - but hopefully that will point you in the right direction.

      Reply
  66. Frans says

    February 11, 2014 at 2:42 am

    Hi Diane,

    I have a situation where i receive an email from an internal system with pdf document attached. I then need to forward it to the email mentioned after Email Address: I do this by using your suggested code and it works fine:

    With Reg1
    .Pattern = "(Email Address:\s*(\d*)\s*)"
    .Global = True
    End With

    If Reg1.test(Item.Body) Then
    Set M1 = Reg1.Execute(Item.Body)
    For Each M In M1
    strCode = M.SubMatches(1)
    'MsgBox "reg1: " & strCode
    Next
    End If

    With Reg2
    .Pattern = "([a-z0-9.]*)@([a-z0-9.]*)"
    .Global = True
    End With

    See below what the body of the email looks like.

    Please Find attached report for patient: MRS L HOWSON.
    Email Address: fttest@emaildomain.com
    Reference number: D0630422

    I then need to extract the patient name and the reference number and use that in the new Subject but i dont get it to work. Can you maybe lend a helping hand please.

    Many thanks

    Reply
    • Diane Poremsky says

      February 11, 2014 at 10:12 am

      if the message is plain text, this will work (the email address needs cleaned if html) - rather than looping twice, it uses case statements and an array to pick up the second match in each line.

      Sub PatientInfo()
      Dim olMail As Outlook.MailItem
      Dim Reg1 As RegExp
      Dim M1 As MatchCollection
      Dim M As Match
      Dim strResult(3) As String
      Dim strTest(3) As String
      Dim strName, strRef, strTo As String

      Set Reg1 = New RegExp

      Set olMail = Application.ActiveExplorer().Selection(1)

      For i = 1 To 3
      strResult(i) = ""
      With Reg1
      Select Case i
      Case 1
      .Pattern = "(Please(.*)[:](.*)).\s*\n"
      .Global = False
      Case 2
      .Pattern = "(Email(.*)[:]\s*(.*)).\s*\n"
      .Global = False

      Case 3
      .Pattern = "(Reference(.*)[:](.*)).\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
      strTest(1) = M.SubMatches(1)
      'second match
      strResult(i) = M.SubMatches(2)

      Debug.Print i & strTest(i)
      Debug.Print i & strResult(i)

      strName = strResult(1)
      strTo = strResult(2)
      strRef = strResult(3)

      Next
      End If

      Next i
      Debug.Print "Subject: " & strName & " " & strRef & "email: " & strTo
      Set Reg1 = Nothing
      Set olMail = Nothing
      Set M1 = Nothing
      Set M = Nothing

      End Sub

      Reply
  67. Kevin says

    December 12, 2013 at 10:06 am

    Hi Diane,

    I have a similar situation where I need to create a task from an newmail. Here is the code used for that use:

    Sub ConvertMailToTask(Item As Outlook.MailItem)
    Sub ConvertMailToTask(Item As Outlook.MailItem)
    Dim objTask As Outlook.TaskItem
    Set objTask = Application.CreateItem(olTaskItem)
    With objTask
    .Subject = Item.Subject
    .StartDate = Item.ReceivedTime
    .Body = Item.Body
    .DueDate = (This is the information I am looking for)
    .Save
    End With
    Set objTask = Nothing
    End Sub

    This is activated through a rule running the script. How can I extract the duedate from the body of that mail and apply the value to the previous script?

    Here is the format of the text in the body: Due Date : 2013-12-06

    Thank you!

    Reply
    • Diane Poremsky says

      December 16, 2013 at 12:49 am

      Try this pattern:
      .Pattern = "Due Date\s*[:]+\s*([\w-]*)"

      Reply
  68. zack says

    December 9, 2013 at 3:58 pm

    Can you please help. I have very limited knowledge of VB and I have 2007 Outlook running on windows 7 PC. I want to acheive the following:

    1 - I get the generic email from a marketing source. and i need to extract the following information in the message body.
    - Item number:
    - Item title
    - Name
    - email
    - phone number

    2 - I need to use outlook to auto reply to to the email from the message with BCC to another person(fixed) the message and use a template for that item number. I normally use the signature to reply to message. I have created several signatures with a predefined message to each item number.
    3 - i would like to use the -item title as the subject.

    that will make my life very easy and instead of sitting and replying email with a predefined signatures, everything will automated. Your help will be greatly appreciated.

    Reply
  69. anired says

    December 4, 2013 at 11:13 pm

    Thanks Diane for the reply,actually what am trying to implement is to write a pattern which takes in single mails/chain of mails as input and return the latest mail body txt as output.Yeah even i have tried similar patterns like you have mentioned From separator or signatures like
    thanks,regards but i found these patterns are not fully solving my purpose ,i was wondering is thr any way like outlook separates the mails with a line when we look at mails in outlook client ,so that i can just return the part before the first line separator.any pointers will be a great help .Thanks much.

    PS:the mails are retrieved from exchange server using EWS services with "bodytype.text" as thr format .

    Reply
    • Diane Poremsky says

      December 5, 2013 at 9:25 am

      It's going to be tough. If the message is HTML, you can read the source code - the css is different for previous replies. That won't help if RTF or plain text though.

      Reply
  70. anired says

    December 3, 2013 at 5:41 am

    Hi,

    How to extract the latest mail body from a chain of mails,(i.e the topmost mail body txt from a mail chain) .thanks much

    Reply
    • Diane Poremsky says

      December 4, 2013 at 12:06 pm

      I would try look for the first unique separator - probably From:

      With Reg1
      .Pattern = "(.*)From[:]+\s*(\w*)\s*"
      .Global = False ' stops at the first match
      End With

      If it works (I haven't tested it), the (.*) should get the message down to the first message header.

      Reply
      • Diane Poremsky says

        December 4, 2013 at 12:20 pm

        Hmm. its not picking up the content before the From.

  71. terence says

    November 20, 2013 at 5:29 pm

    Input text at email :

    BAML (BANK OF XXX)
    Total Amount: 1000 Total Price: 22

    CSFB (CREDIT XXX HK)
    Total Amount: 11000 Total Price: 2.2

    How can i achieve

    BAML - 1000
    CSFB - 11000

    Reply
    • Diane Poremsky says

      December 4, 2013 at 12:33 pm

      Will the XXX vary with each message? If it's always BAML (BANK OF XXX) and CSFB (CREDIT XXX HK), you can get the total amount line and hard code the BAML and CSFB. If you need to pick both up too, you'd look for a pattern of (\w*) (\((\w-\s*) and (Total Amount[:]+\s(\d*) - use two case statements and global = true to pick up all entries.

      Reply
  72. Nathan King says

    November 3, 2013 at 9:31 pm

    Hi
    I receive regular emails from a specific sender with an attachment with a generic name. I would like to parse the string in the message and use the string to save my attachment. For example, the attachment is named generic.bmp, and the string I would like to extract from the message is
    Dear user-abc@domain:
    I would like to extract user-abc@domain (without the colon at the end) to save the attachment as user-abc@domain.bmp
    How do I incorporate this script with the save attachment script?
    BTW, this is for Outlook 2010
    Thanks

    Reply
    • Diane Poremsky says

      November 4, 2013 at 4:47 am

      Is this a message you are cc'd on? If so, and if the address is the only one in the To field, you can pull it out with .to. If, for example, you are using code that refers to the message objMsg, you'd use objMsg.To.

      Something like this:
      Set objAttachments = objMsg.Attachments
      strFile = objMsg.To & objAttachments.Item(i).FileName
      strFile = strFolderpath & strFile
      objAttachments.Item(i).SaveAsFile strFile

      Or, you can use this pattern in the macro on this page:
      .Pattern = "(([\w-\.]*\@[\w-\.]*)\s*)"
      and use something like
      strFile = M.SubMatches(1)
      where Debug.Print M.SubMatches(1) is. Use the Dim statements and the code from Set Reg1 line on, replacing olMail.Body with the same name you are using to identify the message (objMsg in my first example).

      Reply
  73. Richard Sutter says

    October 3, 2013 at 3:13 pm

    I have a similar situation, where I have large number of form responses from which I need to extract the same types of info and rearrange them into a set pattern. Typically I receive a message like this:
    ---

    SLA:
    Date Entered: 03-OCT-2013 13:43 (GMT -7) Mountain Time.
    External response time (SLA): 03-OCT-2013 22:43.(GMT -7) Mountain Time.

    SR Description: I would like to start troubleshooting to find out why the analyzer reports etc. etc. etc.
    Company: CUSTOMER COMPANY NAME.
    Top Account: Non GAP.
    Customer Sub Region: West Coast.

    Site:
    Site Name: CUSTOMERSITEALPHA#280501.
    Address: 1234 ACADEMY BLVD,POD A, 1ST FLR, LOC# 1007,.
    City: COLORADO SPRINGS.
    State: Colorado.
    Country: United States.
    Division Name: S&R.

    Opened Via: WEB.
    Contact: John Smith.
    Contact's EMAIL: john.smith@customername.com.

    Contract Number: 12345.
    Service Level: Gold Lite
    Serial #: ABC-12345.
    Service Provider: .

    Priority: .
    Severity: Low.

    SR Status: Open.
    Group Assigned: T1 Americas.
    SR Owner: .
    Owner Mail: .
    Owner Phone: .
    SR Type: Malfunction.

    SR Categorization:
    Solution division: S&R.
    Solution name: ABCD Product.
    Solution version: ABCD Product 4.1.
    Solution UP: 25.
    ---

    And I need to extract info and rearrange it into this:

    External response time (SLA): 03-OCT-2013 22:43.(GMT -7) Mountain Time.
    Serial #: ABC-12345.
    Solution name: ABCD Product.
    Solution version: ABCD Product 4.1.
    Solution UP: 25.
    SR Description: I would like to start troubleshooting to find out why the analyzer reports etc. etc. etc.
    Contact: John Smith.
    john.smith@customername.com.

    I've tried several ways to get this info in this order into a text file or a msg box and just keep failing at the find step.... Any suggestions ?

    Reply
    • Diane Poremsky says

      October 4, 2013 at 9:04 pm

      Try something like this - you'll need 1 case statement for each line you need to capture, in the order you want them. When you get everything, Try putting it into a message body - olMail.body= testSubject - once you know that part is working then you can change the output.

      For i = 1 To 7

      With Reg1
      Select Case i
      Case 1
      .Pattern = "(External response time (SLA)[:]([\w-\s]*)\s*)\n"
      .Global = False

      Case 2
      .Pattern = "(Serial #[:]([\w-\s]*)\s*)\n"
      .Global = False

      Case 3
      .Pattern = "(Solution name:[:]([\w-\s]*)\s*)\n"
      .Global = False
      End Select

      ' repeat for the additional case's

      End With

      Reply
  74. verdantly says

    September 10, 2013 at 1:20 pm

    Hi Diane -

    Thanks again for the good info. I wonder how you would use something similar to the above to find a number in an email when it's label is on the line before or even two lines before. For example, something like this would appear in the body of the email along with items and a total:

    PO#
    --------
    123

    Reply
    • Diane Poremsky says

      September 10, 2013 at 1:32 pm

      If you can figure out the pattern to use, it will work. - I'll see if i can figure it out.

      Reply
  75. Corby Hicks says

    August 20, 2013 at 7:02 am

    Thanks, Diane! Really helpful! I played around with it this morning a bit but haven't had much success. I'm getting the following result "Order VBNSA-025230; .; ." I just realized the Date string is longer than I wrote previously. It actually appears as "09 AUG 2013 14:00:05"... I don't need / want the time. I'm assuming that would be the reason for the date not appearing in the results?

    THANKS AGAIN!

    Reply
    • Diane Poremsky says

      August 20, 2013 at 7:45 am

      That would be the reason. Try this as case 2 - .Pattern = "(Date[:]([\w-\s]*))\s\d*[:]"

      Reply
  76. Corby Hicks says

    August 19, 2013 at 12:26 pm

    Hi. Thanks for your articles! They have been very helpful. I am wondering if there is a way to capture multiple pieces of information and copy them to the subject. For example, on receipts I receive regularly, I need to extract three pieces of info:
    Order ID : VBNSA-XXXXXX
    Order Date: 09 AUG 2013
    Total $XX.XX

    Is it possible to find these and copy into the subject field?

    Reply
    • Diane Poremsky says

      August 19, 2013 at 3:50 pm

      It is possible. This gets the order and date: .Pattern = "([:]([\w-\s]*)\n)" The money patterns I tried aren't working. I'll see if i can get one that works for it.

      Reply
      • Diane Poremsky says

        August 19, 2013 at 5:56 pm

        I added a code sample to the page that get multiple patterns from a message. If you need to process the messages as they arrive, you can convert it to a run a script rule by changing the sub name to Public Sub GetValueUsingRegEx(Item As Outlook.MailItem) and creating a rule.

  77. carrolltd47 says

    June 25, 2013 at 11:43 am

    Wanted to output to a text file.

    Reply
    • Diane Poremsky says

      June 25, 2013 at 12:28 pm

      Crude version of the necessary code, taken from the second macro here. This code woulds go after End If, before End Sub.
      Set objFile = objFS.CreateTextFile(strFile, False)
      For Each oMail In ActiveExplorer.Selection
      With objFile
      .Write M.SubMatches(1)
      End With
      Next
      objFile.Close

      I have a macro that uses regex to write to Excel at Use a macro to copy data in Outlook email to Excel workbook.

      Reply
  78. carrolltd47 says

    June 25, 2013 at 5:16 am

    Diane, this is a great tip, however, can you tell me how to point to a specific folder in Outlook and where the output file is created?

    Thanks,

    Tim

    Reply
    • Diane Poremsky says

      June 25, 2013 at 9:22 am

      The code works on the selected message, so its not limited to any folder. It's a concept macro, so it only outputs to the immediate window (Ctrl+G to open the immediate window in the VB Editor)
      Debug.Print M.SubMatches(1)

      what type of file did you want to create?

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Visit Slipstick Forums.
What's New at Slipstick.com

Latest EMO: Vol. 31 Issue 3

Subscribe to Exchange Messaging Outlook






Support Services

Do you need help setting up Outlook, moving your email to a new computer, migrating or configuring Office 365, or just need some one-on-one assistance?

Our Sponsors

CompanionLink
ReliefJet
  • Popular
  • Latest
  • Week Month All
  • Jetpack plugin with Stats module needs to be enabled.
  • Sync Issues and Errors with Gmail and Yahoo accounts
  • Error Opening iCloud Appointments in Classic Outlook
  • Opt out of Microsoft 365 Companion Apps
  • Mail Templates in Outlook for Windows (and Web)
  • Urban legend: Microsoft Deletes Old Outlook.com Messages
  • Buttons in the New Message Notifications
  • Move Deleted Items to Another Folder Automatically
  • Open Outlook Templates using PowerShell
  • Count and List Folders in Classic Outlook
  • Google Workspace and Outlook with POP Mail
Ajax spinner

Recent Bugs List

Microsoft keeps a running list of issues affecting recently released updates at Fixes or workarounds for recent issues in classic Outlook (Windows).

For new Outlook for Windows: Fixes or workarounds for recent issues in new Outlook for Windows .

Outlook for Mac Recent issues: Fixes or workarounds for recent issues in Outlook for Mac

Outlook.com Recent issues: Fixes or workarounds for recent issues on Outlook.com

Office Update History

Update history for supported Office versions is at Update history for Office

Outlook Suggestions and Feedback

Outlook Feedback covers Outlook as an email client, including Outlook Android, iOS, Mac, and Windows clients, as well as the browser extension (PWA) and Outlook on the web.

Outlook (new) Feedback. Use this for feedback and suggestions for Outlook (new).

Use Outlook.com Feedback for suggestions or feedback about Outlook.com accounts.

Other Microsoft 365 applications and services




New Outlook Articles

Sync Issues and Errors with Gmail and Yahoo accounts

Error Opening iCloud Appointments in Classic Outlook

Opt out of Microsoft 365 Companion Apps

Mail Templates in Outlook for Windows (and Web)

Urban legend: Microsoft Deletes Old Outlook.com Messages

Buttons in the New Message Notifications

Move Deleted Items to Another Folder Automatically

Open Outlook Templates using PowerShell

Count and List Folders in Classic Outlook

Google Workspace and Outlook with POP Mail

Newest Code Samples

Open Outlook Templates using PowerShell

Count and List Folders in Classic Outlook

Insert Word Document into Email using VBA

Warn Before Deleting a Contact

Use PowerShell to Delete Attachments

Remove RE:, FWD:, and Other Prefixes from Subject Line

Change the Mailing Address Using PowerShell

Categorize @Mentioned Messages

Send an Email When You Open Outlook

Delete Old Calendar Events using VBA

VBA Basics

How to use the VBA Editor

Work with open item or selected item

Working with All Items in a Folder or Selected Items

VBA and non-default Outlook Folders

Backup and save your Outlook VBA macros

Get text using Left, Right, Mid, Len, InStr

Using Arrays in Outlook macros

Use RegEx to extract message text

Paste clipboard contents

Windows Folder Picker

Custom Forms

Designing Microsoft Outlook Forms

Set a custom form as default

Developer Resources

Developer Resources

Developer Tools

VBOffice.net samples

SlovakTech.com

Outlook MVP David Lee

Repair PST

Convert an OST to PST

Repair damaged PST file

Repair large PST File

Remove password from PST

Merge Two Data Files

Sync & Share Outlook Data

  • Share Calendar & Contacts
  • Synchronize two computers
  • Sync Calendar and Contacts Using Outlook.com
  • Sync Outlook & Android Devices
  • Sync Google Calendar with Outlook
  • Access Folders in Other Users Mailboxes

Diane Poremsky [Outlook MVP]

Make a donation

Mail Tools

Sending and Retrieval Tools

Mass Mail Tools

Compose Tools

Duplicate Remover Tools

Mail Tools for Outlook

Online Services

Calendar Tools

Schedule Management

Calendar Printing Tools

Calendar Reminder Tools

Calendar Dates & Data

Time and Billing Tools

Meeting Productivity Tools

Duplicate Remover Tools

Productivity

Productivity Tools

Automatic Message Processing Tools

Special Function Automatic Processing Tools

Housekeeping and Message Management

Task Tools

Project and Business Management Tools

Choosing the Folder to Save a Sent Message In

Run Rules on messages after reading

Help & Suggestions

Submit Outlook Feature Requests

Slipstick Support Services

Buy Microsoft 365 Office Software and Services

Visit Slipstick Forums.

What's New at Slipstick.com

Home | Outlook User | Exchange Administrator | Office 365 | Outlook.com | Outlook Developer
Outlook for Mac | Common Problems | Utilities & Addins | Tutorials
Outlook & iCloud Issues | Outlook Apps
EMO Archives | About Slipstick | Slipstick Forums
Submit New or Updated Outlook and Exchange Server Utilities

Send comments using our Feedback page
Copyright © 2026 Slipstick Systems. All rights reserved.
Slipstick Systems is not affiliated with Microsoft Corporation.