Kundenkommunikation per E-Mail verwalten, Teil 1

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Wenn Sie den E-Mail-Verkehr mit Ihren Kunden im Griff haben wollen, kopieren Sie einfach alle betroffenen E-Mails in Ihre Kundendatenbank. Dort landen diese in einer Tabelle, deren Datensätze Sie den Kunden zuordnen können. Vor dem Zuordnen müssen Sie jedoch noch festlegen, welche E-Mails aus welchen Ordnern importiert werden sollen. Dieser Beitrag zeigt, wie Sie den Zugriff auf Outlook und den Import der E-Mails automatisieren.

Bevor Sie eine E-Mail überhaupt einem Kunden in Ihrer Datenbank zuordnen können, müssen Sie diese erstmal lesen und gegebenenfalls die wichtigsten Daten der E-Mail in der Datenbank speichern.

Dies erledigen Sie mit den in diesem Beitrag vorgestellten Techniken. Dabei sind folgende Schritte nötig:

  • Definieren der Ordner, deren E-Mails eingelesen werden sollen, und festlegen, welche davon Ausgangs- und welche Eingangsordner sind
  • Angabe der eigenen E-Mail-Adressen, um nur gezielt adressierte E-Mails zu importieren
  • Angabe der E-Mail-Adressen der Kunden, deren E-Mails berücksichtigt werden sollen
  • Markieren der importierten E-Mails in Outlook, damit diese als eingelesen erkannt und nicht nochmals eingelesen werden
  • Zuordnen der eingelesenen E-Mails zu den Kunden in der Kundentabelle
  • Aufbauen einer hierarchischen Struktur aus E-Mails und den passenden Antworten
  • Anzeige dieser E-Mail-Hierarchie im TreeView-Steuerelement

Eingangs- und Ausgangsordner festlegen

Der erste Schritt dient dazu, die zu berücksichtigenden Ordner von Outlook zu ermitteln. Normalerweise verwendet man nur einen Posteingang und einen Ordner, in dem die gesendeten Objekte landen.

Gegebenenfalls haben Sie aber mehrere E-Mail-Adressen eingerichtet oder filtern E-Mails gleich nach dem Eingang oder Ausgang mit entsprechenden Regeln in andere Ordner. Daher erstellen wir gleich zu Beginn eine Tabelle, welche die zu durchsuchenden Ordner speichert, und zwei Formulare, mit denen Sie die gewünschten Outlook-Ordner festlegen können – ein einfaches und eines mit der Darstellung der zu prüfenden Ordner als TreeView.

Die Tabelle heißt tblMailordner und enthält die folgenden drei Felder:

  • MailordnerID: Primärschlüsselfeld
  • Mailordner: Pfad des Ordners

Mit einigen Werten sieht diese Tabelle etwa wie in Bild 1 aus.

pic002.png

Bild 1: Tabelle zum Speichern der Outlook-Ordner

Ordner ermitteln

Wie füllen Sie diese Tabelle nun mit den Outlook-Ordnern Die einfachste Methode ist, einfach den zur Auswahl von Outlook-Ordnern vorgesehenen Dialog zu verwenden. Nehmen wir an, Sie verwenden ein Formular namens frmMailordner, das die in der Tabelle tblMailordner enthaltenen Datensätze in einem Listenfeld namens lstMailordner anzeigt. Dann können Sie diesem Formular eine Schaltfläche namens cmdHinzufuegen zuweisen, welche die Ereignisprozedur aus Bild 2 öffnet.

Listing 1: Hinzufügen eines Mailordners zur Tabelle tblMailordner

Private Sub cmdHinzufuegen_Click()
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objFolder As Outlook.Folder
    Dim db As DAO.Database
    Set db = CurrentDb
    Set objOutlook = New Outlook.Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objFolder = objNamespace.PickFolder
    If Not objFolder Is Nothing Then
        db.Execute "INSERT INTO tblMailordner(Mailordner) VALUES(''" _
            & objFolder.FolderPath & "'')", dbFailOnError
        Me!lstMailordner.Requery
    End If
End Sub

pic001.png

Bild 2: Auswahl von Outlook-Ordnern mit dem dafür vorgesehenen Dialog

