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).
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.
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.
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