Outlook-Mails mit Klasse

Das Versenden von E-Mails mit Access ist eines der besten Beispiele für die Interaktion von Access mit anderen Office-Komponenten. Es gibt zahlreiche Anwendungsfälle für das Versenden von E-Mails von einer Datenbank-Anwendung aus – egal, ob es sich nun um Anschreiben an Kunden, an Serien-E-Mails oder auch an E-Mails zum Versenden von Fehlermeldungen handelt. Grund genug, diese Funktion einmal in eine eigene Klasse auszulagern, die Sie dann ganz einfach in die Zielanwendung importieren und direkt einsetzen können.

Diese Klasse umfasst einige Funktionen, die erst mit neueren Outlook-Versionen verfügbar sind. Wir weisen an entsprechender Stelle darauf hin und stellen auch eine Version der Klasse zur Verfügung, die mit älteren Outlook-Versionen arbeitet. Um die hier vorgestellte Klasse einsetzen zu können, müssen Sie lediglich die Klasse in Ihre Anwendung importieren und einen Verweis auf die Bibliothek Microsoft Outlook x.0 Object Library zum VBA-Projekt der aktuellen Datenbank hinzufügen. Die Klasse finden in der Beispieldatenbank zu diesem Beitrag, den Verweis fügen Sie über den Verweise-Dialog (VBA-Editor, Menü-Eintrag Extras|Verweise) hinzu.

Einfacher Versand

Wenn Sie beispielsweise einen Kundendatensatz samt E-Mail-Adresse des Kunden in einem Formular anzeigen, können Sie diesem eine einfache Schaltfläche zum Erstellen einer E-Mail an diesen Kunden hinzufügen (s. Bild 1).

pic001.png

Bild 1: Einfacher Mailversand an einen Kunden

Ein Klick auf diese Schaltfläche soll eine neue E-Mail anlegen und öffnen, damit der Betreff und der Inhalt eingefügt werden können. Der dazu notwendige Code sieht schlicht wie folgt aus:

Private Sub cmdEMailSenden_Click()
    Dim objMail As clsMail
    Set objMail = New clsMail
    With objMail
        .AnHinzufuegen Me.EMail
        .Betreff = "Beispielbetreff"
        .Inhalt = "Dies ist eine Beispiel-E-Mail."
        .Senden
    End With
End Sub

Sie erstellen hier ein neues Objekt auf Basis der Klasse clsMail und legen dann die Eigenschaften der zu erstellenden E-Mail fest. Als Betreff und Inhalt weisen Sie entsprechende Platzhaltertexte zu, den Empfänger hingegen als Parameter der Methode ToHinzufuegen. Warum das Wir hätten auch einfach eine Eigenschaft namens An verwenden können, aber daraus wäre nicht ersichtlich geworden, dass Sie damit nicht nur einen Empfänger, sondern gleich mehrere einfügen können.

Die Methode Senden führt schließlich zum Versand der E-Mail.

E-Mail vor dem Versenden anzeigen

Fügen Sie dem gleichen Formular nun eine zweite Schaltfläche mit dem Text E-Mail erstellen hinzu und nennen diese cmdMailErstellen. Hinterlegen Sie dafür den folgenden Code:

Private Sub cmdMailErstellen_Click()
    Dim objMail As clsMail
    Set objMail = New clsMail
    With objMail
        .AnHinzufuegen Me.EMail
        .Betreff = "[Betreff]"
        .Inhalt = "[Inhalt]"
        .Anzeigen
    End With
End Sub

Diese Prozedur legt ebenfalls eine neue E-Mail an und weist einen Empfänger zu. Allerdings werden Betreff und Inhalt jeweils mit Platzhaltern gefüllt, die vom Benutzer noch durch den gewünschten Text ersetzt werden sollen.

Damit die Klasse die E-Mail nicht gleich versendet, sondern zuerst anzeigt, rufen Sie diesmal nicht die Senden-Methode, sondern die Anzeigen-Methode auf.

Dies öffnet die E-Mail im entsprechenden Editor von Outlook und ermöglicht das manuelle ändern und das anschließende Versenden der E-Mail. Das Ergebnis finden Sie in Bild 2, dort sind auch die Platzhalter für Betreff und Inhalt zu erkennen.

pic002.png

Bild 2: Per VBA erzeugte E-Mail

E-Mails speichern

Einen Schritt weiter geht die nächste Anwendung. Die Tabelle tblEMails soll Informationen über alle versendeten E-Mails erfassen. Wenn die E-Mails mit der ersten Schaltfläche versendet werden, stehen Betreff und Inhalt bereits fest und können direkt in der Tabelle gespeichert werden.

Dazu fügen Sie einfach hinter dem Aufruf der Senden-Methode eine entsprechende Anfügeabfrage ein:

db.Execute ("INSERT INTO tblEMails(KundeID, EMail, Betreff, Inhalt, Versanddatum) VALUES(" _
    & Me!KundeID & ", ''" & Me!EMail & "'', ''" & .Betreff & "'', ''" & .Inhalt & "'', " & IsoDatum(Date) & ")")

Wenn der Benutzer die zu versendende E-Mail aber erst anzeigen lässt, danach den Betreff und den Inhalt manuell anpasst und die E-Mail erst dann versendet, wie landen die Daten dann in der Tabelle Immerhin trägt der Benutzer diese Daten nur in der E-Mail ein, nicht in der Datenbank.

Auch dies ermöglicht die Klasse: Sie trägt die geänderten Inhalte für den Betreff und den Inhalt der E-Mail mit dem Versenden in die entsprechenden Eigenschaften der Klasse clsMail ein, sodass Sie diese gleich nach dem Versenden weiterverarbeiten können.

Wie das aussehen kann, zeigt der Beispielcode aus Listing 1. Der Aufruf der Methode Anzeigen hält den Code an, bis der Benutzer die angezeigte Mail versendet (siehe weiter unten). Klickt der Benutzer auf die Senden-Schaltfläche der E-Mail, werden die Inhalte an die Klasse übergeben und können mit den Eigenschaften Betreff und Inhalt wieder ausgelesen werden. Hier erfolgt die Ausgabe im Direktfenster, bevor die E-Mail-Informationen in der Tabelle tblEMails gespeichert werden.

Listing 1: Weiterverarbeiten der geänderten Inhalte einer E-Mail nach dem Versenden

Private Sub cmdMailErstellen_Click()
    Dim objMail As clsMail
    Dim db As DAO.Database
    Set objMail = New clsMail
    Set db = CurrentDb
    With objMail
        .AnHinzufuegen Me.EMail
        .Betreff = "[Betreff]"
        .Inhalt = "[Inhalt]"
        .Anzeigen
        Debug.Print .Betreff
        Debug.Print .Inhalt
        db.Execute ("INSERT INTO tblEMails(KundeID, EMail, Betreff, Inhalt, Versanddatum) VALUES(" _
            & Me!KundeID & ", ''" & Me!EMail & "'', ''" & .Betreff & "'', ''" & .Inhalt & "'', " _
            & ISODatum(Date) & ")"), dbFailOnError
    End With
    Set db = Nothing
End Sub

Versenden mehrerer E-Mails

Sie können diese Klasse auch nutzen, um E-Mails gleich an mehrere Empfänger zu versenden. Ein Beispiel hierzu finden Sie in Listing 2.

Listing 2: Versenden mehrerer E-Mails

Public Function Serienmail()
    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    Dim objMail As clsMail
    Set db = CurrentDb
    Set rst = db.OpenRecordset("SELECT * FROM tblKunden", dbOpenDynaset)
    Set objMail = New clsMail
    Do While Not rst.EOF
        With objMail
            .AnHinzufuegen rst!EMail
            .Betreff = "Betreff"
            .Inhalt = "Inhalt"
            .Senden
            .NeueMail
        End With
        rst.MoveNext
    Loop
    Set objMail = Nothing
    rst.Close
    Set rst = Nothing
    Set db = Nothing
End Function

Diese Prozedur verwendet die Tabelle tblKunden als Datenherkunft für ein Recordset-Objekt.

In einer Do While-Schleife durchläuft die Prozedur alle Datensätze dieses Recordsets und versendet darin jeweils eine E-Mail für den aktuellen Datensatz.

Im Gegensatz zum Versenden einer einzelnen E-Mail müssen Sie nur einen kleinen Unterschied beachten: Nach dem Versenden einer Mail und vor dem dem Versenden der nächsten E-Mail müssen Sie mit der Methode NeueMail eine neue E-Mail erstellen.

Alternativ können Sie auch das Erstellen der E-Mail mit Set objMail = New clsMail in die Schleife verlegen.

Dies würde jedoch dazu führen, dass für jede E-Mail erneut eine Outlook-Instanz erstellt beziehungsweise eine bestehende Instanz referenziert werden muss – und dies wirkt sich bei vielen E-Mails sicher auf die Performance aus.

E-Mail blind an mehrere Empfänger

Natürlich können Sie auch eine einzige E-Mail gleichzeitig an mehrere verschiedene Empfänger versenden.

Dazu strukturieren Sie einfach die Befehle der zuvor vorgestellten Prozedur so um, dass nur noch die Zuweisung der BCC-Empfängeradressen innerhalb der Schleife liegt:

Public Function MailAnMehrereBlindeEmpfaenger()
    ...
    Set rst = db.OpenRecordset("SELECT * FROM tblKunden", dbOpenDynaset)
    Set objMail = New clsMail
    With objMail
        .AnHinzufuegen "info@access-basics.de"
        Do While Not rst.EOF
            .BCCHinzufuegen rst!EMail
            rst.MoveNext
        Loop
        .Betreff = "Betreff"
        .Inhalt = "Inhalt"
        .Anzeigen
        .NeueMail
    End With
    ...
End Function

Das Erstellen der E-Mail, das Hinzufügen der übrigen Informationen sowie das Versenden erfolgen außerhalb der Do…While-Schleife. Das Ergebnis sieht dann etwa wie in Bild 3 aus.

pic003.png

Bild 3: E-Mail mit mehreren BCC-Empfängern

Absender ändern

Gegebenenfalls möchten Sie in einer Anwendung E-Mails mit verschiedenen Absenderadressen versenden.

In diesem Fall verwenden Sie die Eigenschaft Von der Klasse clsEMail, um eine alternative Absenderadresse anzugeben.

Bedenken Sie, dass Sie nur solche Absenderadressen angeben können, für die in Outlook entsprechende Konten angelegt sind.

Gesendete E-Mail in bestimmten Ordner verschieben

Gegebenenfalls möchsten Sie eine E-Mail nach dem Versenden nicht im Standardordner Gesendete Objekte speichern, sondern in einem benutzerdefinierten Ordner unterhalb dieses Ordners.

Dann geben Sie einfach für die Eigenschaft Zielordner des Objekts objMail den Namen des Ordners an – beispielsweise wie in folgendem Beispiel:

Public Function MailInBestimmtenOrdner()
    Dim objMail As clsMail
    Set objMail = New clsMail
    With objMail
        .AnHinzufuegen "info@access-im-unternehmen.de"
        .Betreff = "Betreff"
        .Inhalt = "Inhalt"
        .Zielordner = "test"
        .Senden
    End With
    Set objMail = Nothing
End Function

Wenn sich der gewünschte Zielordner nicht direkt unter dem Gesendete Objekt-Ordner befindet, trennen Sie die Unterordner durch Schrägstriche:

.Zielordner = "test/test/test"

Dies legt dann, soweit noch keiner der Ordner vorhanden ist, gleich drei verschachtelte Ordner an.

Aufbau der Klasse clsMail

Schauen wir uns nun an, wie die Klasse clsEMail aufgebaut ist und wie diese funktioniert. Wenn Sie die Klasse selbst nachbauen möchten, erstellen Sie zunächst ein entsprechendes Klassenmodul mit dem Befehl Einfügen|Klassenmodul des VBA-Editors und speichern Sie dieses unter dem Namen clsMail.

Beim Initialisieren der Klasse etwa mit der Anweisung

Set objMail = New clsMail

wird in dieser Klasse gleich das Initialize-Ereignis ausgelöst, das mit folgender Ereignisprozedur implementiert wurde:

Private Sub Class_Initialize()
    Set objOutlook = New Outlook.Application
    Set objMail = objOutlook.CreateItem(olMailitem)
End Sub

Diese Prozedur erzeugt zunächst eine neue Instanz von Outlook beziehungsweise referenziert eine bestehende Instanz mit der Objektvariablen objOutlook, die wie folgt im Kopf des Klassenmoduls deklariert wird:

Private objOutlook As Outlook.Application

Das ebenfalls in dieser Prozedur erzeugte MailItem-Objekt wird wie folgt deklariert:

Private WithEvents objMail As Outlook.MailItem

Das Schlüsselwort WithEvents sorgt dafür, dass Sie die Ereignisse des MailItem-Objekts im vorliegenden Klassenmodul implementieren können. Wozu dies nötig ist, erfahren Sie weiter unten.

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