How to search for appointments in Outlook via VBA/DASL? - vba

I am trying to cycle through specific appointments of the current day and display their details in a msgbox.
I found out about DASL filter queries.
However, it only brings up the first appointment it finds. The FindNext method never steps to the next appointment, even though it came from an example I found on the web doing something very similar.
When I set the same DASL filter directly in Outlook, it shows the appointments as expected.
Here is my current sub:
Sub GetAppointments()
Dim sFilter As String
Dim oExplorer As Outlook.Explorer
Dim oFolder As Outlook.Folder
Dim oAppointment As Outlook.AppointmentItem
sFilter = "#SQL=" & _
"%today(""urn:schemas:calendar:dtstart"")% AND " & _
"%today(""urn:schemas:calendar:dtend"")% AND " & _
"""urn:schemas-microsoft-com:office:office#Keywords"" LIKE '%Meeting%'"
Set oExplorer = Application.ActiveExplorer
Set oFolder = oExplorer.CurrentFolder
Set oAppointment = oFolder.Items.Find(sFilter)
While TypeName(oAppointment) <> "Nothing"
MsgBox oAppointment.Subject & vbCr & _
oAppointment.Start & vbCr & _
oAppointment.End
Set oAppointment = oFolder.Items.FindNext
Wend
End Sub

You need to deal with the same Items collection if you want to get more results:
Dim appItems as Outlook.Items
Set appItems = oFolder.Items
Set oAppointment = appItems.Find(sFilter)
While TypeName(oAppointment) <> "Nothing"
MsgBox oAppointment.Subject & vbCr & _
oAppointment.Start & vbCr & _
oAppointment.End
Set oAppointment = appItems.FindNext
Wend
When you ask the Items property from a folder, a new Items instance is returned so further FindNext calls don't make any sense.
Read more about the Find/FindNext methods in the following articles:
How To: Retrieve Outlook calendar items using Find and FindNext methods
How To: Use Restrict method in Outlook to get calendar items
Also you may want to include recurrence occurrences, in that case you need to set up a corresponding property on the Items collection:
Dim appItems as Outlook.Items
Set appItems = oFolder.Items
appItems.Sort "[Start]"
appItems.IncludeRecurrences = True
Set oAppointment = appItems.Find(sFilter)
While TypeName(oAppointment) <> "Nothing"
MsgBox oAppointment.Subject & vbCr & _
oAppointment.Start & vbCr & _
oAppointment.End
Set oAppointment = appItems.FindNext
Wend
The property returns a Boolean that indicates True if the Items collection should include recurrence patterns.
This property only has an effect if the Items collection contains appointments and is not sorted by any property other than Start in ascending order. The default value is False. Use this property when you want to retrieve all appointments for a given date, where recurring appointments would not normally appear because they are not associated with any specific date. If you need to sort and filter on appointment items that contain recurring appointments, you must do so in this order: sort the items in ascending order, set IncludeRecurrences to True, and then filter the items.

Related

How to extract text from custom flags

I handle a number of emails every day. I flag emails with custom text to track emails and correlate each with the other.
How do I extract emails that are flagged along with custom texts in each flagged email in a folder.
I could manage to follow VBA code available at VBA Express forum:
Sub CountItems()
Dim objMainFolder As Outlook.folder
Dim lItemsCount As Long
'Select a folder
Set objMainFolder = Outlook.Application.Session.PickFolder
If objMainFolder Is Nothing Then
MsgBox "You choose select a valid folder!", vbExclamation + vbOKOnly, "Warning for Pick Folder"
Else
'Initialize the total count
lItemsCount = 0
Call LoopFolders(objMainFolder, lItemsCount)
End If
'Display a message for the total count
MsgBox "There are " & lItemsCount & " items in the " & objMainFolder.Name & " folder Including its subfolders.", vbInformation, "Count Items"
End Sub
Sub LoopFolders(ByVal objCurrentFolder As Outlook.folder, lCurrentItemsCount As Long)
Dim objSubfolder As Outlook.folder
lCurrentItemsCount = lCurrentItemsCount + objCurrentFolder.Items.Count
'Process all folders and subfolders recursively
If objCurrentFolder.Folders.Count Then
For Each objSubfolder In objCurrentFolder.Folders
Call LoopFolders(objSubfolder, lCurrentItemsCount)
Next
End If
End Sub
It displays the count of emails in a folder and its subfolders.
I stumbled across "How do you access custom Follow-Up flag values (“Flag to…”) in Outlook 2016?" which partially solves my problem.
The solution, from what I could understand, pivots around the Search Folder in Outlook mail client and setting custom view by All Mail fields and Follow Up Flag and then setting the condition of the latter to "is not empty". Grouping by "Follow Up Flag" ascending then displays the custom flags in groups for easy reference.
However, that does not solve the problem of listing the custom flag values.
Iterating over all folder in Outlook and searching for specific items is not really a good idea as shown in your sample code:
'Process all folders and subfolders recursively
If objCurrentFolder.Folders.Count Then
For Each objSubfolder In objCurrentFolder.Folders
Call LoopFolders(objSubfolder, lCurrentItemsCount)
Next
End If
Instead, you may consider using the AdvancedSearch method of the Outlook Application class which performs a search based on a specified DAV Searching and Locating (DASL) search string. The AdvancedSearch method and related features in the Outlook object model do not create a Search Folder that will appear in the Outlook user interface. However, you can use the Save method of the Search object that is returned to create a Search Folder that will appear in the Search Folders list in the Outlook user interface.
The key benefits of using the AdvancedSearch method in Outlook are:
The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
Full support for DASL queries (custom properties can be used for searching too). You can read more about this in the Filtering article in MSDN. To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
Finally, you can stop the search process at any moment using the Stop method of the Search class.
Read more about that in the Advanced search in Outlook programmatically: C#, VB.NET article.
Public m_SearchComplete As Boolean
Private Sub Application_AdvancedSearchComplete(ByVal SearchObject As Search)
If SearchObject.Tag = "MySearch" Then
m_SearchComplete = True
End If
End Sub
Sub TestSearchForMultipleFolders()
Dim Scope As String
Dim Filter As String
Dim MySearch As Outlook.Search
Dim MyTable As Outlook.Table
Dim nextRow As Outlook.Row
m_SearchComplete = False
'Establish scope for multiple folders
Scope = "'" & Application.Session.GetDefaultFolder(olFolderInbox).FolderPath
& "','" & Application.Session.GetDefaultFolder(olFolderSentMail).FolderPath & "'"
'Establish filter
If Application.Session.DefaultStore.IsInstantSearchEnabled Then
Filter = Chr(34) & "urn:schemas:httpmail:subject" & Chr(34) & " ci_phrasematch 'Office'"
Else
Filter = Chr(34) & "urn:schemas:httpmail:subject" & Chr(34) & " like '%Office%'"
End If
Set MySearch = Application.AdvancedSearch(Scope, Filter, True, "MySearch")
While m_SearchComplete <> True
DoEvents
Wend
Set MyTable = MySearch.GetTable
Do Until MyTable.EndOfTable
Set nextRow = MyTable.GetNextRow()
Debug.Print nextRow("Subject")
Loop
End Sub
Also you may consider using the Find/FindNext or Restrict methods that allow getting items that correspond to the search filter in a specific folder (per folders). Read more about these methods in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
You can apply .Restrict on FlagRequest to count items with a custom text flag.
Option Explicit
Sub CountCustomFlagItems()
Dim objMainFolder As folder
Dim lItemsCount As Long
Dim customText As String
Dim resFilter As String
Dim uMsg As String
'Select a folder
Set objMainFolder = Session.PickFolder
If objMainFolder Is Nothing Then
' user cancelled
Exit Sub
Else
'Initialize the total count
lItemsCount = 0
customText = "Custom Text Here"
' https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem.flagrequest
resFilter = "[FlagRequest] = " & customText
Debug.Print "resFilter: " & resFilter
Call LoopFolders(objMainFolder, lItemsCount, resFilter)
End If
'Display a message for the total count
uMsg = "There are " & lItemsCount & " " & customText & " items in the " & objMainFolder.Name & _
" folder including subfolders."
Debug.Print uMsg & vbCr
'MsgBox uMsg, vbInformation, "Count Items"
End Sub
Sub LoopFolders(ByVal objCurrentFolder As folder, lCurrentItemsCount As Long, resFilter As String)
Dim objSubfolder As folder
Dim objCurrentFolderItems As Items
Dim resItms As Items
Set objCurrentFolderItems = objCurrentFolder.Items
If objCurrentFolderItems.Count Then
' https://learn.microsoft.com/en-us/office/vba/api/outlook.items.restrict
Set resItms = objCurrentFolderItems.Restrict(resFilter)
If resItms.Count Then
Debug.Print objCurrentFolder & " Items Count: " & objCurrentFolderItems.Count
Debug.Print " Filtered items in the folder " & objCurrentFolder & ": " & resItms.Count
Debug.Print
lCurrentItemsCount = lCurrentItemsCount + resItms.Count
End If
End If
'Process all folders and subfolders recursively
If objCurrentFolder.folders.Count Then
For Each objSubfolder In objCurrentFolder.folders
Call LoopFolders(objSubfolder, lCurrentItemsCount, resFilter)
Next
End If
End Sub

Restrict on Custom-Property Not Working in Outlook Calendar Items

I want to add a custom property to my calendar items (ideally it will contain a unique ID), so that I can use Restrict to collect instances of recurring appointment items. But while I seem to be able to add the property, I cannot find any way to use the Items.Restrict() method to find items containing the property.
I know that I can get a collection of all the items on the calendar and loop every one to find what I want - but that is the current method that I use and it is way to slow.
I looked at dozens of sites and found conflicting answers about whether this is even possible - but Microsoft seems to think it is (see first link), as well as other people (see second link).
I have used the locals window in debug mode and Restrict is definitely not collecting any objects.
I can only assume that I am doing something wrong in the Column section (based on this "The custom properties must be defined in the folder where you are applying the filter. If the custom properties are only defined in the item, the search will fail" - first link) or the view but I cannot figure out what.
I do know that I cannot use a TableView because it will not include recurrence instances (see third link).
https://learn.microsoft.com/en-us/office/vba/outlook/how-to/search-and-filter/filtering-a-custom-field
http://www.outlookcode.com/threads.aspx?forumid=2&messageid=27942
https://learn.microsoft.com/en-us/office/client-developer/outlook/pia/how-to-filter-recurring-appointments-and-search-for-a-string-in-the-subject
Sub AddAndRestrictCustomProperty()
Dim NS As Outlook.NameSpace
Dim dcal As Folder
Dim dCalItmes As Items
Dim objd As Items, objc As Items
Dim item As Outlook.AppointmentItem
Dim upCheck As Outlook.UserProperty
Dim udpCheck As Outlook.UserDefinedProperty
Set NS = Application.GetNamespace("MAPI")
Set dcal = NS.GetDefaultFolder(olFolderCalendar)
Set dCalItems = dcal.Items
Set item = dCalItems.Add(olAppointmentItem)
With item
.Subject = "Placeholder Appt"
.Start = "2/12/2019 4:30PM"
.Body = "nothing"
.MeetingStatus = olMeeting
.Save
End With
'adds custom property
Set upCheck = item.UserProperties.Add("userPropCheck", olText, True, olText)
upCheck.Value = "testing"
Debug.Print item.ItemProperties.item("userPropCheck").Value 'prints "testing"
item.Save
'gets instances of custom property in objd
dCalItems.Sort "[Start]"
dCalItems.IncludeRecurrences = True
Set objd = dCalItems.Restrict("[subject] = Placeholder Appt And [Start] >= '2/11/2019' and [Start] <= '2/13/2019'")
Debug.Print objd(1).ItemProperties.item("userPropCheck").Value 'prints testing
'setColumns seems to not work for custom properties
objd.SetColumns ("userPropCheck, subject, start") 'ERROR: The property "userPropCheck" is unknown error
'Jet Restrict Fails
Set objc = dCalItems.Restrict("[userPropCheck] = " & Chr(34) & "testing" & Chr(34))
Debug.Print objc(1).ItemProperties.item("userPropCheck").Value 'ERROR: object variable or with block variable not set error
'Jet Find Fails
Set objc = dCalItems.Find("[userPropCheck] = " & Chr(34) & "testing" & Chr(34))
Debug.Print objc(1).ItemProperties.item("userPropCheck").Value 'ERROR: object variable or with block variable not set error
'DSAL Restrict Fails
sFilter = "#SQL=" & Chr(34) & "http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/userPropCheck" & Chr(34) & "= 'testing'" ''"#SQL=" & Chr$(34) & "http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/userPropCheck" & Chr(34) & " = 'testing'"
Set objc = dCalItems.Restrict(sFilter)
Debug.Print objc(1).ItemProperties.item("userPropCheck").Value 'ERROR: object variable or with block variable not set error
'DSAL Find Fails
sFilter = "#SQL=" & Chr(34) & "http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/userPropCheck" & Chr(34) & "= 'testing'" ''"#SQL=" & Chr$(34) & "http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/userPropCheck" & Chr(34) & " = 'testing'"
Set objc = dCalItems.Find(sFilter)
Debug.Print objc(1).ItemProperties.item("userPropCheck").Value 'ERROR: object variable or with block variable not set error
'THIS WORKS to filter the actual calendar view
Set objView = Application.ActiveExplorer.CurrentView
objView.Filter = Chr(34) & "http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/userPropCheck" & Chr(34) & "= 'testing'"
objView.Save
objView.Apply
End Sub
As you can see I am fairly lost. I can add a custom property to the item and then restrict on something other than that property to get the item and then print out the custom property, and I can filter the current view on the custom property using the DSAL view.Filter, but using that in the Restrict also does not work.

Restrict Outlook Items to today's date - VBA

I've written some code that scans my default Outlook inbox for emails received today with a specific subject.
I then download the attachment for Outlook items that meet my criteria. I am having trouble designating the Restrict method to pull back items received today.
Here is what I have:
Sub DownloadAttachmentFirstUnreadEmail()
Dim oOlAp As Object, oOlns As Object, oOlInb As Object
Dim oOlItm As Object, oOlAtch As Object
Dim sFilter As String
Dim NewFileName As String
NewFileName = "C:\Temp\" & "CHG_Daily_Extract_" & Format(Date, "MM-DD-YYYY") & ".csv"
'~~> Get Outlook instance
Set oOlAp = GetObject(, "Outlook.application")
Set oOlns = oOlAp.GetNamespace("MAPI")
Set oOlInb = oOlns.GetDefaultFolder(olFolderInbox)
'Declare email item restriction
sFilter = "[ReceivedTime] = '" & Format(Date, "DDDDD HH:NN") & "'"
'Catch
If oOlInb.Items.Restrict(sFilter).Count > 0 Then
'~~> Loop thru today's emails
For Each oOlItm In oOlInb.Items.Restrict(sFilter)
'~> Check if the email subject matches
If oOlItm = "ASG CDAS Daily CHG Report" Then
'~~> Download the attachment
For Each oOlAtch In oOlItm.Attachments
oOlAtch.SaveAsFile NewFileName
Exit For
Next
End If
Exit For
Next
'Display if no emails today
Else: MsgBox "No items"
End If
End Sub
When I run the code, I consistently receive my catch message of "No items".
Please let me know if I am using the Restrict method incorrectly. Thank you so much for the help.
How about the following-
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")%
Or with Attachment
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")% AND " & _
Chr(34) & "urn:schemas:httpmail:hasattachment" & _
Chr(34) & "=1"
Example
Option Explicit
Private Sub Examples()
Dim olNs As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim Msg As String
Dim i As Long
Dim Filter As String
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")%"
Set Items = Inbox.Items.Restrict(Filter)
Msg = Items.Count & " Items in " & Inbox.Name
If MsgBox(Msg, vbYesNo) = vbYes Then
For i = Items.Count To 1 Step -1
Debug.Print Items(i) 'Immediate Window
Next
End If
End Sub
Filtering Items Using a Date-time Comparison MSDN
Outlook Date-time Macros
The date macros listed below return filter strings that compare the value of a given date-time property with a specified date in UTC; SchemaName is any valid date-time property referenced by namespace.
Note Outlook date-time macros can be used only in DASL queries.
Macro Syntax Description
today %today(" SchemaName")% Restricts for items with SchemaName
property value equal to today
More Examples Here

Why do I get Object doesn't support mailitem property SenderEmailAddress?

I want to save an attachment from a specific sender that has a specific file extension in the attachment. I'm having trouble with the If part of my loop. I receive Run-time error 438: Object doesn't support this property or method.
Sub GetAttachments()
Dim ns As NameSpace
Dim folder As Outlook.MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
i = 0
If Inbox.Items.Count = 0 Then
MsgBox "There are no messages in the Inbox.", vbInformation, _
"Nothing Found"
Exit Sub
End If
For Each Item In Inbox.Items
If Item.SenderEmailAddress = "email#domain.com" Then
For Each Atmt In Item.Attachments
' This path must exist! Change folder name as necessary.
If Right(Atmt.FileName, 3) = ".py" Then
FileName = "C:\Users\bill\Desktop\TEST\" & Atmt.FileName
Atmt.SaveAsFile FileName
i = i + 1
End If
Next Atmt
End If
Next Item
If i > 0 Then
MsgBox "I found " & i & " attached files." _
& vbCrLf & "I have saved them into the C:\Users\bill\Desktop\TEST folder." _
& vbCrLf & vbCrLf & "Have a nice day.", vbInformation, "Finished!"
Else
MsgBox "I didn't find any attached files in your mail." , vbInformation, "Finished!"
End If
GetAttachments_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Exit Sub
GetAttachments_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: GetAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume GetAttachments_exit
End Sub
The Folder can contain various types of items. Some of them don't provide the SenderEmailAddress property. Try to check out the item class first (or MessageCLass).
Also you may get a security issue if you automate Outlook from another application. See Outlook "Object Model Guard" Security Issues for Developers.
And don't interate over all items in the folder:
For Each Item In Inbox.Items
If Item.SenderEmailAddress = "email#domain.com" Then
You can use the Find/FindNext or Restrict methods of the Items class instead. Read more about these methods in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
Also you may find the AdvancedSearch method of the Application class helpful. The key benefits of using the AdvancedSearch method in Outlook are:
The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
Full support for DASL queries (custom properties can be used for searching too). You can read more about this in the Filtering article in MSDN. To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
You can stop the search process at any moment using the Stop method of the Search class.
See Advanced search in Outlook programmatically: C#, VB.NET for more information.
See this example
Filter = "[SenderEmailAddress] = 'email#domain.com'"
Set Items = Inbox.Items.Restrict(Filter)
ii = 0
For i = Items.Count To 1 Step -1
Set Item = Items.Item(i)
For Each Atmt In Item.Attachments
' This path must exist! Change folder name as necessary.
If Right(Atmt.FileName, 3) = ".py" Then
FilePath = "C:\Temp\"
FileName = Atmt.FileName
Atmt.SaveAsFile FilePath & FileName
ii = ii + 1
End If
Next Atmt
Next

Macro to move msg to folder when subject contains

I'm working with the code below. It works sometimes. I mean I can run test emails and it does what it supposed to do, but sometimes I get errors: The two errors I have gotten so far are: "Operation Failed. Object could not be found." And "Instant Search Not Enabled on Store." It appears to be random. My question is how can I enhance the code to make sure it runs without getting these errors??? I have the code programmed to fire every minute. Thanks
Option Explicit
Sub MoveItems()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolderWA As Outlook.Folder
Dim myDestFolderOR As Outlook.Folder
Dim myDestFolderID As Outlook.Folder
Dim myItems As Outlook.Items
Dim myItemWA As Object
Dim myItemOR As Object
Dim myItemID As Object
Dim strFilter1 As String
Dim strFilter2 As String
Dim strFilter3 As String
Dim RestrictItems As Outlook.Items
Dim Mail As Outlook.MailItem
On Error GoTo ErrHandler
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.Folders("Subpayables Invoices").Folders("Inbox")
Set myItems = myInbox.Items
Set myDestFolderWA = myInbox.Folders("WA")
Set myDestFolderOR = myInbox.Folders("OR")
Set myDestFolderID = myInbox.Folders("ID")
strFilter1 = "#SQL=" & Chr(34) _
& "urn:schemas:httpmail:subject" & Chr(34) _
& " ci_phrasematch 'washington'"
strFilter2 = "#SQL=" & Chr(34) _
& "urn:schemas:httpmail:subject" & Chr(34) _
& " ci_phrasematch 'oregon'"
strFilter3 = "#SQL=" & Chr(34) _
& "urn:schemas:httpmail:subject" & Chr(34) _
& " ci_phrasematch 'idaho'"
Set RestrictItems = myItems.Restrict(strFilter1)
Set myItemWA = RestrictItems.GetFirst
Set RestrictItems = myItems.Restrict(strFilter2)
Set myItemOR = RestrictItems.GetFirst
Set RestrictItems = myItems.Restrict(strFilter3)
Set myItemID = RestrictItems.GetFirst
While TypeName(myItemWA) <> "Nothing"
myItemWA.Move myDestFolderWA
Set myItemWA = RestrictItems.GetNext
Wend
While TypeName(myItemOR) <> "Nothing"
myItemOR.Move myDestFolderOR
Set myItemOR = RestrictItems.GetNext
Wend
While TypeName(myItemID) <> "Nothing"
myItemID.Move myDestFolderID
Set myItemID = RestrictItems.GetNext
Wend
Exit Sub
ErrHandler:
MsgBox Err & ": " & Error(Err)
End Sub
I am not getting any errors, but it is not doing what I want it to do
Did you try to debug the code and see what happens there? Do you get any errors?
The ItemAdd event of the Items class does not run when a large number of items are added to the folder at once (more than 16). This is a well-known issue. Is that the case?
You may consider handling the NewMailEx event of the Application class which is fired when a new item is received in the Inbox. Here is what MSDN states:
The NewMailEx event fires 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. Use this method with caution to minimize the impact on Outlook performance. However, depending on the setup on the client computer, after a new message arrives in the Inbox, processes like spam filtering and client rules that move the new message from the Inbox to another folder can occur asynchronously. You should not assume that after these events fire, you will always get a one-item increase in the number of items in the Inbox.