Mails per Drag and Drop in der Datenbank speichern

Mails landen gewöhnlicherweise im Posteingangsordner und werden dann, entweder automatisch oder manuell, in den jeweiligen Zielordner verschoben – wenn sie nicht gar gelöscht werden. Aber kann das schon alles sein Nein! In diesem Artikel zeigen wir Ihnen, wie Sie beim Verschieben einer Mail in einen bestimmten Ordner weitere Aktionen auslösen können, und zwar per VBA-Ereignis. Auf diese Weise können Sie dann beispielsweise den Inhalt der Mail und gegebenenfalls auch Anlagen direkt in einer dafür vorgesehenen Datenbank speichern.

Welchen Sinn aber soll es haben, den Inhalt von E-Mails in einer Datenbank zu speichern Sie können auf diese Weise etwa die Mails zu bestimmten Kunden in einer entsprechenden Tabelle ablegen und dem Kunden in der Datenbank zuordnen.

So brauchen Sie von der Kundendatenbank aus nicht immer noch Outlook zu öffnen, um die Kommunikation mit diesem Kunden einzusehen.

Voraussetzungen

Für die nachfolgend vorgestellten Techniken benötigen Sie Microsoft Office mit Outlook und Access in der Version 2007 oder neuer.

Ordner anlegen

Als Erstes wollen wir einen Ordner unter Outlook anlegen, dem Sie die in der Datenbank zu speichernden E-Mails hinzufügen. Diesen können Sie manuell anlegen, wir können dies aber auch per Code erledigen.

Dazu öffnen Sie den VBA-Editor von Outlook (bei geöffnetem Outlook-Fenster mit Alt + F11) und fügen dem bereits vorhandenen Klassenmodul ThisOutlookSession über die beiden Kombinationsfelder im Kopf des Codefensters die Ereignisprozedur Application_Startup hinzu (s. Bild 1). Dieses Ereignis wird bei jedem Start von Outlook ausgelöst.

Anlegen der Ereignisprozedur Application_Startup

Bild 1: Anlegen der Ereignisprozedur Application_Startup

Hier können wir einen Code einfügen, der prüft, ob das gewünschte Verzeichnis sich bereits an Ort und Stelle befindet oder ob es noch angelegt werden soll. Letzteres führt die Prozedur dann gegebenenfalls noch durch.

Um beim Starten von Outlook zu prüfen, ob bereits ein Verzeichnis namens Kundenmails vorhanden ist, und dieses gegebenenfalls anzulegen, fügen Sie der Prozedur Application_Startup noch die Zeilen aus Listing 1 hinzu. Diese Prozedur füllt ein Objekt namens objNamespace mit dem MAPI-Namespace-Objekt von Outlook. Dieses liefert über die GetDefaultFolder-Eigenschaft mit dem Parameter olFolderInbox einen Verweis auf den Posteingangsordner.

Public Sub Application_Startup()
     Dim objInbox As Outlook.Folder
     Dim objKundenmails As Outlook.Folder
     Dim objNamespace As Outlook.NameSpace
     Set objNamespace = Outlook.GetNamespace("MAPI")
     Set objInbox = objNamespace.GetDefaultFolder(olFolderInbox)
     On Error Resume Next
     Set objKundenmails = objInbox.Folders("Kundenmails")
     On Error GoTo 0
     If objKundenmails Is Nothing Then
         Set objKundenmails = objInbox.Folders.Add("Kundenmails")
     End If
End Sub

Listing 1: Prüfen, ob das Verzeichnis Kundenmails schon vorhanden ist

Dann versucht die Prozedur, einen darin enthaltenen Ordner namens Kundenmails mit der Variablen objKundenmails zu referenzieren. Gelingt dies nicht, bleibt objKundenmails leer, was die nachfolgende If…Then-Bedingung prüft.

Ist objKundenmails dann nicht gefüllt, legt die Prozedur diesen Ordner an und trägt einen Verweis auf diesen Ordner in die Variable objKundenmails ein.

Ereignis beim Hinzufügen einer Mail auslösen

Das waren die Vorarbeiten. Tatsächlich müssen wir das Folder-Objekt, mit dem wir das Verzeichnis Posteingang referenzieren, aber außerhalb der Prozedur Application_Startup referenzieren – und zwar mit der folgenden Anweisung:

Dim WithEvents objInbox As  Outlook.Folder