Damit wählen Sie einen der Ordner aus und klicken dann auf die Schaltfläche OK. Die Prozedur prüft, ob ein Ordner ausgewählt wurde, und schreibt dann den Wert der Eigenschaft FolderPath in die Tabelle tblMailordner. Die dortigen Ordner werden unmittelbar nach dem Hinzufügen im Listenfeld angezeigt.

Dies ist die einfache Variante und verdeutlicht die grundlegende Technik. Für etwas mehr Komfort möchten Sie aber vielleicht direkt die Struktur der Outlook-Ordner in einem TreeView innerhalb der Datenbank abbilden und dort mit geeigneten Kontrollkästchen die zu berücksichtigenden Ordner markieren.

Outlook-Ordner-Baum

Dazu legen Sie zunächst ein neues Formular namens frmMailordnerTree an und fügen diesem ein TreeView-Steuerelement hinzu. Nennen Sie das Steuerelement ctlMailordner und fügen Sie dem Formular eine Ereignisprozedur für das Ereignis Beim Laden hinzu.

Diese Prozedur setzt die grundlegenden Einstellungen des TreeView-Steuerelements und ruft die Prozedur zum Füllen auf. Im Formularmodul benötigen Sie auf jeden Fall eine Objektvariable für das TreeView-Steuerelement, das mit dem Schlüsselwort WithEvents ausgestattet wird, damit Sie auch auf dessen Ereignisse reagieren können:

Dim WithEvents objMailordner As MSComctlLib.TreeView

Die Prozedur, die beim Laden des Formulars ausgelöst wird, finden Sie in Listing 2. Sie weist zunächst der Objektvariablen objMailordner einen Verweis auf das TreeView-Steuerelement zu.

Listing 2: Ereignisprozedur beim Laden des Formulars

Private Sub Form_Load()
    Set objMailordner = Me!ctlMailordner.Object
    With objMailordner
        .Checkboxes = True
        .Font.name = "Calibri"
        .Font.Size = 9
        .LineStyle = tvwRootLines
    End With
    MailordnerEinlesen
End Sub

Danach stellt sie einige Eigenschaften für das TreeView-Steuerelement ein, was eine Einstellung über den Eigenschaften-Dialog dieses Steuerelements erübrigt. Dabei werden die Kontrollkästchen aktiviert, die Schriftart angepasst und die Root-Linien für die Root-Elemente eingeblendet. Die letzte Anweisung ruft die Prozedur MailordnerEinlesen auf, nach deren Abarbeitung das Formular wie in Bild 3 aussieht.

pic003.png

Bild 3: Outlook-Ordner per TreeView auswählen

Diese Prozedur finden Sie in Listing 3. Für die Execute-Anweisung gleich zu Beginn, die den Wert eines Feldes namens Aktiv der Tabelle tblMailordner auf False einstellt, sind einige erklärende Worte nötig: Das TreeView-Steuerelement soll alle Outlook-Ordner, die standardmäßig Mail-Elemente enthalten, hierarchisch auflisten.

Listing 3: Einlesen der Mailordner und Anhaken der bereits in der Tabelle tblMailordner eingetragenen Ordner

Public Sub MailordnerEinlesen()
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objFolder As Outlook.Folder
    Dim objNode As MSComctlLib.Node
    Dim db As DAO.Database
    Dim rstMailordner As DAO.Recordset
    Set db = CurrentDb
    db.Execute "UPDATE tblMailordner SET Aktiv = FALSE", dbFailOnError
    Set objOutlook = New Outlook.Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    objMailordner.Nodes.Clear
    Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
    Set objNode = NodeAnlegen(db, objFolder, "")
    MailordnerEinlesen_Rek db, objFolder, objNode
    Set objFolder = objNamespace.GetDefaultFolder(olFolderSentMail)
    Set objNode = NodeAnlegen(db, objFolder, "")
    MailordnerEinlesen_Rek db, objFolder, objNode
    Set rstMailordner = db.OpenRecordset("SELECT * FROM tblMailordner WHERE Aktiv = FALSE", _
        dbOpenDynaset)
    Do While Not rstMailordner.EOF
         If MsgBox("Der Mailordner ''" & rstMailordner!Mailordner _
                 & "'' ist nicht mehr in Outlook vorhanden." & vbCrLf & vbCrLf _
                & "Ordner auch aus der Datenbank entfernen", vbYesNo + vbExclamation, _
                "Fehlender Mailordner") = vbYes Then
            db.Execute "DELETE FROM tblMailordner WHERE MailordnerID = " _
                & rstMailordner!MailordnerID, dbFailOnError
        End If
        rstMailordner.MoveNext
    Loop
End Sub

Die dabei angezeigten Kontrollkästchen sollen aktiviert werden, wenn einer der eingelesenen Ordner bereits in der Tabelle tblMailordner enthalten ist. Nun kann es aber passieren, dass der Benutzer einen Mailordner auswählt, die Anwendung schließt, dann einen dieser Ordner in Outlook löscht und erneut das Formular mit dem TreeView-Steuerelement öffnet.

Dann gäbe es einen Mailordner in der Tabelle tblMailordner, der aber nicht mehr in Outlook vorhanden und dementsprechend und auch nicht mehr im TreeView-Steuerelement angezeigt wird. Um dies zu prüfen und den Benutzer gegebenenfalls auf einen solchen Ordner hinzuweisen, wird der Wert des Feldes Aktiv der Tabelle tblMailordner vor dem Füllen des TreeViews auf False eingestellt. Beim Einlesen der Ordner wird die Eigenschaft Aktiv für alle Ordner, die auch in der Tabelle tblMailordner enthalten sind, auf True eingestellt.

Wenn es nach dem Einlesen aller Ordner noch Datensätze in tblMailordner gibt, deren Feld Aktiv den Wert False enthält, sind diese Ordner nicht mehr in Outlook vorhanden. Dies wird dem Benutzer per Meldungsfenster mitgeteilt, der entsprechende Eintrag kann dann aus der Tabelle tblMailordner gelöscht werden.

Zurück zum Code: Nach dem Einstellen des Feldes Aktiv auf den Wert False füllt die Prozedur die Objektvariablen objOutlook und objNamespace mit entsprechenden Verweisen. Normalerweise würden wir hier alle Folder-Elemente in einer For Each-Schleife durchlaufen, aber dies führte auf meinem System zu Problemen: Dort fand die Prozedur mehr als ein Outlook-Root-Element, wobei diese auch noch die gleiche EntryID aufwiesen. Dies führt, wenn man die EntryID als Teil des eindeutigen Schlüssels der TreeView-Elemente verwenden möchte, zu einem Fehler. Eigentlich interessieren uns aber ohnehin nur die Ordner Posteingang und Postausgang, weshalb wir den Einlesevorgang einmal für den durch objNamespace.GetDefaultFolder(olFolderInbox) und einmal für den durch objNamespace.GetDefaultFolder(olFolderSentMail) definierten Root-Ordner ausführen.

Dabei ruft die Prozedur für jeden Ordner die Prozedur NodeAnlegen mit einem Verweis auf das aktuelle Database-Objekt und das Folder-Objekt auf. Diese Prozedur legt für jeden Ordner ein Node-Element im TreeView-Steuerelement an und führt einige andere Aufgaben aus – mehr dazu weiter unten. Anschließend folgt noch ein Aufruf der rekursiven Prozedur MailordnerEinlesen_Rek, die sich um die untergeordneten Ordner kümmert.

Rekursives Einlesen der Ordner

Die rekursive Prozedur MailordnerEinlesen_Rek erwartet als Parameter einen Verweis auf das aktuelle Database-Objekt, auf das Folder-Objekt, dessen Unterordner nun untersucht werden sollen, sowie auf das Node-Objekt, unter dem die weiteren Ordner dargestellt werden sollen (s. Listing 4).

Listing 4: Rekursives Einlesen der unteren Ordner-Ebenen

Public Sub MailordnerEinlesen_Rek(db As DAO.Database, objParentFolder As Outlook.Folder, _
        objParentNode As MSComctlLib.Node)
    Dim objFolder As Outlook.Folder
    Dim objNode As MSComctlLib.Node
    For Each objFolder In objParentFolder.Folders
     Set objNode = NodeAnlegen(db, objFolder, objParentNode.Key)
        If Not objNode Is Nothing Then
            MailordnerEinlesen_Rek db, objFolder, objNode
        End If
    Next objFolder
End Sub

Die Prozedur durchläuft in einer For Each-Schleife wiederum die in objParentFolder enthaltenen Folder-Objekte. Sie ruft für jedes Element einmal die Prozedur NodeAnlegen auf.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar