Filtering Messages in a Folder

A program sometimes needs to traverse an entire collection in order to take some action on all its members, such as displaying, sending, or copying them. But traversing a large collection like AddressEntries or Messages can take an inordinate amount of time. If you are only interested in certain members of the collection, your code can make efficient use of a filter.

The purpose of filtering is to limit the members of a collection that are presented to a traversing operation such as the Visual Basic For Each construction or a GetFirstGetNext loop. The members are limited based on the values of the properties that you specify for the filter. Only those members that satisfy every filter property you have set are passed to your loop for processing.

In the case of messages in a folder, the hierarchy of objects is as follows:

Session object
    Folder object (Inbox or Outbox)
        Messages collection
            Message object
                Attachments collection
                Fields collection
                Recipients collection
            MessageFilter object
                Fields collection
                    Field object

Suppose, for example, you wish to find all unread messages received before a certain date, and to display the subject of each one. Before your display loop, you can set the message filter to limit the messages your loop sees. To do this, you obtain the Inbox folder, the folder's Messages collection, and the collection's MessageFilter object. Next you set the filter's Unread property to True and its TimeLast property to the desired date. Then your loop deals only with the messages it needs.

This code fragment displays the Subject property of every message in the Inbox received before December 9, 1997 that has never been read:

Dim objSess, objInbox, objMsgColl, objMsgFilter As Object 
Dim objMess As Message ' individual message processed in loop 
On Error GoTo error_olemsg 
Set objSess = CreateObject ( "MAPI.Session" ) 
objSess.Logon ' assume valid session for this example 
Set objInbox = objSess.Inbox 
If objInbox Is Nothing Then 
    MsgBox "Invalid IPM Inbox from session" 
    Exit Function 
End If 
Set objMsgColl = objInbox.Messages ' get Inbox's messages collection 
' ( ... then validate the messages collection before proceeding ... ) 
Set objMsgFilter = objMsgColl.Filter 
' ( ... then validate the message filter before proceeding ... ) 
objMsgFilter.TimeLast = DateValue ( "12/09/97" ) 
objMsgFilter.Unread = True ' filter for unread messages 
' Message filter is now specified; ready for display loop 
For Each objMess in objMsgColl ' performs loop, Sets each objMess 
    MsgBox "Message not read: " & objMess.Subject 
Next ' even easier than objMsgColl.GetFirst and .GetNext 
error_olemsg: 
MsgBox "Error " & Str(Err) & ": " & Error$(Err) 
Exit Function ' so many steps to succeed; just exit on error