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