Restrict cannot be used with the Categories property.
Below is the help topic for the Restrict method from Outlook VBA help file:
Restrict Method
See AlsoApplies ToExampleSpecifics
Applies a filter to the Items collection, returning a new collection
containing all of the items from the original that match the filter. This
method is an alternative to using the Find method or FindNext method to
iterate over specific items within a collection. The Find or FindNext
methods are faster than filtering if there are a small number of items. The
Restrict method is significantly faster if there is a large number of items
in the collection, especially if only a few items in a large collection are
expected to be found.
Note If you are using user-defined fields as part of a Find or Restrict
clause, the user-defined fields must exist in the folder. Otherwise the code
will generate an error stating that the field is unknown. You can add a
field to a folder by displaying the Field Chooser and clicking New.
expression.Restrict(Filter)
expression Required. An expression that returns an Items object.
Filter Required String. A filter string expression to be applied. For
details, see the Find method.
Remarks
This method cannot be used and will cause an error with the following
properties:
Body
Categories
Children
Class
Companies
CompanyLastFirstNoSpace
CompanyLastFirstSpaceOnly
ContactNames
Contacts
ConversationIndex
DLName
Email1EntryID
Email2EntryID
Email3EntryID
EntryID
HTMLBody
IsOnlineMeeting
LastFirstAndSuffix
LastFirstNoSpace
AutoResolvedWinner
BodyFormat
InternetCodePage
Permission
LastFirstNoSpaceCompany
LastFirstSpaceOnly
LastFirstSpaceOnlyCompany
LastFirstNoSpaceAndSuffix
MemberCount
NetMeetingAlias
NetMeetingAutoStart
NetMeetingOrganizerAlias
NetMeetingServer
NetMeetingType
RecurrenceState
ReplyRecipients
ReceivedByEntryID
RecevedOnBehalfOfEntryID
ResponseState
Saved
Sent
Submitted
VotingOptions
DownloadState
IsConflict
MeetingWorkspaceURL
Creating Filters for the Find and Restrict Methods
The syntax for the filter varies depending on the type of field you are
filtering on.
String (for Text fields)
When searching Text fields, you can use either an apostrophe ('), or double
quotation marks (""), to delimit the values that are part of the filter. For
example, all of the following lines function correctly when the field is of
type String:
sFilter = "[CompanyName] = 'Microsoft'"
sFilter = "[CompanyName] = ""Microsoft"""
sFilter = "[CompanyName] = " & Chr(34) & "Microsoft" & Chr(34)
Note If the search string contains a single quote character, escape the
single quote character in the string with another single quote character.
For example,
sFilter = "[Subject] = 'Can''t'"
Similarly, if the search string contains a double quote character, escape
the double quote character in the string with another double quote
character.
Date
Although dates and times are typically stored with a Date format, the Find
and Restrict methods require that the date and time be converted to a string
representation. To make sure that the date is formatted as Microsoft Outlook
expects, use the Format function. The following example creates a filter to
find all contacts that have been modified after January 15, 1999 at 3:30
P.M.
sFilter = "[LastModificationTime] > '" & Format("1/15/99 3:30pm", "ddddd
h:nn AMPM") & "'"
Boolean Operators
Boolean operators, TRUE/FALSE, YES/NO, ON/OFF, and so on, should not be
converted to a string. For example, to determine whether journaling is
enabled for contacts, you can use this filter:
sFilter = "[Journal] = True"
Note If you use quotation marks as delimiters with Boolean fields, then an
empty string will find items whose fields are False and all non-empty
strings will find items whose fields are True.
Keywords (or Categories)
The Categories field is of type keywords, which is designed to hold multiple
values. When accessing it programmatically, the Categories field behaves
like a Text field, and the string must match exactly. Values in the text
string are separated by a comma and a space. This typically means that you
cannot use the Find and Restrict methods on a keywords field if it contains
more than one value. For example, if you have one contact in the Business
category and one contact in the Business and Social categories, you cannot
easily use the Find and Restrict methods to retrieve all items that are in
the Business category. Instead, you can loop through all contacts in the
folder and use the Instr function to test whether the string "Business" is
contained within the entire keywords field.
Note A possible exception is if you limit the Categories field to two, or a
low number of values. Then you can use the Find and Restrict methods with
the OR logical operator to retrieve all Business contacts. For example (in
pseudocode): "Business" OR "Business, Personal" OR "Personal, Business."
Category strings are not case sensitive.
Integer
You can search for Integer fields with, or without quotation marks as
delimiters. The following filters will find contacts that were created using
Outlook 2000:
sFilter = "[OutlookInternalVersion] = 92711"
sFilter = "[OutlookInternalVersion] = '92711'"
Using Variables as Part of the Filter
As the Restrict method example illustrates, you can use values from
variables as part of the filter. The following Microsoft Visual Basic
Scripting Edition (VBScript) code sample illustrates syntax that uses
variables as part of the filter.
sFullName = "Dan Wilson"
' This approach uses Chr(34) to delimit the value.
sFilter = "[FullName] = " & Chr(34) & sFullName & Chr(34)
' This approach uses double quotation marks to delimit the value.
sFilter = "[FullName] = """ & sFullName & """"
Using Logical Operators as Part of the Filter
Logical operators that are allowed are AND, OR, and NOT. The following are
variations of the clause for the Restrict method so you can specify multiple
criteria.
OR: The following code returns all contact items that have either Business
or Personal as their category.
sFilter = "[Categories] = 'Personal' Or [Categories] = 'Business'"
AND: The following code retrieves all personal contacts who work at
Microsoft.
sFilter = "[Categories] = 'Personal' And [CompanyName] = 'Microsoft'"
NOT: The following code retrieves all personal contacts who don't work at
Microsoft.
sFilter = "[Categories] = 'Personal' And Not([CompanyName] = 'Microsoft')"
Additional Notes
If you are trying to use the Find or Restrict methods with user-defined
fields, the fields must be defined in the folder, otherwise an error will
occur. There is no way to perform a "contains" operation. For example, you
cannot use Find or Restrict to search for items that have a particular word
in the Subject field. Instead, you can use the AdvancedSearch method, or you
can loop through all of the items in the folder and use the InStr function
to perform a search within a field. You can use the Find and Restrict
methods to search for items that begin within a certain range of characters.
For example, to search for all contacts with a last name beginning with the
letter M, use this filter:
sFilter = "[LastName] > 'LZZZ' And [LastName] < 'N'"
Example
This Visual Basic for Applications (VBA) example uses the Restrict method to
get all Inbox items of Business category and moves them to the Business
folder. To run this example, create or make sure a subfolder called
'Business' exists under Inbox.
Sub MoveItems()
Dim myOlApp As Outlook.Application
Dim myNamespace As Outlook.NameSpace
Dim myFolder As Outlook.MAPIFolder
Dim myItems As Outlook.Items
Dim myRestrictItems As Outlook.Items
Dim myItem As Outlook.MailItem
Set myOlApp = CreateObject("Outlook.Application")
Set myNamespace = myOlApp.GetNamespace("MAPI")
Set myFolder = _
myNamespace.GetDefaultFolder(olFolderInbox)
Set myItems = myFolder.Items
Set myRestrictItems = myItems.Restrict("[Categories] = 'Business'")
For i = myRestrictItems.Count To 1 Step -1
myRestrictItems(i).Move myFolder.Folders("Business")
Next
End Sub
If you use VBScript in an Outlook form, you do not create the Application
object, and you cannot use named constants. This example shows how to
perform the same task using VBScript.
Sub CommandButton1_Click()
Set myNameSpace = Application.GetNameSpace("MAPI")
Set myFolder = myNameSpace.GetDefaultFolder(6)
Set myItems = myFolder.Items
Set myRestrictItems = myItems.Restrict _ ("[Categories] = 'Business'")
For i = myRestrictItems.Count To 1 Step -1
myRestrictItems(i).Move myFolder.Folders("Business")
Next
End Sub
This Visual Basic for Applications example uses the Restrict method to
apply a filter to contact items based on the item's LastModificationTime
property.
Public Sub ContactDateCheck()
Dim myOlApp As Outlook.Application
Dim myNamespace As Outlook.NameSpace
Dim myContacts As Outlook.Items
Dim myItems As Outlook.Items
Dim myItem As Object
Set myOlApp = CreateObject("Outlook.Application")
Set myNamespace = myOlApp.GetNamespace("MAPI")
Set myContacts = myNamespace.GetDefaultFolder(olFolderContacts).Items
Set myItems = myContacts.Restrict("[LastModificationTime] >
'01/1/2003'")
For Each myItem In myItems
If (myItem.Class = olContact) Then
MsgBox myItem.FullName & ": " & myItem.LastModificationTime
End If
Next
End Sub
The following Visual Basic for Applications example is the same as the
example above, except that it demonstrates the use of a variable in the
filter.
Public Sub ContactDateCheck2()
Dim myOlApp As Outlook.Application
Dim myNamespace As Outlook.NameSpace
Dim myContacts As Outlook.Items
Dim myItem As Outlook.Object
Dim DateStart As Date
Dim DateToCheck As String
Dim myRestrictItems As Outlook.Items
Set myOlApp = CreateObject("Outlook.Application")
Set myNameSpace = myOlApp.GetNamespace("MAPI")
Set myContacts = myNameSpace.GetDefaultFolder(olFolderContacts).Items
DateStart = #01/1/2003#
DateToCheck = "[LastModificationTime] >= """ & DateStart & """"
Set myRestrictItems = myContacts.Restrict(DateToCheck)
For Each myItem In myRestrictItems
If (myItem.Class = olContact) Then
MsgBox myItem.FullName & ": " & myItem.LastModificationTime
End If
Next
End Sub
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
You must keep the COM object that raises events referenced at all times.
In
your case you do not have a global/class variable to hold the Items
collection, as soon as GC releases it, no events will be fired:
Thanks a lot, keeping the right things in memory enables a stable
recognition
of emails. Obviously, also a lot more than 15 new incoming emails
seems to
be no problem for the firing Outlook 2007 component.
Anyhow, I added a button to parse unread messages. With
inBoxItems.Restrict("[Unread] = true"), I can filter unread messages.
How can I exclude messages with Outlook 2007's "Red Category"?
inBoxItems.Restrict("[Unread] = true And Not([Categories] = 'Red
Category')")
and others do not work, I get an COM Exception.
Thanks,
Thomas.