Das Schlüsselwort WithEvents ist nötig, damit wir für die Variable objInbox Ereignisprozeduren im Klassenmodul ThisOutlookSession implementieren können. Dies erledigen Sie nun wiede-rum über die beiden Kombinationsfelder im Kopf des Codefensters. Wählen Sie dort links den nun verfügbaren Eintrag objInbox aus und rechts den Eintrag BeforeItemMove aus, sodass der VBA-Editor die Ereignisprozedur objInbox_BeforeItemMove anlegt (s. Bild 2).

Hinzufügen einer Ereignisprozedur, die beim Verschieben einer Mail ausgelöst wird

Bild 2: Hinzufügen einer Ereignisprozedur, die beim Verschieben einer Mail ausgelöst wird

Hier hinterlegen Sie nun einige weitere Codezeilen, die wie in Listing 2 aussehen. Damit haben wir nun die Basis für weitere Funktionen geschaffen: Wir haben eine Ereignisprozedur, die durch das Verschieben einer E-Mail aus dem Verzeichnis Posteingang ausgelöst wird. Diese Prozedur prüft innerhalb einer Select Case-Bedingung das Zielverzeichnis. Nur wenn dieses den Namen Kundenmails trägt, wird ein Meldungsfenster angezeigt, das über die übermittlung der Mail in das Verzeichnis Kundenmails informiert.

Private Sub objInbox_BeforeItemMove(ByVal Item As Object, ByVal MoveTo As MAPIFolder, Cancel As Boolean)
     Select Case MoveTo.Name
         Case "Kundenmails"
             MsgBox "Mail ist angekommen."
     End Select
End Sub

Listing 2: Meldung ausgeben, wenn die Mail in den gewünschten Ordner verschoben wurde

Statt des Meldungsfensters können wir dort nun weitere Anweisungen hinzufügen – etwa, um die Inhalte der E-Mail in der Tabelle einer Datenbank zu speichern.

Tabelle zum Speichern der E-Mails

In einer neuen Datenbankdatei namens Kundenmails.accdb legen wir nun eine neue Tabelle mit der Bezeichnung tblKundenmails an. Diese soll die Felder aus Bild 3 enthalten. Neben dem Primärschlüsselfeld KundenmailID nimmt die Tabelle die grundlegenden Informationen und Inhalte der E-Mail auf – so den Absender, den Empfänger, den Betreff, den Inhalt und das Versanddatum.

Die Tabelle tblKundenmails speichert die grundlegenden Informationen

Bild 3: Die Tabelle tblKundenmails speichert die grundlegenden Informationen

Die Anlagen speichern wir in einer weiteren Tabelle namens tblMailanlagen. Diese finden Sie in Bild 4 vor. Die Tabelle enthält ein Fremdschlüsselfeld namens KundenmailID zum Verknüpfen der Datensätze dieser Tabelle mit denen der Tabelle tblKundenmails. Außerdem speichert die Tabelle den Dateinamen der Anlage im Feld Anlagebezeichnung sowie die Datei selbst im Feld Mailanlage.

Die Tabelle tblMailanlagen speichert die Mailanlagen

Bild 4: Die Tabelle tblMailanlagen speichert die Mailanlagen

Grundsätzlich hätten wir auch einfach nur ein Feld mit dem Datentyp Anlage in der Tabelle tblKundenmails anlegen können. Wir möchten da Anlage-Feld jedoch nicht dazu nutzen, mehrere Dateien zu speichern, da Informationen wie etwa der Dateiname dann nicht so einfach über die Benutzeroberfläche (etwa über Formulare) einsehbar sind.

E-Mails und Anlagen speichern

Listing 3 liefert zunächst zwei Konstanten namens cStrPath und cStrDB, die den Pfad und den Namen der Datenbank enthalten. Sicher gibt es elegantere Möglichkeiten, als Pfad und Dateiname hier fest zu verdrahten, aber aktuell reicht uns diese Variante aus.

Const cStrPath As String = "Z:\Dokumente\Daten\Fachmagazine\AccessImUnternehmen\2014\06\OutlookDrop\"
Const cStrDB As String = "Kundenmails.accdb"
Private Sub objInbox_BeforeItemMove(ByVal Item As Object, ByVal MoveTo As MAPIFolder, Cancel As Boolean)
     If Not MoveTo Is Nothing Then
         Select Case MoveTo.Name
             Case "Kundenmails"
                 MailSpeichern Item
         End Select
     End If
End Sub

Listing 3: Konstanten mit Pfad und Datenbankname und die Ereignisprozedur objInbox_BeforeItemMove

Die Ereignisprozedur objInbox_BeforeItemMove prüft wiederum den Zielordner des Drag-and-Drop-Vorgangs und ruft im Falle des Ordners Kundenmails die Prozedur MailSpeichern auf. Dieser übergibt sie mit dem Parameter Item einen Verweis auf das verschobene E-Mail-Objekt. Sicher haben Sie auch erkannt, dass wir der Prozedur noch eine If…Then-Bedingung hinzugefügt haben. Diese prüft, ob MoveTo überhaupt einen Wert enthält. Sollte der Benutzer nämlich eine E-Mail vollständig löschen (also bei gedrückter Umschalttaste und ohne Umweg über den Ordner Gelöschte Objekte), dann ist das MoveTo-Objekt gar nicht mehr mit einem Verweis auf das entsprechende MailItem-Objekt gefüllt und die Prozedur kann beendet werden.

Vorbereitungen für den Zugriff auf Access

Das VBA-Projekt von Outlook kümmert sich normalerweise nicht um Access-Datenbanken. Dementsprechend wird auch der Zugriff auf die Tabellen einer Datenbank mit den Methoden der DAO-Bibliothek nicht nativ unterstützt. Damit wir beim Programmieren den gewohnten Komfort mit IntelliSense auch für die DAO-Objekte erhalten, fügen wir dem Projekt einen Verweis auf die Bibliothek Microsoft Office x.0 Access database engine Objects hinzu – und zwar über den Verweise-Dialog aus Bild 5, den Sie mit dem Menüeintrag Extras|Verweise öffnen.

Verweis auf die DAO-Bibliothek hinzufügen

Bild 5: Verweis auf die DAO-Bibliothek hinzufügen

Speichern der E-Mail

Das Speichern der E-Mail erledigt die Prozedur MailSpeichern, die Sie in Listing 4 finden.

Private Sub MailSpeichern(objMail As Outlook.MailItem)
     Dim db As DAO.Database
     Dim rst As DAO.Recordset
     Dim lngKundenmailID As Long
     Set db = OpenDatabase(cStrPath & cStrDB)
     Set rst = db.OpenRecordset("SELECT * FROM tblKundenmails WHERE 1 = 2", dbOpenDynaset)
     rst.AddNew
     rst!Absenderemail = objMail.SenderEmailAddress
     rst!Empfaengeremail = objMail.Recipients.Item(1)
     rst!Betreff = objMail.Subject
     rst!Inhalt = objMail.Body
     rst!GesendetAm = objMail.SentOn
     lngKundenmailID = rst!KundenmailID
     rst.Update
     If objMail.Attachments.Count > 0 Then
         AnlagenSpeichern db, lngKundenmailID, objMail.Attachments
     End If
End Sub

Listing 4: Prozedur zum Speichern des Inhalts einer E-Mail in der Tabelle tblKundenmails

Die Prozedur erstellt zunächst einen Verweis auf die Zieldatenbank namens Kundenmails.accdb in dem angegebenen Zielordner. Dort, wo Sie sonst die CurrentDb-Funktion verwenden, um auf die aktuelle Datenbank zuzugreifen, nutzen wir nun die Funktion OpenDatabase, um von Outlook aus die Datenbank Kundenmails.accdb zu nutzen. Dann erstellt die Prozedur ein Recordset-Objekt auf Basis der Tabelle tblKundenmails, wobei allerdings keine Datensätze zurückgegeben werden sollen – daher die Bedingung 1=2.

Die Prozedur fügt einen neuen Datensatz hinzu und füllt einige Felder:

Die Eigenschaft SenderEMailAddress landet im Feld AbsenderEMail, Subject in Betreff, Body in Inhalt und SentOn im Feld GesendetAm. Etwas komplizierter ist es mit der Empfängeradresse: Eine E-Mail kann natürlich mehrere Empfängeradressen enthalten. Diese finden Sie in der Recipients-Auflistung des MailItem-Objekts. Wir tragen hier daher einfach den ersten Wert dieser Auflistung in das Feld Empfaengeremail ein (Item(1)).

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

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar