Scan All Incoming Emails Outlook - vba

I have the following code to do something on every email I receive via Outlook in the inbox with a specfic subject. It works but if multiple emails arrive at the same time (ie when Outlook re-queries the server my email address is based off of) it will only run the below code on the most recent one received. Any suggestions?
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
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 InStr(Msg.SentOnBehalfOfName, "name") <> 0 Then
'Do Something
End If
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub

You could run the code on the items in the folder.
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 InStr(Msg.SentOnBehalfOfName, "name") <> 0 Then
'Do Something
' Move Msg to a "Done" folder
' or mark it read or some way
' you can use to not reprocess an item
End If
End If
SkippedItems
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
Sub SkippedItems
dim i as long
Dim skippedMsg As MailItem
dim inboxItems as items
dim inboxItemsCount as long
On Error GoTo ErrorHandlerSkippedItems
set inboxItems = session.GetDefaultFolder(olFolderInbox).Items
inboxItemsCount = inboxItems.count
if inboxItemsCount > 0 then
for i = inboxItemsCount to 1 step -1
If TypeName(inboxItems(i)) = "MailItem" Then
Set skippedMsg = inboxItems(i)
If InStr(skippedMsg.SentOnBehalfOfName, "name") <> 0 Then
'Do Something
' Move SkippedMsg to a "Done" folder
' or mark it read or some way
' you can use to not reprocess an item
set skippedMsg = nothing
End If
End If
Next
End If
ProgramExitSkippedItems:
set skippedMsg = nothing
set inboxItems = nothing
Exit Sub
ErrorHandlerSkippedItems:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExitSkippedItems
End Sub

Related

Items_ItemAdd(ByVal Item As Object) is not processing multiple items that come in at the same time

If only one email is sent at a time then my code works fine, otherwise, if multiple items come in at the same time then only one of the emails is processed and moved. Basically, my code is processing items as they come into outlook. And if the email is received as a distribution list then the email is sent to a sub folder based on the distribution list name and time of day.
Here's my 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")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal cusItem As Object)
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
Dim strEntryID As String
Dim objAddressentry As Outlook.AddressEntry
Dim objRecipient As Outlook.Recipient
Dim objDestFolder As Outlook.MAPIFolder
Dim objRecs As Outlook.Recipients
Dim i As Integer
If TypeName(cusItem) = "MailItem" Then
On Error GoTo ErrorHandler
Set objRecs = cusItem.Recipients
For i = 1 To objRecs.Count
Set objRecipient = objRecs.Item(i)
strEntryID = objRecipient.EntryID
Set objAddressentry = objNS.GetAddressEntryFromID(strEntryID)
If objAddressentry = "amazonselling" And TimeValue(Now()) >= TimeValue("08:00:00 AM") And TimeValue(Now()) <= TimeValue("05:00:00 PM") Then
Set objDestFolder = objNS.GetDefaultFolder(olFolderInbox).Folders("ryule")
cusItem.Move objDestFolder
Exit For
End If
Next
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description & vbCrLf & "Click Ok to continue operations"
Resume ProgramExit
End Sub
Also, if I don't declare and set those variables twice then my code doesn't work as intended. Why is that and how could that be fixed?
The ItemAdd event is not fired when a large number of items are added to the folder at once (more than sixteen). This is a known issue when dealing with the Outlook object model. Instead, I'd suggest considering the NewMailEx event which is fired when a new message arrives in the Inbox and before client rule processing occurs. You can use the Entry ID returned in the EntryIDCollection array to call the NameSpace.GetItemFromID method and process the item.
Anyway, it seems the problem is in your code, try to remove additional declarations from both methods:
Private WithEvents Items As Outlook.Items
Private objNS As Outlook.NameSpace
Private Sub Application_Startup()
Set objNS = Application.GetNamespace("MAPI")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal cusItem As Object)
Dim strEntryID As String
Dim objAddressentry As Outlook.AddressEntry
Dim objRecipient As Outlook.Recipient
Dim objDestFolder As Outlook.MAPIFolder
Dim objRecs As Outlook.Recipients
Dim i As Integer
If TypeName(cusItem) = "MailItem" Then
On Error GoTo ErrorHandler
Set objRecs = cusItem.Recipients
For i = 1 To objRecs.Count
Set objRecipient = objRecs.Item(i)
strEntryID = objRecipient.EntryID
Set objAddressentry = objNS.GetAddressEntryFromID(strEntryID)
If objAddressentry = "amazonselling" And TimeValue(Now()) >= TimeValue("08:00:00 AM") And TimeValue(Now()) <= TimeValue("05:00:00 PM") Then
Set objDestFolder = objNS.GetDefaultFolder(olFolderInbox).Folders("ryule")
cusItem.Move objDestFolder
Exit For
End If
Next
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description & vbCrLf & "Click Ok to continue operations"
Resume ProgramExit
End Sub

Implementing .SentOnBehalfOfName

My code:
Public WithEvents myItem As Outlook.MailItem
Private Sub Application_ItemLoad(ByVal Item As Object)
If Item.Class = olMail Then
Set myItem = Item
End If
End Sub
Private Sub myItem_Open(Cancel As Boolean)
Dim oAccount As Outlook.Explorer
Dim oMail As MailItem
Dim Recip As Outlook.Recipient
Set oAccount = Application.ActiveExplorer
MsgBox (oAccount.CurrentFolder.Store)
If oAccount.CurrentFolder.Store = "account#outlook.com" Then
MsgBox ("CC needs to be added")
Set Recip = myItem.Recipients.Add("cc#cc.cc")
Recip.Type = olCC
Recip.Resolve
Else
MsgBox ("no need to add CC")
End If
End Sub
I would like to add something like myItem.SentOnBehalfOfName = "sent#behalf.com" into my code. Pasting it into my code does not work. I probably have to set something before.
I tried myItem.SentOnBehalfOfName = "sent#behalf.com" but it does not do anything. It does not show any errors.
This tricky SentOnBehalfOfName behaviour is described in previous posts.
Private Sub myItem_Open_SentonBehalf_Test()
Dim oExpl As Explorer
Dim myItem As mailitem
Set oExpl = ActiveExplorer
Set myItem = CreateItem(olMailItem)
' Do not display
If oExpl.CurrentFolder.store = "account#outlook.com" Then
Debug.Print "myItem.SentOnBehalfOfName:" & "x " & myItem.SentOnBehalfOfName & " x"
myItem.SentOnBehalfOfName = "sent#behalf.com"
Debug.Print "myItem.SentOnBehalfOfName:" & "x " & myItem.SentOnBehalfOfName & " x"
' be careful to put this after updating SentOnBehalfOfName
myItem.Display
' Manually display the From field to see the updated entry
Else
Debug.Print "Wrong path."
End If
ExitRoutine:
Set myItem = Nothing
Set oExpl = Nothing
End Sub

How do I PASS a SECOND Variable to run after a new mail is received in Outlook?

Private WithEvents Items As Outlook.Items
Public MyTrueFalse As Boolean
Private Sub Application_Startup()
Dim MyTrueFalse As Boolean 'Redundant?'
MyTrueFalse = True 'Defaults to False'
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, ByVal MyTrueFalse As Boolean)
If MyTrueFalse Then GoTo DoThisAlso 'Example Only'
On Error Goto ErrorHandler
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
' ******************
' do something here
' ******************
End If
DoThisAlso:
MsgBox "MyTrueFalse is: " & MyTrueFalse
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
I am using the code above and its working wonderfully on the NEW EMAIL trigger (THANK YOU - Gautam Mainkar (LINK). However, I am trying to pass a Boolean (True/False) variable along with the Items event trigger.
So I am attempting to set say...MyTrueFalse within the Application_Startup() so it is set ONLY ONCE, and passed whenever Items_ItemAdd is triggered by a new email.
I do not want another sub routine, just pass MyTrueFalse boolean as set in the Application_Startup().
I have tried multiple variations of Public settings and multiple variables on the Items_ItemAdd sub and nothing works. I am hoping someone can help me here. Thanks
Oh Yeah: it resides in ThisOutlookSession
Private WithEvents Items As Outlook.Items
Private MyTrueFalse As Boolean
Private Sub Application_Startup()
MyTrueFalse = True
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)
If MyTrueFalse Then GoTo DoThisAlso 'Example Only'
On Error Goto ErrorHandler
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
' ******************
' do something here
' ******************
End If
DoThisAlso:
MsgBox "MyTrueFalse is: " & MyTrueFalse
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
Tim Williams was right, corrected the code (above) and works great!! Thanks Tim. Mike

Trigger to run a outlook macro

