Outlook: Elemente durchsuchen mit AdvancedSearch

Die “AdvancedSearch”-Methode der Application-Klasse von Outlook erlaubt das Suchen von Elementen nach bestimmten Kriterien in dem vorgegebenen Ordner – gegebenenfalls sogar mit Unterordnern. An ihr hängen zwei Ereignisse namens “AdvancedSearchComplete” und “AdvancedSearchStopped”, die je nach dem Ausgang der Suche ausgelöst werden. Dieser Artikel zeigt, wie wir eine Suche in Outlook-Elementen per VBA durchführen und wie wir die damit zusammenhängenden Ereignisse verwenden müssen, damit die Suche wie gewünscht funktioniert. Außerdem erfährst Du, wie Du Suchbegriff und Suchbereich definieren musst.

Im Artikel Outlook: Die Application-Klasse (www.vbentwickler.de) haben wir die AdvancedSearch-Methode und die beiden Ereignisse AdvancedSearchComplete und AdvancedSearchStopped zusammen mit den anderen Elementen der Application-Klasse von Outlook vorgestellt. Im vorliegenden Artikel nun gehen wir ins Detail und zeigen, wie Du in Outlook mit diesen Techniken suchen kannst.

Asynchrone Suche

Als Erstes wollen wir uns dabei ansehen, warum die Suche neben der Methode AdvancedSearch überhaupt ein weiteres Ereignis namens AdvancedSearchComplete benötigt.

Der Grund ist einfach: Die Methode AdvancedSearch ist nämlich eine asynchrone Methode, das heißt, sie wird, einmal aufgerufen, unabhängig vom aufrufenden Code ausgeführt. Das heißt, dass der aufrufende Code einfach weiterläuft. Das ist insofern ungünstig, als dass wir nach dem Aufruf von AdvancedSearch nicht einfach abwarten können, bis die Suche abgeschlossen ist und dann das Suchergebnis auswerten können.

Stattdessen haben wir zwei Möglichkeiten:

  • Wir können beispielsweise eine Schleife definieren, die solange läuft, bis die Suche beendet ist. Wie finden wir das heraus? Wir verwenden in der Schleife ein Abbruchkriterium, das erst dann wahr wird, wenn die Suche fertig ist. Das wiederum erkennen wir, indem wir das Ereignis AdvancedSearchComplete implementieren und dort die als Abbruchkriterium verwendete und öffentlich deklarierte Variable einstellen. Danach können wir die Schleife verlassen und das Suchergebnis auswerten.
  • Die zweite Variante verschiebt die Auswertung des Suchergebnisses direkt in die Implementierung des Ereignisses AdvancedSearchComplete. Wir können auch hier auf das Suchergebnis zugreifen, das in diesem Fall über den Parameter der Ereignisprozedur geliefert wird.

Wir schauen uns im Anschluss beide Varianten an.

Ausprobieren der Suchfunktion mit Endlosschleife

Die nächste Frage ist, wo wir die Suchfunktion ausführen wollen. In einer späteren Stufe würden wir diese beispielsweise als Teil einer Anwendung wie einer reinen VB-Anwendung oder auch einer Datenbankanwendung verwenden.

Oder wir rufen die Suchfunktion über einen benutzerdefinierten Ribboneintrag auf. Da das für die reine Vorstellung der AdvancedSearch-Methode etwas zu aufwendig ist, wollen wir diese zunächst gesondert betrachten, indem wir sie einfach aus einem Modul aus dem VBA-Editor von Outlook heraus aufrufen.

Als Erstes benötigen wir eine Boolean-Variable zum Speichern der Information, ob die Suche bereits beendet ist. Diese deklarieren wir wie folgt:

Public bolSearchComplete As Boolean

Außerdem können wir das Ereignis nicht einfach für die Application-Klasse implementieren, sondern wir müssen dafür eine eigene Objektvariable des Typs Outlook.Application deklarieren:

Public WithEvents objApplication As Outlook.Application

Damit können wir nun eine Suche wie in der Prozedur SucheNachMailsMitBestimmtemBetreff programmieren (siehe Listing 1).

Sub SucheNachMailsMitBestimmtemBetreff()
     Dim objSearch As Outlook.Search
     Dim objResults As Outlook.Results
     Dim strScope As String
     Dim strFilter As String
     Dim i As Integer
     Set objApplication = Outlook.Application
     bolSearchComplete = False
     strFilter = "urn:schemas:httpmail:subject = ''Test A''"
     strScope = "Posteingang"
     Set objSearch = objApplication.AdvancedSearch(strScope, strFilter, False, "Test")
     Do While Not bolSearchComplete = True
         DoEvents
     Loop
     Set objResults = objSearch.Results
     For i = 1 To objResults.count
         Debug.Print objResults.Item(i).Subject
     Next i
End Sub

Listing 1: Beispiel für den Aufruf von AdvancedSearch

Die Prozedur deklariert einige wichtige Variablen:

  • objSearch: Variable für das Search-Objekt, mit dem wir die durch AdvancedSearch erstellte Suche referenzieren
  • objResults: Objektvariable des Typs Results zum Referenzieren des Suchergebnisses
  • strScope: String-Variable für die Angabe des zu durchsuchenden Bereichs, hier Posteingang.
  • strFilter: String-Variable für den Ausdruck mit dem Filterkriterium

Die Prozedur referenziert zunächst das Application-Objekt der aktuellen Outlook-Instanz mit objApplication. Dann stellt es bolSearchComplete zunächst auf False ein, falls dieses durch eine vorherige Suche noch den Wert True enthielt.

Dann schreibt es das Filterkriterium, dazu später mehr, in die Variable strFilter und den zu durchsuchenden Bereich in strScope. Schließlich startet die Prozedur mit der Methode AdvancedSearch den Suchvorgang.

Neben strScope und strFilter wird für den dritten Parameter SearchSubFolders noch der Wert False übergeben, weil wir keine Unterordner durchsuchen wollen. Und für den vierten Parameter übergeben wir einen Tag, anhand dessen wir später in der Ereignisprozedur AdvancedSearchComplete herausfinden können, ob das Ereignis auch durch diese Suche ausgelöst wurde – in diesem Fall schlicht Test.

Nun geschieht Folgendes: Die Suche wird gestartet und die Prozedur läuft direkt weiter, da der Aufruf der Suchfunktion wie oben beschrieben asynchron erfolgt.

Damit die aufrufende Prozedur dennoch nach Abschluss der Suche das Suchergebnis untersuchen kann, startet dort nun eine Do While-Schleife, die solange wiederholt wird, bis die Variable bolSearchComplete den Wert True erhält. Und das ist genau dann der Fall, wenn das Ereignis AdvancedSearchComplete ausgelöst wird und wir die folgende Ereignisprozedur dafür implementiert haben:

Private Sub objApplication_AdvancedSearchComplete(_
         ByVal SearchObject As Search)
     Debug.Print "The AdvancedSearchComplete Event fired"
     If SearchObject.Tag = "Test" Then
         bolSearchComplete = True
     End If
End Sub

Damit wir sehen, wann das Ereignis ausgelöst wird, geben wir per Debug.Print eine Meldung im Direktbereich aus. Danach prüfen wir, ob der Aufruf von AdvancedSearch mit dem Wert Test als vierten Parameter das Ereignis ausgelöst hat. Ist das der Fall, stellt die Prozedur bolSearchComplete auf True ein.

Danach kann die aufrufende Prozedur die Do While-Schleife verlassen und das Suchergebnis aus der Eigenschaft Results von objSearch mit der Variablen objResults referenzieren. Dieses durchlaufen wir in einer For…Next-Schleife über die Werte 1 bis zu der mit objResults.Count ermittelten Anzahl der Suchergebnisse.

Für das jeweils mit objResults.Item(i) ermittelte Element der Liste mit den Suchergebnissen geben wir nun den Inhalt der Eigenschaft Subject im Direktbereich aus.

Suchfunktion mit Auswertung in AdvancedSearchComplete

Die zweite Variante soll, wie weiter oben vorgegeben, das Suchergebnis direkt in der durch das Ereignis AdvancedSearchComplete ausgelösten Prozedur analysieren. Die auslösende Prozedur sieht viel schlanker aus und endet bereits mit dem Aufruf von AdvancedSearch:

Sub SucheImPosteingangErgebnisImEreignis()
     Dim objSearch As Outlook.Search
     Dim strScope As String
     Dim strFilter As String
     Set objApplication = Outlook.Application
     strFilter = "urn:schemas:httpmail:subject = ''Test A''"
     strScope = "Posteingang"
     Set objSearch = objApplication.AdvancedSearch(_
         strScope, strFilter, False, "Test")
End Sub

Auch die Variable bolSearchComplete benötigen wir nicht mehr. Die Ereignisprozedur objApplication_AdvancedSearchComplete erhält dafür einige neue Zeilen. Sie deklariert nun die Variable des Typs Outlook.Results und füllt diese mit der Eigenschaft Results des mit dem Parameter SearchObject gelieferten Suchobjekts.

Dieser entspricht dem Rückgabewert der Methode AdvancedSearch aus dem vorherigen Beispiel. Danach prüft die Ereignisprozedur wieder anhand des Tags, ob es sich um das Ereignis der zuvor aufgerufenen Suche handelt. Ist das der Fall, durchläuft die Prozedur die Elemente des Suchergebnisses in einer For…Next-Schleife und gibt den Wert der Eigenschaft Subject der gefundenen Elemente aus:

Private Sub objApplication_AdvancedSearchComplete(_
         ByVal SearchObject As Search)
     Dim objResults As Outlook.Results
     Dim i As Integer
     If SearchObject.Tag = "Test" Then
         Set objResults = SearchObject.Results
         For i = 1 To objResults.count
             Debug.Print objResults.Item(i).Subject
         Next i
     End If
End Sub

Anpassen des zu durchsuchenden Bereichs

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Visual Basic Entwickler:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 200 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar