Using the Search Object
Microsoft® Outlook® 2002
Summary: Microsoft Outlook 2002 incorporates a powerful search mechanism that allows users to create complex queries and retrieve many different types of data. This functionality, along with the ability to store and manipulate the results of a search, makes Outlook a very powerful and effective tool when working in the collaborative environment. This article provides a conceptual overview and code samples of the Outlook 2002 search functionality. (7 printed pages)
Microsoft Outlook has always been your all-in-one solution for collecting, organizing, scheduling, and sorting information of all different types. Over the course of a day a typical user will send, receive, and sort incoming and outgoing mail, organize tasks, write notes, and schedule meetings using the calendar. All of this information is stored in separate folders as separate items and quite possibly in separate locations. Unless you continually empty your Deleted Items folder or keep track of what's in your Inbox, you could be faced with a difficult challenge. While Outlook is a great tool for coordinating this information, it has always lacked the important ability to search.
Outlook 2002 incorporates a powerful search tool that allows you to conduct powerful and effective searches on many different types of data. The Search object uses a SQL-like syntax that allows you to build and execute complex queries on various different types of data. New properties and events allow you to customize your searches and ensure the integrity of your data.
In addition to the new search functionality, Outlook 2002 features a Results collection that allows you to programmatically search through the results of your query.
This article discusses the Microsoft Outlook search functionality and provides detailed examples of:
- Creating custom searches
- Trapping and retrieving search results
- Viewing results
At the heart of every search is an effective query. In Outlook 2002, the query takes the form of a SQL-like text string that combines the flexibility of creating efficient custom searches with the power to return fast, complete results. The query string forms the Filter argument of the Search object's AdvancedSearch method.
You use the AdvancedSearch method to execute a search. The AdvancedSearch method takes up to four arguments that allow you to customize the search to meet your needs. They are as follows:
Table 1. AdvancedSearch method arguments
|Scope||String||The scope of the search. For example, the name of the folder in which the search will be conducted.|
|Filter||Variant||The DASL string that defines the logic of the search. This Variant defines the constraints of the search based on the internal schema of the mail server. This argument is optional.|
|SearchSubFolders||Variant||Determines if the search will include any subfolders of the original search scope. This argument is only available for searches conducted against a Microsoft Exchange server or PST folder hierarchy. If True, the search will include any subfolders of the original scope. This argument is optional.|
|Tag||String||A name given as an identifier of the search. The Tag argument is used to identify a search after it has finished or has been stopped. This argument is optional.|
The number of arguments you decide to use depends on the complexity of the search you are trying to create. For example, the following code sample uses only the Scope argument to return all items in a given folder.
Sample 1. A simple search
Sub SimpleSearch(ByVal strScope As String) 'Conducts a simple search. Dim objSch As Search Set objSch = Application.AdvancedSearch(Scope:=strScope) End Sub
Use the following statement to call this subroutine:
In this case, "FolderName" is the name of the folder in which to search.
To create more complex searches, use the Filter argument to constrain the scope of your search.
The Filter argument uses SQL-like logic that allows you to query the schema of your mail server and return a more refined set of data. The syntax is similar to a SQL SELECT statement, but omits everything before the WHERE clause.
The following code sample uses the Filter property to return all MailItem objects that have been forwarded in the user's Inbox.
Sample 2. Using the Filter argument
Sub SearchForForwards(ByVal strF As String, ByVal strScope As String, _ ByVal strTag As String) 'List all forwards in the Inbox. Dim objSch As Search 'Return all MailItem objects in the Inbox with subject lines like "FW:" 'Create the Search object by calling the AdvancedSearch method. Set objSch = Application.AdvancedSearch(Scope:=strScope, _ Filter:=strF, Tag:=strTag) End Sub
Use the following code to call this subroutine:
SearchForForwards strF:="urn:schemas:mailheader:subject" _ & " LIKE 'FW:%'", strScope:="Inbox", _ strTag:="AllForwards"
In this example, all MailItem objects in the Inbox with a subject line containing the prefix "FW:" will be returned. This is accomplished by using the SQL LIKE operator to filter all MailItem objects with a mailheader subject line that is similar to "FW:". This example also uses the Tag argument. The Tag argument is useful when you are executing several searches simultaneously. When a given search completes execution—either by being stopped or by completing the task—you can return the Tag value to determine which search has completed.
The AdvancedSearch method is also very flexible. You can create multiple searches simultaneously simply by executing the AdvancedSearch method in successive lines of code. The following code sample conducts two searches simultaneously.
Sample 3. Conducting multiple searches simultaneously
Sub MultipleSearches(ByVal strF As String, ByVal strF2 As String, _ ByVal strS As String, ByVal strTag As String, _ ByVal strTag2 As String) 'Conducts multiple searches simultaneously. Dim objSch As Search Dim objSch2 As Search 'Search 1. Set objSch = Application.AdvancedSearch(Scope:=strS, _ Filter:=strF, Tag:=strTag) 'Search 2. Set objSch2 = Application.AdvancedSearch(Scope:=strS, _ Filter:=strF2, Tag:=strTag2) End Sub
Use the following code to call this subroutine:
MultipleSearches strF:="urn:schemas:httpmail:fromname" _ & " LIKE 'Paul%'", _ strF2:="urn:schemas:mailheader:subject" _ & " LIKE 'FW:%'", strS:="Inbox", _ strTag:="FromName", _ strTag2:="FindAllForwards"
In the above example, two searches are executed simultaneously to return two results sets that represent all forwards in the user's Inbox from "Paul." Both searches use the Tag argument in order to keep track of each process. As we will see in the next section, events are used to signal the completion of a search so that effective results may be captured.
You can also search through multiple folders simultaneously by specifying the scope of the search as a comma-delimited string of folder names. This is an effective way of broadening the scope of your search with increasing the returned data set or creating simultaneous searches.
The following code sample searches for all messages with a given subject line in the user's Inbox, Calendar and Tasks folders.
Sample 4. Searching in multiple folders
Sub SearchForSubject(ByVal strFilter As String, ByVal strScope As String) 'Search for all items with a certain subject 'in multiple folders. Dim objSch As Search Set objSch = Application.AdvancedSearch(strScope, strFilter) End Sub
Use the following code to call the subroutine:
SearchForSubject strFilter:= _ "urn:schemas:httpmail:subject = 'Fiftieth Birthday Party'", _ strScope:="'Inbox', 'Calendar', 'Tasks'"
The AdvancedSearch method is an effective tool for building powerful search queries. But where are the results of the search stored and how do we know if a search has completed? As we will see in the next section, events are used to signal the completion of a search so that effective results may be captured.
Once you've created your query and executed the AdvancedSearch method, you need to collect and view the results of your search. Since complex searches take time to execute, you need to ensure that the search has completed before obtaining the results of the search. This is very important—otherwise, you may return an incomplete data set or no data set at all.
This is accomplished first by using one of two events, which are members of the Application object, to signal that your search has concluded.
Table 2. Search-related application level events
|AdvancedSearchComplete||This event fires when a search has completed successfully.|
|AdvancedSearchStopped||This event fires when a search has been halted manually using the Search object's Stop method.|
Use the AdvancedSearchComplete event to signal that your search has completed successfully. The following example uses an event procedure to signal that a search has completed. The Tag property of the Search object, which corresponds to the Tag argument of the AdvancedSearch method, is displayed to signal which search has concluded.
Sample 5. Using the AdvancedSearchComplete event
Private Sub Application_AdvancedSearchComplete(ByVal _ SearchObject As Search) 'Signals the end of a search. Dim objRsts As Results Set objRsts = SearchObject.Results 'Display message to user. Debug.Print "The search " & SearchObject.Tag & _ " has completed. It contains " _ & objRsts.Count & " items." & vbCr End Sub
If the search is successful, the results, along with the name of the search and the number of items returned, are displayed in the Immediate window.
Use the AdvancedSearchStopped event to signal that a search has been stopped manually. This event code should be included to trap searches that are halted by the Search object's Stop method.
Once the AdvancedSearchComplete or AdvancedSearchStopped event has fired, signaling that a search has completed or has been halted, use the Results property of the Search object to capture the results of the search. The Results property of the Search object returns the Results object. The Results object contains the output of the search as well as the methods used to view the data set. For example, the Results object contains the GetFirst, GetNext, GetPrevious and GetLast methods that allow you to cycle through the results. The Results object also contains the Sort method that allows you to sort data.
The following example uses the AdvancedSearchComplete event to capture the results of the search in a Results object. Once the search has completed the results object is created and the data is displayed in the Immediate window.
Sample 6. Using the Results object
Private Sub Application_AdvancedSearchComplete(ByVal _ SearchObject As Search) 'Signals the end of a search and displays the 'results in the Immediate window. Dim objRsts As Results Dim objItem As Object Set objRsts = SearchObject.Results 'Display message to user. Debug.Print "The search " & SearchObject.Tag & _ " has completed. It contains " _ & objRsts.Count & " items." & vbCr 'Cycle through each item of results. Set objItem = objRsts.GetFirst If Not objItem Is Nothing Then Do 'Print each item in Immediate window. Debug.Print objItem 'Get next item. Set objItem = objRsts.GetNext Loop Until objItem Is Nothing Else If objItem Is Nothing Then Debug.Print "The results set is empty." End If End If End Sub
In the above example, the GetFirst method is called to return the first item in the collection. If this item contains data, or the search was successful, then the data is printed in the Immediate window. The GetNext method is called to return the next item in the collection. If the results object contains no data, a message is displayed in the Immediate window.
The Search object and its accompanying methods and events provide an extremely powerful and flexible tool for searching and retrieving information. Users can harness the powerful logic of SQL along with the ease and flexibility of Visual Basic for Applications (VBA) to create powerful searches and return concise, accurate results sets. Along with the Results object, which allows you to store and display the results set, the Search object provides the functionality to retrieve and organize your most important information.