Benutzeroberfläche für CDO-Serienmails

Im Beitrag “Serienmails versenden mit CDO” haben wir einige Prozeduren und Funktionen vorgestellt, mit denen Sie Serien-E-Mails über die CDO-Bibliothek von Windows versenden können. Das macht natürlich nur halb soviel Spaß, wenn nur die nackten Routinen vorliegen. Also zeigen wir im vorliegenden Beitrag auch noch, wie Sie eine praktische Benutzeroberfläche zum Verwalten der für den Versand einer Serienmail benötigten Daten programmieren.

Datenmodell der Anwendung

Die Anwendung zum Versenden von Serienmails enthält einige Tabellen, die wie im Folgenden vorstellen.

Im Beziehungen-Fenster aus Bild 1 sehen Sie die benötigten Tabellen. Die ersten beiden heißen tblKunden sowie tblAnreden. Die Tabelle tblConfigurations enthält die Daten für die Konfiguration des Mailservers und die Tabelle tblMailings die Daten zum Mailing selbst, also eine Bezeichnung, die Absenderadresse, den Betreff, den Inhalt und die Anlagen. Der Tabelle tblMailings haben wir ein Fremdschlüsselfeld namens ConfigurationID hinzugefügt, mit dem wir die für das jeweilige Mailing verwendete Konfiguration speichern können. Außerdem enthält die Tabelle tblMailings zwei Felder, mit denen die Adressaten des Mailings definiert werden. SQLSource nimmt den SQL-Ausdruck auf, der die Empfängeradressen liefert und Mailfield den Namen des Feldes aus diesem Ausdruck, der festlegt, welches Feld die Mailadresse enthält.

Datenmodell der Anwendung

Bild 1: Datenmodell der Anwendung

Zu erstellende Formulare

Wir wollen der Lösung einige Formulare hinzufügen, mit der Sie diese komfortabel steuern können. Dazu gehören die folgenden:

  • Formular zum Verwalten der Konfigurationen
  • Formular zum Verwalten der Mailings
  • Formular zum Auswählen der Empfänger des Mailings

Formular zum Verwalten der Konfigurationen

Wir beginnen mit dem Formular frmConfigurations. Das Formular verwendet die Tabelle tblConfigurations als Datensatzquelle. Ziehen Sie alle Felder aus der Feldliste in das Formular und ordnen Sie diese so an wie in Bild 2. Dann fügen Sie noch einige weitere Steuerelemente hinzu:

Entwurf des Formulars frmConfigurations

Bild 2: Entwurf des Formulars frmConfigurations

  • Kombinationsfeld cboSchnellauswahl (in den Formularkopf)
  • Schaltfläche cmdOK (mit den anderen Schaltflächen in den Formularfuß)
  • Schaltfläche cmdNeu
  • Schaltfläche cmdLoeschen

Außerdem passen wir den Namen des Kontrollkästchens für das Feld Standard auf chkDefault an.

Schnellauswahl für die Konfiguration

Das Kombinationsfeld cboSchnellauswahl verwendet eine Abfrage auf Basis der Tabelle tblConfigurations als Datensatzherkunft. Dabei verwenden wir nur die ersten beiden Felder ConfigurationID und ConfigurationName, wobei wir diese nach dem Feld ConfigurationName sortieren wollen:

SELECT ConfigurationID, ConfigurationName FROM tblConfigurations ORDER BY ConfigurationName;

Damit das Kombinationsfeld nur die Bezeichnung der Konfiguration anzeigt, aber nicht den Inhalt des Autowertfeldes, stellen wir die Eigenschaft Spaltenanzahl auf 2 und Spaltenbreiten auf 0cm ein. Damit das Kombinationsfeld nach dem Wechsel zu einem anderen Datensatz im Formular den Namen der aktuellen Konfiguration anzeigt, fügen wir die folgende Prozedur hinzu, die durch das Ereignis Beim Anzeigen ausgelöst wird:

Private Sub Form_Current()
     Me!cboSchnellauswahl = Me!ConfigurationID
End Sub

Gegebenenfalls ändert der Benutzer die Bezeichnung der Konfiguration. Damit sich dies direkt im Kombinationsfeld zur Schnellauswahl wiederspiegelt, aktualisieren wir dieses, wenn der Benutzer Daten im Formular aktualisiert und gespeichert hat:

Private Sub Form_AfterUpdate()
     Me!cboSchnellauswahl.Requery
End Sub

Aktionen beim Laden des Formulars

Beim Öffnen des Formulars soll dieses den ersten Datensatz anzeigen, der im Feld Default den Wert True enthält – der also als Standardkonfiguration definiert ist. Damit dies geschieht, suchen wir direkt in der Prozedur, die durch das Ereignis Beim Laden ausgelöst wird, mit der FindFirst-Methode des Recordsets des Formulars nach diesem Datensatz. Unabhängig davon, ob dies einen Datensatz findet, soll das Kombinationsfeld cboSchnellauswahl auf den gleichen Datensatz eingestellt werden, den auch das Formular anzeigt. Dafür stellen wir den Wert von Me!cboSchnellauswahl anschließend auf Me!ConfigurationID ein:

Private Sub Form_Load()
     Me.Recordset.FindFirst "Default = True"
     Me!cboSchnellauswahl = Me!ConfigurationID
End Sub

Auswahl einer anderen Konfiguration per Kombinationsfeld

Damit das Formular nach der Auswahl eines anderen Datensatzes über das Kombinationsfeld cboSchnellauswahl den gewünschte Datensatz anzeigt, fügen wir dem Kombinationsfeld eine Prozedur für das Ereignis Nach Aktualisierung hinzu. Diese sieht wie folgt aus und prüft zunächst, ob im Kombinationsfeld überhaupt ein Datensatz ausgewählt ist. Falls ja, sucht die Prozedur mit der FindFirst-Methode des Recordsets des Formulars nach dem betroffenen Datensatz und stellt diesen ein:

Private Sub cboSchnellauswahl_AfterUpdate()
     If Not Nz(Me!cboSchnellauswahl, 0) = 0 Then
         Me.Recordset.FindFirst "ConfigurationID = "  & Me!cboSchnellauswahl
     End If
End Sub

Einstellen der Standardkonfiguration

Das Feld Default der Tabelle tblConfigurations legt fest, welche Konfiguration standardmäßig verwendet werden soll. Das bedeutet schlicht und einfach, dass diese Konfiguration beim Anlegen neuer Mailings für das Fremdschlüsselfeld ConfigurationID der Tabelle tblMailings festgelegt wird. Außerdem soll diese Konfiguration beim Öffnen des Formulars frmConfigurations standardmäßig angezeigt werden, was wir weiter oben bereits realisiert haben.

Mit dem Kontrollkästchen wollen wir dem Benutzer die Möglichkeit bieten, eine andere Konfiguration als Standardkonfiguration festzulegen. Dabei nutzen wir als Erstes die Prozedur, die durch das Ereignis Vor Aktualisierung des Kontrollkästchens chkDefault ausgelöst wird. Diese prüft, ob der Benutzer soeben den Haken aus dem Kontrollkästchen entfernt hat. Falls ja, soll eine Meldung erscheinen, die den Benutzer darauf hinweist, dass er zum Ändern der Standardkonfiguration erst zu der gewünschten Standardkonfiguration wechseln muss und diese dann mit einem Klick auf das Kontrollkästchen mit dem Text Standard festlegen kann. Das Ereignis Vor Aktualisierung nutzen wir deshalb, weil wir hier mit dem Cancel-Parameter einstellen können, dass die Änderung rückgängig gemacht wird, wenn der Benutzer das Kontrollkästchen deaktiviert hat:

Private Sub chkDefault_BeforeUpdate(Cancel As Integer)
     If Not Me!chkDefault Then
         MsgBox "Um eine andere Konfiguration zur  Standardkonfiguration zu machen, aktivieren Sie  diese Option für die gewünschte Konfiguration."
         Cancel = True
     End If
End Sub

Wenn der Benutzer hingegen das Kontrollkästchen chkDefault aktiviert hat, soll die aktuell angezeigte Konfiguration als Standardkonfiguration eingestellt werden. In diesem Fall feuert auch noch das Ereignis Nach Aktualisierung des Kontrollkästchens, was die folgende Prozedur auslöst:

Private Sub chkDefault_AfterUpdate()
     Dim db As DAO.Database
     If Me!chkDefault Then
         Set db = CurrentDb
         db.Execute "UPDATE tblConfigurations  SET Default = 0 WHERE NOT ConfigurationID = "  & Me!ConfigurationID, dbFailOnError
     End If
End Sub

Diese Prozedur prüft, ob chkDefault den Wert True hat, also ob der Benutzer das Kontrollkästchen für diesen Datensatz aktiviert hat. Falls ja, führt die Prozedur mit der Execute-Methode des Database-Objekts eine Abfrage aus, die den Wert des Feldes Default für alle anderen Datensätze der Tabelle tblConfigurations auf 0 einstellt. Damit ist sichergestellt, dass das Feld Default nur für den aktuell angezeigten Datensatz den Wert True aufweist.

Löschen einer Konfiguration

Mit einem Klick auf die Schaltfläche cmdLoeschen kann der Benutzer die aktuelle Konfiguration löschen. Dazu löst die Schaltfläche die folgende Prozedur aus. Diese löscht den aktuellen Datensatz und versucht danach, den Datensatzzeiger auf den ersten Datensatz einzustellen, dessen Feld Default den Wert True aufweist:

Private Sub cmdLoeschen_Click()
     RunCommand acCmdDeleteRecord
     Me.Recordset.FindFirst "Default = True"
End Sub

Anlegen einer neuen Konfiguration

Um eine neue Konfiguration anzulegen, muss der Benutzer nur auf die Schaltfläche cmdNeu klicken. Diese springt dann zu einem neuen, leeren Datensatz:

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

Schließen des Formulars

Ein Klick auf die Schaltfläche cmdOK ruft die DoCmd.Close-Methode auf und schließt das aktuelle Formular:

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

Wenn Sie in die Formularansicht wechseln und einen Datensatz eingegeben haben, sieht dieses wie in Bild 3 aus.

Das Formular frmConfigurations in der Formularansicht

Bild 3: Das Formular frmConfigurations in der Formularansicht

Kennwort verbergen

Damit das Textfeld Password das Kennwort nicht direkt anzeigt, sondern Sternchen als Platzhalter verwendet, stellen wir die Eigenschaft Eingabeformat auf Kennwort ein.

Formular zum Verwalten der Mailings

Das Formular frmMailings dient zum Verwalten der Mailings. Es verwendet die Tabelle tblMailings als Datensatzquelle. Aus dieser Tabelle haben wir alle Felder in den Detailbereich der Entwurfsansicht gezogen.

Für die in Bild 4 markierten Felder stellen wir die Eigenschaft Horizontaler Anker auf den Wert Beide ein. So können wir die Felder vergrößern, indem wir die Breite des Formulars vergrößern. Anschließend müssen Sie die Bezeichnungsfelder dieser Steuerelemente markieren und für diese die Eigenschaft Horizontaler Anker auf Links einstellen, da diese durch die vorherige Einstellung auf Rechts festgelegt wurde.

Das Formulars frmMailings in der Entwurfsansicht

Bild 4: Das Formulars frmMailings in der Entwurfsansicht

Eines der Felder können wir außerdem in der Höhe anpassbar machen. Das ist für das Feld TextBody am sinnvollsten. Daher stellen wir seine Eigenschaft Vertikaler Anker auf Beide ein. Auch hier müssen wir die Eigenschaft Vertikaler Anker für das entsprechende Bezeichnungsfeld wieder auf Oben festlegen. Außerdem müssen wir die Eigenschaft Vertikaler Anker für alle Felder, die sich unterhalb des Textfeldes TextBody befinden, auf Unten einstellen, da diese sonst beim Vergrößern der Höhe des Formulars vom Textfeld TextBody überlappt werden.

Die Beschriftungen der Bezeichnungsfelder wurden bisher von den Feldnamen übernommen, diese passen wir jedoch auch noch an (noch nicht im Screenshot sichtbar).

Listenfeld für die Anhänge

Sie sehen die geänderten Bezeichnungen in Bild 5. Hier sehen Sie auch, wie Sie das Textfeld für die Anzeige der Daten des Feldes Attachments in ein Listenfeld umwandeln können – und zwar über das Kontextmenü. Anschließend ändern Sie noch den Namen des Listenfeldes in lstAttachments. Leider können wir die Bindung des Listenfeldes an das Feld Attachments danach nicht mehr nutzen, denn ein Listenfeld bindet man in der Regel an eine Datensatzherkunft wie eine Tabelle oder Abfrage. Deshalb bauen wir das Listenfeld ein wenig um. Als Erstes entfernen Sie den Inhalt der Eigenschaft Steuerelementinhalt. Dann stellen Sie die Eigenschaft Herkunftstyp auf Wertliste ein. Schließlich sorgen wir dafür, dass beim Wechseln des Datensatzes im Formular der Inhalt des Feldes Attachments als Wert des Listenfeldes eingestellt wird.

Ändern des Textfeldes für die Anhänge in ein Listenfeld

Bild 5: Ändern des Textfeldes für die Anhänge in ein Listenfeld

Dazu legen wir die Prozedur Form_Current mit der folgenden Anweisung an:

Private Sub Form_Current()
     Me!lstAttachments.RowSource = Me!Attachments
End Sub

Damit zeigt das Listenfeld bei jedem Datensatzwechsel automatisch die enthaltenen Attachments an.

Attachments hinzufügen

Dem Listenfeld lstAttachments stellen wir eine Schaltfläche namens cmdHinzufuegen zur Seite, welche die Ereignisprozedur aus Listing 1 auslöst. Diese stellen wir in ähnlicher Form im Beitrag E-Mails mit Anlagen mit Outlook versenden (www.access-im-unternehmen.de/1357) vor. Wir mussten allerdings einige Anpassungen vornehmen, da unser Listenfeld wie oben beschrieben nicht die Daten einer eigenen Tabelle oder Abfrage anzeigt, sondern den Inhalt des Feldes Attachment als Wertliste. Deshalb arbeiten wir beim Hinzufügen nicht mit der AddItem-Methode des Listenfeldes, sondern fügen die im Dateiauswahl-Dialog selektierten Daten dem Text aus dem Feld Attachments der Tabelle tblMailings hinzu, sofern die jeweilige Datei dort noch nicht enthalten ist. Für die Nutzung des Dateiauswahl-Dialogs fügen Sie dem VBA-Projekt noch einen Verweis auf die Bibliothek Microsoft Office x.0 Object Library hinzu.

Private Sub cmdHinzufuegen_Click()
     Dim objFileDialog As FileDialog
     Dim l As Long, Dim m As Long
     Dim bolVorhanden As Boolean
     Dim strAttachments As String
     Dim varAttachment As Variant
     strAttachments = Me!lstAttachments.RowSource
     Set objFileDialog = FileDialog(msoFileDialogFilePicker)
     With objFileDialog
         .AllowMultiSelect = True
         .Title = "Anlagen auswählen"
         .Filters.Clear
         .Filters.Add "Alle Dateien", "*.*"
         .ButtonName = "Hinzufügen"
         If .Show = True Then
             For l = 1 To .SelectedItems.Count
                 If Not Len(Me!lstAttachments.RowSource + .SelectedItems(l)) > 32750 Then
                     bolVorhanden = False
                     For Each varAttachment In Split(strAttachments, ";")
                         If varAttachment = .SelectedItems(l) Then
                             bolVorhanden = True
                             Exit For
                         End If
                     Next varAttachment
                     If Not bolVorhanden Then
                         strAttachments = strAttachments & ";" & .SelectedItems(l)
                     End If
                     If Left(strAttachments, 1) = ";" Then
                         strAttachments = Mid(strAttachments, 2)
                     End If
                 Else
                     MsgBox "Es können keine weiteren Dateien hinzugefügt werden."
                     Exit Sub
                 End If
             Next l
         End If
     End With
     Me!lstAttachments.RowSource = strAttachments
     Me!Attachments = strAttachments
End Sub

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

TestzugangOder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar