Mails mit Vorlage

Ein großer Teil der Kommunikation mit Kunden läuft per E-Mail. Das ist vor allem dann der Fall, wenn der Kunde ein Anliegen per E-Mail vorbringt. Manchmal muss man den Kunden aber auch aus anderen Gründen kontaktieren – beispielsweise weil eine Lieferung per Post zurückgekommen ist. Wollen Sie dann die Kundenverwaltung öffnen, die E-Mail-Adresse des Kunden ermitteln, nach Outlook wechseln, dort eine neue E-Mail an den Kunden anlegen und Ihre Nachricht samt Betreff von Hand eingeben Nein, denn die meisten Anfragen lassen sich leicht mit einer geeigneten Vorlage erledigen.

Als Ausgangspunkt für die Lösung aus diesem Beitrag nehmen wir eine zurückgesendete Lieferung an einen Kunden (das war der konkrete Anlass für diesen Beitrag). In diesem Fall wollen wir dem Kunden eine Mitteilung schicken, dass eine Sendung zurückgeschickt wurde und ihn bitten, die beim Versand verwendete Adresse zu prüfen und gegebenenfalls zu korrigieren.

Bisher habe ich dazu die Kundenverwaltung gestartet, dort das Kundenformular geöffnet und über das Suchfeld den Datensatz zu diesem Kunden ermittelt. Dann habe ich eine neue E-Mail in Outlook angelegt, die E-Mail-Adresse in das An-Feld eingetragen, eine Betreff zur E-Mail hinzugefügt und einen entsprechenden Text geschrieben.

Dieser enthielt dann die beim Versand genutzte Adresse, die ich praktischerweise per Mausklick generieren kann und nur noch als Adressblock in die E-Mail zu kopieren brauche.

Alles in allem eine Menge Schritte, die ich etwa bei einem Versand eines Magazins zwischen fünf und zehn Mal wiederholen muss. Für jemanden, der gern automatisierte Wege für Standardaufgaben entwickelt und nutzt, ist das eine wenig erfreuliche Aufgabe. Allerdings hat bisher auch die Motivation nicht gereicht, um hierfür eine Lösung zu programmieren – immerhin würde das doch noch etwas länger dauern als die manuelle Erstellung von fünf bis zehn individuellen Mails. Wenn es aber der Zufall so will, dass ich gerade Beiträge für Access im Unternehmen schreibe, lässt sich das prima kombinieren – ich habe eine praktische Lösung und kann diese auch noch an meine Leser weitergeben. Also: Ran ans Werk!

Daten der Anwendung

Als Daten für die Anwendung nutzen wir eine Tabelle namens tblKunden, die in der Datenblattansicht wie in Bild 1 aussieht und deren Anreden über ein Fremdschlüsselfeld namens AnredeID aus der per 1:n-Beziehung verknüpften Tabelle tblAnreden festgelegt werden.

Datenherkunft für die Lösung

Bild 1: Datenherkunft für die Lösung

Ausgangspunkt

Wir gehen an dieser Stelle davon aus, dass Sie ein Kundenformular verwenden, in dem Sie die Kundendaten eines bestimmten Kunden zügig über eine entsprechende Suchfunktion anzeigen können. Wir nutzen dazu die Suchfunktion aus dem Beitrag Flexible Suche in Formularen (http://www.access-im-unternehmen.de/965) beziehungsweise Suchen mit der clsFlexSearch-Klasse (http://www.access-im-unternehmen.de/964).

Kundenformular erstellen

Falls Sie kein solches Formular verwenden, erstellen wir auf die Schnelle eines. Dazu legen Sie ein neues Formular namens frmKunde an.

Diesem weisen Sie als Datenherkunft die Tabelle tblKunden zu. Ziehen Sie alle Felder aus der Feldliste in den Detailbereich der Entwurfsansicht (s. Bild 2).

Entwurf des Kundenformulars

Bild 2: Entwurf des Kundenformulars

Außerdem fügen Sie die Klasse clsFlexSearch aus der Beispieldatenbank zu obigem Beitrag (oder aus der Datenbank zu diesem Beitrag) in das VBA-Projekt Ihrer Lösung.

Daneben benötigen wir noch eine Abfrage namens qryKundensuche, welche die Felder der beiden Tabellen tblKunden und tblAnreden so zusammenführt, dass alle Felder der Tabelle tblKunden (außer AnredeID) und nur das Feld Anrede der Tabelle tblAnreden zurückgegeben werden (s. Bild 3).

Abfrage als Datenherkunft für die Suchfunktion

Bild 3: Abfrage als Datenherkunft für die Suchfunktion

Suchfeld hinzufügen

Nun fügen Sie dem Kundenformular ganz oben ein Textfeld namens txtSuche hinzu. Schließlich legen Sie für die Ereignisprozedur Beim Laden des Formulars den Wert [Ereignisprozedur] an und klicken auf die Schaltfläche rechts daneben, um die entsprechende Prozedur zu erstellen. Diese füllen Sie dann wie folgt:

Private Sub Form_Load()
     Set objFlexSearch = New clsFlexSearch
     With objFlexSearch
         .Suchabfrage = "qryKundensuche"
         .PKFeld = "KundeID"
         .PKFeldEinschliessen = False
         Set .Suchfeld = Me!txtSuche
     End With
End Sub

Dies erstellt ein Objekt auf Basis der Klasse clsFlexSearch und teilt dieser mit, dass es qryKundensuche als Grundlage für die Suche nutzen soll, dass KundeID das Primärschlüsselfeld ist und dass dieses nicht in die Suche eingeschlossen werden soll.

Außerdem wird das Textfeld txtSuche als Suchfeld festgelegt. objFlexSearch müssen Sie natürlich im gleichen Formular deklarieren, und zwar wie folgt im Kopf des Moduls:

Dim WithEvents objFlexSearch As clsFlexSearch

Danach legen Sie noch eine Ereignisprozedur für das Ereignis Beim Entladen an, die nur die Objektvariable objFlexSearch leert:

Private Sub Form_Unload(Cancel As Integer)
     Set objFlexSearch = Nothing
End Sub

Schließlich definieren Sie, was geschehen soll, wenn der Benutzer einen Suchausdruck in das Textfeld txtSuche eingegeben hat und dann die Eingabetaste betätigt. Dazu wählen Sie aus dem linken Kombinationsfeld oben im VBA-Fenster des Klassenmoduls Form_frmKunde den Eintrag objFlexSearch aus, was automatisch die leere Ereignisprozedur objFlexSearch_Suchen anlegt. Diese füllen Sie dann wie folgt:

Private Sub objFlexSearch_Suchen(strWhere As String)
     Me.Filter = strWhere
     Me.FilterOn = True
End Sub

Dadurch wird der Filter des Formulars auf einen Ausdruck eingestellt, der mit dem Wert des Parameters strWhere der Prozedur geliefert wird.

Wenn Sie das Kundenformular nun öffnen, können Sie die Feldnamen eingeben, die direkt entsprechend ergänzt werden. Ein Klick auf Tab vervollständigt das Suchfeld und trägt einen Doppelpunkt ein, hinter dem Sie den Vergleichswert eintragen. Mehrere Ausdrücke können Sie mit And voneinander trennen. Sie können aber auch einfach einen Wert wie andre@minhorst.com eingeben, dann werden alle Felder aller Datensätze nach diesem Wert untersucht (s. Bild 4).

Suchfunktion im Einsatz

Bild 4: Suchfunktion im Einsatz

Vorlagen verwalten

Nun benötigen wir eine Tabelle, mit der wir die Vorlagen für die E-Mails verwalten können. Diese Tabelle soll schlicht tblMailvorlagen heißen und sieht im Entwurf wie in Bild 5 aus. Das Feld Bezeichnung haben wir mit einem eindeutigen Index versehen. Die Felder Betreff, Inhalt und EMail nehmen die Vorlagen für die entsprechenden Texte auf. Hier können Sie Gebrauch von Platzhaltern machen, die später aus den Daten der Kundentabelle gefüllt werden – mehr dazu weiter unten in der Beschreibung der Nutzung des Formulars, das diese Daten anzeigt.

Die Tabelle tblMailvorlagen

Bild 5: Die Tabelle tblMailvorlagen

Wichtig sind noch die beiden Felder TabelleAbfrage und PKFeld. TabelleAbfrage nimmt den Namen der Tabelle oder Abfrage auf, welche die Daten für den Kunden liefern soll, PKFeld den Namen des in dieser Tabelle oder Abfrage zur Identifizierung des Kunden notwendigen Primärschlüsselfeldes.

Formular zum Bearbeiten der Mailvorlagen

Die Daten dieser Tabellen wollen wir in einem separaten Formular bearbeiten. Dieses heißt frmMailvorlagen und sieht in der Entwurfsansicht wie in Bild 6 aus. Damit es die Daten der Tabelle tblMailvorlagen in alphabetischer Reihenfolge liefert, verwenden wir den folgenden SQL-Ausdruck als Datenherkunft für das Formular:

Das Formular frmMailvorlagen in der Entwurfsansicht

Bild 6: Das Formular frmMailvorlagen in der Entwurfsansicht

SELECT tblMailvorlagen.MailvorlageID, tblMailvorlagen.Bezeichnung, tblMailvorlagen.Betreff, tblMailvorlagen.Inhalt, tblMailvorlagen.EMail, tblMailvorlagen.TabelleAbfrage, tblMailvorlagen.PKFeld 
FROM tblMailvorlagen 
ORDER BY tblMailvorlagen.Bezeichnung;

Allerdings soll das Formular ja ohnehin nur die Details eines Datensatzes anzeigen, daher stellen wir die Eigenschaften Bildlaufleisten, Datensatzmarkierer und Navigationsschaltflächen auf den Wert Nein und Automatisch zentrieren auf Ja ein. Wieso dann die Datensätze nach dem Alphabet sortieren Ganz einfach: Weil auch das Kombinationsfeld cboAuswahl seine Daten aus der Tabelle tblMailvorlagen bezieht und beide den gleichen Datensatz anzeigen sollen. Hier bietet es sich einfach an, die Mailvorlage zu liefern, deren Bezeichnung in der alphabetischen Sortierung als erste erscheint.

Das Kombinationsfeld benötigt nur die beiden Felder MailvorlageID und Bezeichnung, daher verwenden wir eine verkürzte Version der Abfrage, die wir als Datenherkunft für das Formular genutzt haben, als Datensatzherkunft:

SELECT tblMailvorlagen.MailvorlageID, tblMailvorlagen.Bezeichnung FROM tblMailvorlagen 
ORDER BY tblMailvorlagen.Bezeichnung;

Das Formular zeigt ja nun bereits automatisch den ersten Datensatz nach alphabetischer Reihenfolge an. Damit das Kombinationsfeld den gleichen Datensatz anzeigt, fügen wir dem Formular für das Ereignis Beim Laden die folgende Ereignisprozedur hinzu:

Private Sub Form_Load()
     Me!cboAuswahl = Me!MailvorlageID
End Sub 

Diese wählt den gleichen Eintrag aus, der auch im Formular angezeigt wird.

Damit nach der Auswahl eines der Einträge des Kombinationsfeldes die gewählte Mailvorlage im Formular angezeigt wird, legen Sie für das Ereignis Nach Aktualisierung des Kombinationsfeldes die folgende Ereignisprozedur an:

Private Sub cboAuswahl_AfterUpdate()
     Me.Filter = "MailvorlageID = " & Me!cboAuswahl
     Me.FilterOn = True
End Sub

Dies filtert das Formular nach dem im Kombinationsfeld ausgewählten Eintrag.

Damit beim Klick auf die Schaltfläche cmdNeu ein neuer, leerer Datensatz im Formular erscheint, hinterlegen wir für das Beim Klicken-Ereignis der Schaltfläche diese Prozedur:

Private Sub cmdNeu_Click()
     DoCmd.GoToRecord Record:=acNewRec
End Sub

Damit erscheint ein neuer, leerer Datensatz. Dieser ist natürlich noch nicht in der Datensatzherkunft des Kombinationsfeldes enthalten.

Daher legen wir die folgende Prozedur an, die in diesem Fall den Wert des Kombinationsfeldes auf den Wert Null einstellt (im Falle eines Wechsels zu einem anderen Datensatz wird dieser auch im Kombinationsfeld angezeigt):

Private Sub Form_Current()
     Me!cboAuswahl.Requery
     Me!cboAuswahl = Me!MailvorlageID
End Sub

Das Aktualisieren der Datensatzherkunft des Kombinationsfeldes dient dazu, den neu angelegten Datensatz direkt nach dem Wechsel zu einem anderen Datensatz in das Kombinationsfeld aufzunehmen.

Fehlt noch die Schaltfläche zum Schließen des Formulars:

Private Sub cmdOK_Click()
     DoCmd.Close acForm, Me.Name
End Sub

Vorlage anlegen

In Aktion sieht das Formular nun wie in Bild 7 aus. Für das Feld Bezeichnung geben Sie eine sinnvolle Bezeichnung an, unter der Sie die Mailvorlage schnell finden. Das Feld Tabelle/Abfrage soll die Datenquelle aufnehmen, aus der die Daten für die Platzhalter in den nachfolgenden Eigenschaften der Mailvorlage entnommen werden sollen. Wir geben hier die Abfrage qryKunden an, welche die Felder der Tabellen tblKunden und tblAnreden wie in Bild 8 zusammenführt.

Die Abfrage qryKunden dient als Datenquelle für das Ersetzen der Platzhalter

Bild 7: Die Abfrage qryKunden dient als Datenquelle für das Ersetzen der Platzhalter

Das Formular frmMailvorlagen in der Formularansicht

Bild 8: Das Formular frmMailvorlagen in der Formularansicht

Das Feld E-Mail statten Sie mit dem Namen des Feldes der Datenherkunft aus, welche die E-Mail-Adresse des Kunden liefert, in diesem Fall schlicht EMail. Betreff füllen Sie mit dem gewünschten Betreff der E-Mail. In diesem Fall benötigen wir keinen Platzhalter. Das Feld Inhalt jedoch enthält einen Platzhalter für das Feld Briefanrede der Tabelle tblAnreden und Nachname aus der Tabelle tblKunden. Das ist noch verständlich. Aber was geschieht mit dem folgenden Platzhalter, der ja offensichtlich keinem Feld der Datenherkunft entspricht

[=Adressblock(0, 5, [KundeID])]

Hierbei handelt es sich nicht um einen normalen Platzhalter, sondern um eine VBA-Funktion, die den Text bereitstellt, der für den Platzhalter eingesetzt werden soll. Wenn Sie den Beitrag Dynamischer Adressblock (www.access-im-unternehmen.de/1090) bereits gelesen haben, kennen Sie die hier verwendete Funktion Adressblock bereits: Sie ermittelt aufgrund der Konfiguration in der Konfigurationstabelle tblKonfiguration einen Adressblock mit den Daten des Kunden.

Sie erwartet drei Parameter: Der erste gibt an, ob man die Liefer- oder die Rechnungsadresse holen will (hier 0 für die Lieferadresse), die zweite, welche Konfiguration der Tabelle tblKonfigurationen genutzt werden soll, und die dritte enthält den Primärschlüsselwert für den Kundendatensatz, der die Daten liefert. (Hinweis: Im Beitrag Dynamischer Adressblock haben wir als ersten Parameter noch die Konstante Lieferadresse verwendet. Das funktioniert hier leider nicht, daher verwenden wir den entsprechenden Zahlenwert der Enumeration – den Grund erfahren Sie gleich.)

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