I tried to set a rule in Outlook only to learn that rules are not case-sensitive.
I want if an email is received and the subject includes "Test Email" (like This is a Test Email), then check the body.
If the body contains the word NO, in capital letters (not a part of a word), then move the email to a specific folder.
I found the below script for incoming emails that contain NO in the body.
How do I first check for "Test Email" in the title?
Private WithEvents InboxItems As Outlook.Items
Private m_Rules As Variant
Sub Application_Startup()
Dim i As Long
i = -1: ReDim m_Rules(1000)
i = i + 1: m_Rules(i) = Array("NO", "No Folder")
ReDim Preserve m_Rules(i)
Set InboxItems = Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub InboxItems_ItemAdd(ByVal Item As Object)
Dim Folder As Outlook.MAPIFolder
Dim i As Long, Find As String
'Find = Item.Subject
Find = Item.Body
For i = 0 To UBound(m_Rules)
If InStr(1, Find, m_Rules(i)(0), vbBinaryCompare) Then
Set Folder = Application.Session.GetDefaultFolder(olFolderInbox)
Set Folder = Folder.Folders(m_Rules(i)(1))
Item.Move Folder
Exit For
End If
Next
End Sub
Here is a Regex search function which I use to filter received e-mail. Should be editable to what you desire
In ThisOutlookSession
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
On Error Resume Next
Call RegExFilterRules(EntryIDCollection)
End Sub
In a module
Sub RegExFilterRules(ItemID As String)
Dim ThisNamespace As Outlook.NameSpace: Set ThisNamespace = Application.GetNamespace("MAPI")
Dim Inbox As Outlook.MAPIFolder: Set Inbox = ThisNamespace.GetDefaultFolder(olFolderInbox)
Dim Junk As Outlook.MAPIFolder: Set Junk = ThisNamespace.GetDefaultFolder(olFolderJunk)
Dim oMsg As Outlook.MailItem: Set oMsg = ThisNamespace.GetItemFromID(ItemID, Inbox.StoreID)
If Not oMsg Is Nothing And oMsg.Class = olMail Then
If FindPattern(oMsg.Subject, "^M\d+$") Then oMsg.Move Junk ' oMsg.Delete
End If
End Sub
Private Function FindPattern(Str As String, Pattern As String) As Boolean
' Requires Reference: Microsoft Scripting Runtime
Dim RegEx As Object: Set RegEx = CreateObject("vbscript.RegExp")
With RegEx
.Global = True
.IgnoreCase = True
.MultiLine = True
.Pattern = Pattern
FindPattern = .Test(Str)
End With
End Function
Related
I'm attempting to move email with specific subject when received.
The mail is still in my Inbox. I've tested by sending mail from my account with specific subject.
Option Explicit
Private WithEvents inboxItems As Outlook.Items
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application
Dim objectNS As Outlook.NameSpace
Set outlookApp = Outlook.Application
Set objectNS = outlookApp.GetNamespace("MAPI")
Set inboxItems = objectNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
Dim Msg As Outlook.MailItem
Set myInbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
If TypeName(item) = "MailItem" Then
Set Msg = item
If InStr(0, Msg.Subject, "Testing Subject", vbTextCompare) > 0 Then
Set fldr = Outlook.Session.GetDefaultFolder(olFolderInbox).Folders("Testing")
Msg.Move fldr
End If
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
I created this macro in ThisOutlookSession.
I think you may have an error with the naming of your Sub which means it doesn't fire
Items_ItemAdd => inboxItems_ItemAdd
As an addendum: I recently implemented a RegEx filter to incoming e-mails as I found I couldn't easily use rules to filter out some junk e-mail coming my way. This should be able to adapted to your needs (I've added the rule I think should work for you, but it's untested)
Within the 'ThisOutlookSession'
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
On Error Resume Next
Call RegExFilterRules(EntryIDCollection)
End Sub
Within a module
Sub RegExFilterRules(ItemID As String)
' Requires Reference: Microsoft Scripting Runtime
Dim ThisNamespace As Outlook.NameSpace: Set ThisNamespace = Application.GetNamespace("MAPI")
Dim Inbox As Outlook.MAPIFolder: Set Inbox = ThisNamespace.GetDefaultFolder(olFolderInbox)
Dim Junk As Outlook.MAPIFolder: Set Junk = ThisNamespace.GetDefaultFolder(olFolderJunk)
Dim oMsg As Outlook.MailItem: Set oMsg = ThisNamespace.GetItemFromID(ItemID, Inbox.StoreID)
If Not oMsg Is Nothing And oMsg.Class = olMail Then
'If FindPattern(oMsg.Subject, "^M\d+$") Then oMsg.Move Junk ' oMsg.Delete
If FindPattern(oMsg.Subject, "^Testing Subject") Then oMsg.Move Inbox.Folders("Testing")
End If
End Sub
Private Function FindPattern(Str As String, Pattern As String) As Boolean
Dim RegEx As Object: Set RegEx = CreateObject("vbscript.RegExp")
With RegEx
.Global = True
.IgnoreCase = True
.MultiLine = True
.Pattern = Pattern
FindPattern = .Test(Str)
End With
End Function
I want to add user to an existing DL using outlook VBA. For example. I have a DL which has email id as "testdl#contoso.com" and want add an existing user name "John.Wick#contoso.com". I also know that I can use DistListItem.AddMember to add user to an existing DL. But I am getting idea to find the existing distribution list. Please help me with this.
Sub Add_User_To_DL()
Dim myNameSpace AS Outlook.NameSpace
Dim myFolder AS Outlook.Folder
Dim myDistList AS Outlook.DistListItem
Dim myFolderItems AS Outlook.Items
Set myNameSpace = Application.GetNamespace("MAPI")
Set myFolder = myNameSpace.GetDefaultFolder(olFolderContacts)
myFolder.Display
End Sub
But this code just opens Contacts group window. What I want is , to open the specified DL and then add specified member to DL.
To find a distribution list that includes a specific address.
Option Explicit
Sub Find_ContactGroup_Given_Member()
Dim ContactGroup As String
Dim objItem As Object
Dim objContactsFolder As Folder
Dim i As Long
Set objContactsFolder = Session.GetDefaultFolder(olFolderContacts)
For Each objItem In objContactsFolder.Items
If TypeOf objItem Is DistListItem Then
Debug.Print objItem.DLName
For i = 1 To objItem.MemberCount
If objItem.GetMember(I).Address = "testdl#contoso.com" Then
Debug.Print objItem.GetMember(i).Name
objItem.Display
End If
Next i
End If
Next
End Sub
To reference a distribution list:
Option Explicit
Sub DistListDisplay()
Dim strDistListName As String
Dim objItem As Object
Dim objContactsFolder As Folder
Dim objContactGroup As DistListItem
Dim bFound As Boolean
strDistListName = InputBox("Name of an existing distribution list.", , "Test")
If Len(strDistListName) = 0 Then Exit Sub ' Cancel
Set objContactsFolder = Session.GetDefaultFolder(olFolderContacts)
For Each objItem In objContactsFolder.Items
If TypeOf objItem Is DistListItem Then
If objItem.DLName = strDistListName Then
Set objContactGroup = objItem
With objContactGroup
.Display
bFound = True
Exit For
End With
End If
End If
Next
If bFound = False Then
MsgBox strDistListName & " not found."
End If
End Sub
I hired someone to write code which does the following when an email is highlighted.
FW Email
Insert already copied item from clipboard and paste in To Field (the copied email address)
Remove FW: from Subject line
Remove everything above the original message which includes the original email info/date/address etc.
It leaves a blank line above the first word of the body which is "Hello Name".
How can I delete that empty row so "Hello Name" is at the top of the email OR delete the "Hello Name" alltogether?
Sub ForwardFromClipboard2()
Dim tmpEmail As MailItem
Dim fwEmail As MailItem
For Each Item In Application.ActiveExplorer.Selection
If TypeName(Item) = "MailItem" Then
Set tmpEmail = Item.Forward
tmpEmail.Subject = Item.Subject
tmpEmail.To = GetClipBoardText
tmpEmail.Display
RemoveSign (tmpEmail.Subject)
Set tmpEmail = Nothing
End If
Next
End Sub
Sub RemoveSign(MySubject As String)
Dim objOL As Application
Dim objDoc As Object
Dim objSel As Object
Set objOL = Application
Set objDoc = objOL.ActiveInspector.WordEditor
Set objSel = objDoc.Application.Selection
' delete signature
If objDoc.Bookmarks.Exists("_MailOriginal") Then
Set objBkm = objDoc.Bookmarks("_MailOriginal")
objSel.Start = 0
objSel.End = objBkm.Start
objDoc.Windows(1).Selection.Delete
End If
' delete FROM:, TO:, SUBJECT:
Dim search As String
search = "Subject:"
Dim search2 As String
search2 = MySubject
For Each para In objDoc.Paragraphs
Dim txt As String
txt = para.Range.Text
If InStr(txt, search) Or InStr(txt, search2) Then
para.Range.Delete
Exit For
End If
Next
End Sub
Function GetClipBoardText() As String
Dim DataObj As MSForms.DataObject
Set DataObj = New MSForms.DataObject
On Error GoTo Whoa
DataObj.GetFromClipboard
myString = DataObj.GetText(1)
GetClipBoardText = myString
Exit Function
Whoa:
GetClipBoardText = ""
End Function
You can use the HTMLBody or the Word object model to edit the message body according to your needs. The Word object model provides the Delete method of the Range class which deletes the specified number of characters or words. See Chapter 17: Working with Item Bodies for more information.
Every day I receive several automated e-mails which contain some information that needs to be forwarded to another e-mail address(es).
This e-mail address is in the automated e-mail, and will not always be the same. This e-mail address is located in a table, under the row labeled "Remarks". I've inserted a picture to illustrate this.
I would like to automate this process using Outlook VBA Macros. Some additional information:
1) I cannot use the "run a script" function under Rules.
2) The incoming e-mails are automated and will always be the same format.
What I need help is in:
1) Copying the e-mail address in the next column of the "remarks" row.
I have already managed to automate the process of recognizing the incoming e-mail (by its subject title) and auto-forwarding it to a predefined e-mail address and changing the forwarded email subject title.
Private WithEvents Items as Outlook.Items
Private Sub application_startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNameSpace("MAPI")
'Setting target folder as inbox
Set Items = objectNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
On Error GoTo ErrorHandler
Dim Msg As Outlook.Mailitem
'act only if it is a mail item
If TypeName(Item) = "MailItem" Then
Set Msg = Item
'Detect emails with specified subject title
If Msg.Subject = "Test" Then
Set myForward = Item.Forward
myForward.Recipients.Add("test#gmail.com")
myForward.Subject = "FW: Success"
myForward.Save
myForward.Send
EndIf
EndIf
ProgramExit: Exit Sub
ErrorHandler:
MsgBox Err.Number & "-" & Err.Description
Resume ProgramExit
End Sub
According to my understand, You want to get address in email body.
You could use the below code:
Option Explicit
Sub Example()
Dim Item As MailItem
Dim RegExp As Object
Dim Search_Email As String
Dim Pattern As String
Dim Matches As Variant
Dim len1 As String
Dim result As String
Set RegExp = CreateObject("VbScript.RegExp")
Pattern = "remarks\s+(\b[A-Z0-9._%+-]+\b)"
For Each Item In ActiveExplorer.Selection
Search_Email = Item.Body
With RegExp
.Global = False
.Pattern = Pattern
.IgnoreCase = True
Set Matches = .Execute(Search_Email)
End With
If Matches.Count > 0 Then
len1 = Matches(0).Length() - 8
result = Mid(Matches(0), 12, len1)
result = result + "#gmail.com"
MsgBox result
Debug.Print Matches(0)
Else
Debug.Print "Not Found "
End If
Next
Set RegExp = Nothing
End Sub
For more information, you could refer to this link:
Extract Email address from a table in .HTMLbody
I am trying to, in VBA for Outlook 2013, sort any mail with a certain number format in the subject into corresponding folders. If the folder does not exist (if the strings in the subject and folder don't match), the folder is created. I need this macro to handle a non-default inbox. The following links are where I got the original code, which is spliced together at the bottom. I'm getting a run time error (-2147221233 (8004010f)) on line:
Set objProjectFolder = objDestinationFolder.Folders(folderName)
http://joelslowik.blogspot.com/2011/04/sort-emails-in-outlook-using-macro-and.html
Get email from non default inbox?
Dim WithEvents myitems As Outlook.Items
Dim objDestinationFolder As Outlook.MAPIFolder
Sub Application_Startup()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.MAPIFolder
Dim myitems As Outlook.Items
Dim strFilter As String
' let the user choose which account to use
Set myAccounts = Application.GetNamespace("MAPI").Stores
For i = 1 To myAccounts.Count
res = MsgBox(myAccounts.Item(i).DisplayName & "?", vbYesNo)
If res = vbYes Then
Set myInbox = myAccounts.Item(i).GetDefaultFolder(olFolderInbox)
Exit For
End If
Next
If myInbox Is Nothing Then Exit Sub ' avoid error if no account is chosen
Set objDestinationFolder = myInbox.Parent.Folders("Inbox")
For Count = myInbox.Items.Count To 1 Step -1
Call myitems_ItemAdd(myInbox.Items.Item(Count))
Next Count
StopRule
End Sub
' Run this code to stop your rule.
Sub StopRule()
Set myitems = Nothing
End Sub
' This code is the actual rule.
Private Sub myitems_ItemAdd(ByVal Item As Object)
Dim objProjectFolder As Outlook.MAPIFolder
Dim folderName As String
' Search for email subjects that contain a case number
' Subject line must have the sequence of 4 numbers + - + 3 numbers (CPS case number syntax)
Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Global = False
objRegEx.Pattern = "[0-9]{4,4}\-?[0-9]{0,3}"
Set colMatches = objRegEx.Execute(Item.Subject)
'For all matches, move those matches to respective folder (create folder if it does not exist)
If colMatches.Count > 0 Then
For Each myMatch In colMatches
folderName = "Docket # " & myMatch.Value
If FolderExists(objDestinationFolder, folderName) Then
Set objProjectFolder = objDestinationFolder.Folders(folderName)
Else
Set objProjectFolder = objDestinationFolder.Folders.Add(folderName)
End If
Item.Move objProjectFolder
Next
End If
Set objProjectFolder = Nothing
End Sub
Function FolderExists(parentFolder As MAPIFolder, folderName As String)
Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Global = False
objRegEx.Pattern = folderName
For Each F In parentFolder.Folders
Set colMatches = objRegEx.Execute(F.Name)
If colMatches.Count > 0 Then
FolderExists = True
folderName = colMatches(0).Value
Exit Function
End If
Next
FolderExists = False
End Function
I recently upgraded to Outlook 2016 and had the same problem: the default Inbox was not where I expected it.
When I installed Outlook 2016, it created a default store “outlook data file”. As I added my email accounts, it created a separate store for each of them. It was not until later I realised the default Inbox was in the unused “outlook data file”.
For your interest, this macro will display the name of the store holding the default Inbox:
Sub DsplUsernameOfStoreForDefaultInbox()
Dim NS As Outlook.NameSpace
Dim DefaultInboxFldr As MAPIFolder
Set NS = CreateObject("Outlook.Application").GetNamespace("MAPI")
Set DefaultInboxFldr = NS.GetDefaultFolder(olFolderInbox)
Debug.Print DefaultInboxFldr.Parent.Name
End Sub
In your code replace
Set myInbox = myAccounts.Item(i).GetDefaultFolder(olFolderInbox)
by
Set myInbox = Session.Folders("outlook data file").Folders("Inbox")
after replacing "outlook data file" with the name of the store containing the Inbox you wish to access.
You can use this technique for referencing any folder at any depth within any store. For example:
Set FldrTgt = Session.Folders("zzzz").Folders("yyyy").Folders("xxxx").Folders("wwww")
Extra point
I do not see the point of:
Set objDestinationFolder = myInbox.Parent.Folders("Inbox")
This starts at myBox, uses property Parent to go up to the store then property Folders to go down to "Inbox" again. It is the same as:
Set objDestinationFolder = myInbox