I have set a rule on outlook to delete permanently incoming email (based on subject condition).
I also set a vba macro to forward incoming emails (because any rules to forward emails are disabled by IT).
The problem:
the macro of (forward incoming emails) is auto run before the outlook rule is executed.
I need to run my macro after that rule on outlook is executed and finished.
I do not prefer to transfer the rule itself into a vba code.
In advance, all thanks for your support.
Private Sub objInboxItems_ItemAdd(ByVal item As Object) 'Forward Incoming emails
Dim objMail As Outlook.MailItem
Dim objForward As Outlook.MailItem
If Not TypeOf item Is MailItem Then Exit Sub
Set objMail = item
Set objForward = objMail.Forward
With objForward
.Recipients.Add ("***#yahoo.com")
.Recipients.ResolveAll
.Send
End With
Set objMail = Nothing
Set objForward = Nothing
End Sub
Force the rule to run on startup.
The assumption is this will run before ItemAdd code.
In ThisOutlookSession
Private Sub Application_Startup()
Dim st As Store
Dim myRules As Rules
Dim rl As Rule
Dim ruleName As String
Dim k As Long
' get store (can be any store)
Set st = Session.defaultStore
Debug.Print st.DisplayName
' get rules from specified store
Set myRules = st.GetRules()
ruleName = "name of rule to delete incoming email based on subject"
For k = 1 To myRules.count
Set rl = myRules(k)
Debug.Print myRules(k).name
If myRules(k).name = ruleName Then
' Regardless of rule store,
' the applicable Folder is by default the inbox of the default store
' Designate a folder if not the default inbox
rl.Execute ShowProgress:=True
Debug.Print ruleName & " has run."
Exit For
End If
Next
End Sub
Related
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
In MS Outlook there are two accounts. For most incoming email the two accounts receive the same email, sometimes in CC or TO fields together. The two accounts are similar and have almost the same subfolders.
Application_NewMailEX triggers twice if email is sent to both accounts.
I need to handle only one account (Inbox folder and its subfolders) and not the second one.
My purpose is execute the code in the NewMailEx sub only one time and only for one of the two email accounts set up in Outlook and not for the other one.
The code after some jobs inserts some values in a SQL Server DB.
Something like:
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
Dim arr() As String
Dim NS As Outlook.NameSpace
Dim itm As MailItem
Dim m As Outlook.MailItem
Dim i as Integer
On Error Resume Next
arr = Split(EntryIDCollection, ",")
For i = 0 To UBound(arr)
Set itm = NS.GetItemFromID(arr(i))
If itm.Class = olMail Then
Set m = itm
' Filter
If m.Sender = "Our Client" and Trim(m.Subject) = "12 AXR check" then
' operations
'....
' Insert DB
'....
End If
' Other things
End If
Next
End Sub
Without understanding why there is duplication I can suggest you verify the inbox first.
Option Explicit
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
Dim arr() As String
Dim NS As Outlook.NameSpace
'Dim itm As Mailitem
Dim itm As Object ' <---
Dim m As Outlook.mailitem
Dim i As Integer
'On Error Resume Next
' If you need this determine the exact place then
' turn error bypass off as soon as possible with
'On Error GoTo 0
Set NS = GetNamespace("MAPI")
arr = Split(EntryIDCollection, ",")
For i = 0 To UBound(arr)
Set itm = NS.GetItemFromID(arr(i))
If itm.Class = olMail Then
Set m = itm
Debug.Print "mail received"
Debug.Print itm.Parent.Parent.name
If itm.Parent.Parent.name = "someone#somewhere.com" Then
' operations
Debug.Print " item in my inbox processed"
Else
Debug.Print " item in any other inbox not processed"
End If
End If
Next
End Sub
Update
I only made a small change and its working
If InStr(1, LCase(itm.Parent.Parent.FolderPath), "sharingaccount#123.abc") > 0 Then
Debug.Print "OK"
End If
I used that code because I have a structure, for the accounts, like the following and I wanted to handle only and exclusively incoming email in SharingAccount and its subfolder:
MyPersonalMail#123.abc
Inbox
Documents
FromLinux
FromAra
SharingAccount#123.abc
Inbox
Documents
FromLinux
FromAra
Thanks
I created a rule, that starts a VBA-script depending on the subject of a received email (Rule: Subject "MY_SUBJECT" -> start script).
The VBA script is then doing some stuff and then it should finally delete the original email.
This part is easy:
Sub doWorkAndDeleteMail(Item As Outlook.MailItem)
' doSomething:
' delete email from inbox
Item.Delete
End Sub
Now the email will sit in the deleted-items-folder. But what I need to achieve is, to also delete this mail from the deleted-items folder. Since I know the subject of this mail (because this triggered my rule in the first place), I tried the following approach:
Sub doWorkAndDeleteMail(Item As Outlook.MailItem)
' doSomething:
' delete email from inbox
Item.Delete
End Sub
' delete email from deleted items-folder
Dim deletedFolder As Outlook.Folder
Set deletedFolder = Application.GetNamespace("MAPI"). _
GetDefaultFolder(olFolderDeletedItems)
Dim i As Long
For i = myFolder.Items.Count To 1 Step -1
If (deletedFolder.Items(i).Subject) = "MY_SUBJECT" Then
deletedFolder.Items(i).Delete
Exit For
End If
Next if
End Sub
Well, this basically works: The mail with this subject will be found in the deleted-items-folder and it will be deleted, yes.
But sadly it does not work as expected:
This permanent deletion only works once I start the script a second time.
So the email which is triggering my script will never be deleted permanently in this script's actual run, but only in the next run (once the next email with the trigger-subject for my rule is received - but then this very next email won't be deleted, again).
Do you have any idea what I am doing wrong here? It somehow looks like I need to refresh my deleted-items folder somehow. Or do I have to comit my first Item.Delete somehow explicitly?
The problem was not recreated, but try stepping through this then run normally if it appears to do what you want.
Sub doWorkAndDeleteMail(Item As mailitem)
Dim currFolder As Folder
Dim DeletedFolder As Folder
Dim i As Long
Dim mySubject As String
Set currFolder = ActiveExplorer.CurrentFolder
mySubject = Item.Subject
Debug.Print mySubject
Set DeletedFolder = GetNamespace("MAPI").GetDefaultFolder(olFolderDeletedItems)
Set ActiveExplorer.CurrentFolder = DeletedFolder
Debug.Print "DeletedFolder.count before delete: " & DeletedFolder.Items.count
' delete email from deleted items-folder
Item.Delete
Debug.Print "DeletedFolder.count after delete: " & DeletedFolder.Items.count
' If necessary
'DoEvents
For i = DeletedFolder.Items.count To 1 Step -1
Debug.Print DeletedFolder.Items(i).Subject
If (DeletedFolder.Items(i).Subject) = mySubject Then
Debug.Print DeletedFolder.Items(i).Subject & " *** found ***"
DeletedFolder.Items(i).Delete
Exit For
End If
Next
Set ActiveExplorer.CurrentFolder = currFolder
End Sub
Tim Williams suggested another existing thread. I had a look at that already before and decided that appoach would be exactly the same representation of my bug. I did try it out, though (to show my motiviation :) ), but the behaviour is - as expected - exactly the same: Again the final deletion only works once the next time the script is triggered via rule:
Sub doWorkAndDeleteMail(Item As Outlook.MailItem)
' First set a property to find it again later
Item.UserProperties.Add "Deleted", olText
Item.Save
Item.Delete
'Now go through the deleted folder, search for the property and delete item
Dim objDeletedFolder As Outlook.Folder
Dim objItem As Object
Dim objProperty As Variant
Set objDeletedFolder = Application.GetNamespace("MAPI"). _
GetDefaultFolder(olFolderDeletedItems)
For Each objItem In objDeletedFolder.Items
Set objProperty = objItem.UserProperties.Find("Deleted")
If TypeName(objProperty) <> "Nothing" Then
objItem.Delete
End If
Next
End Sub
I would be really glad to get some help here. I also wanted to comment on that other thread, but my reputation is not enough, yet.
Try something like this, code goes under ThisOutlookSession
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim olNs As Outlook.NameSpace
Dim DeletedFolder As Outlook.MAPIFolder
Set olNs = Application.GetNamespace("MAPI")
Set DeletedFolder = olNs.GetDefaultFolder(olFolderDeletedItems)
Set Items = DeletedFolder.Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
Dim olNs As Outlook.NameSpace
Dim DeletedFolder As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim Filter As String
Dim i As Long
Set olNs = Application.GetNamespace("MAPI")
Set DeletedFolder = olNs.GetDefaultFolder(olFolderDeletedItems)
Filter = "[Subject] = 'MY_SUBJECT'"
Set Items = DeletedFolder.Items.Restrict(Filter)
If TypeOf Item Is Outlook.MailItem Then
For i = Items.Count To 1 Step -1
DoEvents
Items.Remove i
Next
End If
End Sub
Edit
Sub doWorkAndDeleteMail(Item As Outlook.MailItem)
' First set a property to find it again later
Item.UserProperties.Add "Deleted", olText
Item.Save
Item.Delete
'Now go through the deleted folder, search for the property and delete item
Dim olNs As Outlook.NameSpace
Dim DeletedFolder As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim Filter As String
Dim i As Long
Set olNs = Application.GetNamespace("MAPI")
Set DeletedFolder = olNs.GetDefaultFolder(olFolderDeletedItems)
Filter = "[Subject] = 'MY_SUBJECT'"
Set Items = DeletedFolder.Items.Restrict(Filter)
If TypeOf Item Is Outlook.MailItem Then
For i = Items.Count To 1 Step -1
DoEvents
Items.Remove i
Next
End If
End Sub
the Mailbox folder that you get can be used as a collection, meaning that you can remove the item directly, you will need the collection to be sent to the function but that should be managable :)
Sub doWorkAndDeleteMail(Mailbox As Outlook.Folder, Item As Outlook.MailItem)
' doSomething:
' delete email from inbox
For Ite = 1 To Mailbox.Items.Count
If Mailbox.Items(Ite).EntryID = Item.EntryID Then
Mailbox.Items.Remove Ite
Exit For
End If
Next
End Sub
Remember that IF you want to Delete more than 1 Item per call of "For Ite = 1 To Mailbox.Items.Count", you will need to subtract 1 from the check of the item within the For segment since when you remove a mail from it, it will reduce the rest of the mails index number by 1.
Hope you can still use this :)
Regards Sir Rolin
I would like to make it so if an email comes in with a phone number in the subject line (so 10 numerical digits) then the system automatically moves it to a folder called "Texting."
User Reidacus asked a very similar question here:
Move incoming mail to folders with RegEx in a rule
But I can't get it to work for me. When the email comes in it just sits in my inbox. I am very new the VBA and (sorry), I don't have a clue what I'm doing. Do I need to install anything special into my system to get this to work?
Here is my adapted code (note: in the real code I have my real email address)
Sub filter(Item As Outlook.MailItem)
Dim ns As Outlook.NameSpace
Dim MailDest As Outlook.Folder
Set ns = Application.GetNamespace("MAPI")
Set Reg1 = CreateObject("VBScript.RegExp")
Reg1.Global = True
Reg1.Pattern = "([\d][\d][\d][\d][\d][\d][\d][\d][\d][\d])"
If Reg1.Test(Item.Subject) Then
Set MailDest = ns.Folders("firstname.lastname#email.ca").Folders("Inbox").Folders("Texting")
Item.Move MailDest
End If
End Sub
In order for your Sub Filter to run everytime a new emails comes in, you need to add an "event listener", by adding the code below to the ThisOutlookSession module (this code is taken from home, here on SO : How do I trigger a macro to run after a new mail is received in Outlook? )
In order for this code to take affect, you must Restart Outlook.
ThisOutlookSession Module Code
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")
' get default local Inbox
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
' Call your custom-made Filter Sub
Call filterNewMail_TenDig(item)
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
Now, you only need to make the following modifications to your Module code. Using ns.GetDefaultFolder(olFolderInbox) will get you the default "Inbox" folder for the current profile (read here at MSDN link ).
Sub filterNewMail_TenDig Code
Sub filterNewMail_TenDig(item As Outlook.MailItem)
Dim ns As Outlook.NameSpace
Dim MailDest As Outlook.Folder
Set ns = Outlook.Application.GetNamespace("MAPI")
Set reg1 = CreateObject("VBScript.RegExp")
With reg1
.Global = True
.IgnoreCase = True
.Pattern = "\d{10,10}" ' Match any set of 10 digits
End With
If reg1.Test(item.Subject) Then
Set MailDest = ns.GetDefaultFolder(olFolderInbox).Folders("Texting")
item.Move MailDest
End If
End Sub
I'm trying to forward emails from my company's Outlook to an email account outside of our company. I have been given the ok to do this.
I'd like to forward any email that contains "Excel Friday" in the subject line.
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")
' default local Inbox
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
On Error GoTo ErrorHandler
Dim Msg As Outlook.MailItem
If TypeName(Item) = "MailItem" Then
Set Msg = Item
If Msg.Subject = "Excel Friday" Then
Dim myMail As Outlook.MailItem
Set myMail = Msg.Reply
myMail.To = "xxxxxx#fakemail.com"
myMail.Display
End If
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
I'd like to forward any email that contains "Excel Friday" in the subject line to another email address.
But in the code you check for the exact match of the subject line:
If Msg.Subject = "Excel Friday" Then
Instead you need to look for a substring. To find the position of a substring in a string, use Instr function.
If Instr(Msg.Subject, "Excel Friday") Then
Also I have noticed that you use the Reply method:
Set myMail = Msg.Reply
Use the Forward method instead:
Set myMail = Msg.Forward
And then use the Send method.
myMail.Recipients.Add "Eugene Astafiev"
myMail.Send
Be aware, the code is based on the ItemAdd event handler. This event is not fired when a large number of items are added to the folder at once (more than 16).
You can do this using a Run a Script rule
Sub ChangeSubjectForward(Item As Outlook.MailItem)
Item.Subject = "Test"
Item.Save
Set olForward = Item.Forward
olForward.Recipients.Add "Jasonfish11#domain.com"
olForward.Send
End Sub
If a vba you can run on all messages in a folder at any time.
Paste into ThisOutlookSession and run
Sub ChangeSubjectThenSend()
Dim olApp As Outlook.Application
Dim aItem As Object
Set olApp = CreateObject("Outlook.Application")
Set mail = olApp.ActiveExplorer.CurrentFolder
For Each aItem In mail.Items
aItem.Subject = "New Subject"
aItem.Save
Set olForward = aItem.Forward
olForward.Recipients.Add "Jasonfish11#domain.com"
olForward.Send
Next aItem
End Sub
source Link