is there a way Outlook automatically runs a macro whenever I get an email that goes to a specific folder in Outlook (just to clarify, the email goes there because I have set up a rule, so instead of going to my inbox it goes to that folder).
I think I would need code that detects whenever my folder receives an new email and then automatically runs the macro.
My code is the following, I execute test, which executes SaveEmailAttachmentsToFolder.
Sub Test()
'Arg 1 = Folder name of folder inside your Inbox 'Arg 2 = File extension, "" is every file 'Arg 3 = Save folder, "C:\Users\Ron\test" or "" ' If you use "" it will create a date/time stamped folder for you in your "Documents" folder ' Note: If you use this "C:\Users\Ron\test" the folder must exist.
SaveEmailAttachmentsToFolder "Dependencia Financiera", "xls", "V:\Dependencia Financiera\Dependencia Financiera\"
End Sub
Sub SaveEmailAttachmentsToFolder(OutlookFolderInInbox As String, _ ExtString As String, DestFolder As String)
Dim ns As NameSpace
Dim Inbox As Folder
Dim SubFolder As Folder
Dim subFolderItems As Items
Dim Atmt As Attachment
Dim FileName As String
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set SubFolder = Inbox.Folders(OutlookFolderInInbox)
Set subFolderItems = SubFolder.Items
If subFolderItems.Count > 0 Then
subFolderItems.Sort "[ReceivedTime]", True
For Each Atmt In subFolderItems(1).Attachments
If LCase(Right(Atmt.FileName, Len(ExtString))) = LCase(ExtString) Then
FileName = DestFolder & Atmt.FileName
Atmt.SaveAsFile FileName
End If
Next Atmt
End If
' Clear memory ThisMacro_exit:
Set SubFolder = Nothing
Set Inbox = Nothing
Set ns = Nothing
Set subFolderItems = Nothing
End Sub
seulberg1 told me to use the follwing code how, should my paste my own code since, it has 2 Subs.
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup() Dim olApp As Outlook.Application
Set olApp = Outlook.Application Set Items = GetNS(olApp).GetDefaultFolder(olFolderInbox).Folders("YourFolderName").Items End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
'Add your code here
ProgramExit: Exit Sub ErrorHandler: MsgBox Err.Number & " - " & Err.Description Resume ProgramExit End Sub
Function GetNS(ByRef app As Outlook.Application) As Outlook.NameSpace Set GetNS = app.GetNamespace("MAPI") End Function
Thanks you in advance !!!
This code (adapted from Jimmy Pena) should do the trick.
It initiates the event listener on Outlook startup and checks the folder "Your Folder Name" for new emails. It then performs a designatable action at the ("Add your code here") section.
Let me know if this helps
Best regards
seulberg1
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Set olApp = Outlook.Application
Set Items = GetNS(olApp).GetDefaultFolder(olFolderInbox).Folders("YourFolderName").Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
**'Add your code here**
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
Function GetNS(ByRef app As Outlook.Application) As Outlook.NameSpace
Set GetNS = app.GetNamespace("MAPI")
End Function

Outlook Add Items quits working - Items_ItemAdd(ByVal Item As Object)

I am watching for new items and then calling a subroutine. In place of the subroutine, I am currently using a message box for testing.
Initially the code worked properly. After running it a few times, it quit working. If I shut down Outlook and reopened it would work again a few more times. I searched many sites for answers.
I tried backing up the project file, deleting it, restoring it. I was able to use this code again for awhile. Now I can't get it to work, regardless of what I do. I have been working on this for two days, but I cannot understand what is going wrong. I'm running Outlook 2010 and my code is posted below.
The code is saved in This Outlook Session:
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).Folders("Access Data Collection Replies").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
' ******************
' This is going to be the code to respond to the dealer and to call procedures. Maybe it can be handled with case statements. Then each event can be identified.
' ******************
MsgBox("It Worked!")
Call AnswerD
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
your code works find, if you are trying to get the msg box to pop then
Move this line code
MsgBox ("It Worked!")
next to
If TypeName(item) = "MailItem" Then
MsgBox ("It Worked!")
here is complete code tested on Outlook 2010
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim olNameSpace As Outlook.NameSpace
Set olNameSpace = Application.GetNamespace("MAPI")
'// ' Default local Inbox (olFolderInbox) & sub ("Folder Name")
Set Items = olNameSpace.GetDefaultFolder(olFolderInbox).Folders("Access Data Collection Replies").Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
If TypeOf item Is Outlook.MailItem Then
MsgBox ("It Worked!")
'AnswerD '<-- un-comment to call subroutine.
End If
End Sub
Private Sub SaveMovePrint(OlMail As Outlook.MailItem)
'On Error GoTo ErrorHandler
' ******************
' Here subroutine
' ******************
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub