Automatisch E-Mails versenden mit CDO

15. Mai 2013

Für den automatischen Versand von E-Mails per VBA bieten sich auf den ersten Blick zwei Möglichkeiten an:

  • DoCmd.SendObject
  • Generieren und Versenden der E-Mail per Outlook

Gegen diese Möglichkeiten sprechen folgende Argumente:

  • Bei Anwendung der SendObject-Methode ist es für den Entwickler hinderlich, dass der Benutzer eine Warnmeldung erhält und dem Versand explizit zustimmen muss. Verweigert er die Zustimmung, wird die E-Mail nicht versendet. Diese Methode eignet sich deshalb z.B. nicht, um den Datenbank-Entwickler - vom Benutzer unbemerkt - über ein Problem zu informieren.
  • Das Versenden einer E-Mail per Outlook funktioniert inzwischen ohne Interaktion mit dem Benutzer, allerdings setzt es voraus, dass Outlook bzw. Exchange Server in der aktuellen Umgebung installiert und eingerichtet ist, was z.B. auf einem Terminalserver nicht unbedingt der Fall ist. Außerdem erscheinen die versendeten E-Mails im Postfach desjenigen, dessen Account verwendet wurde.

E-Mails mit CDO

Eine elegante Lösung für den automatischen Versand von Emails ohne Outlook bieten die Microsoft Collaboration Data Objects (CDO). Eine einfache E-Mail im Nur-Text-Format kann über einen lokalen SMTP-Server z.B. folgendermaßen versendet werden:

Public Function EmailVersand()

Dim OutMail As Object
Dim Schema As String

Const cdoSendUsingPort = 2 ' send the message using the network (SMTP over the network)
Const cdoAnonymous = 0     ' do not authenticate

  Set OutMail = CreateObject("CDO.Message")
  Schema = "http://schemas.microsoft.com/cdo/configuration/"

  With OutMail
    .From = <EmailAbsender>
    .To = <EmailEmpfänger>
    .Subject = <Betreff>
    .BodyPart.Charset = "iso-8859-1"
    .TextBody = "Guten Tag, dies ist ein Test."
    With .Configuration.Fields
      .Item(Schema & "sendusing") = cdoSendUsingPort
      .Item(Schema & "smtpserver") = <Server>
      .Item(Schema & "smtpserverport") = 25
      .Item(Schema & "smtpauthenticate") = cdoAnonymous
      .Update
    End With
    .Send
  End With

  Set OutMail = Nothing
  
  Exit Function

End Function

Wird ein externer SMTP-Server verwendet, so muss man noch die Authentifizierung ergänzen:

Const cdoBasic = 1  ' use basic (clear-text) authentication

      ...
      .Item(Schema & "smtpauthenticate") = cdoBasic
      .Item(Schema & "sendusername") = <EmailAccount>
      .Item(Schema & "sendpassword") = <Password>
      ...

Man kann aber auch leicht eine E-Mail mit HTML-Formatierung erstellen, indem man anstelle von .TextBody die Eigenschaft .HTMLBody verwendet:

    .HTMLBody = <html><p>Guten Tag, dies ist ein Test.</p></html>"

Über die Eigenschaft .AddAttachment kann man Dateien als Anhang hinzufügen:

    .AddAttachment = <Datei1>
    .AddAttachment = <Datei2>

Möchte man in einer E-Mail im HTML-Format ein Bild anzeigen, so muss man dieses als eingebettetes Content-Element hinzufügen und kann es dann unter der vereinbarten ID im Body der E-Mail verwenden:

Dim BP As Object

Const CdoReferenceTypeName = 1

...

 Set BP = OutMail.AddRelatedBodyPart("<Grafikdatei>",  _
         "pic1.jpg", CdoReferenceTypeName)
 BP.Fields.Item("urn:schemas:mailheader:Content-ID") = _
         "<pic1.jpg>"
 BP.Fields.Update

  ...

    .HTMLBody = "<html><img src="cid:pic1.jpg" /></html>"

Infos zu allen Parametern zur Konfiguration von CDO findet man im
» Microsoft Developer Network.