Mail mit VBA generieren mit angehängten PDF

Moderator: ModerationP

Mail mit VBA generieren mit angehängten PDF

Beitragvon Prinzessin87 » 23. Aug 2021, 14:55

Hallo Ihr Lieben,

ich arbeite nun wieder an meinem Programm weiter nach einem Jahr Pause und musste feststellen das ich wieder voll verwirrt bin :roll:
Hoffe ihr könnt mir hier wieder den richtigen Weg zeigen :oops:

Also die Programierung funktioniert! Meine Kollegen haben aber mitgeteilt dass die Schriftart nicht die gleiche ist wie in der Mail die Signatur

Hier mal den Code für der die Nachricht generiert: HIER MUSS DER FEHLER LIEGEN - Hab damals die zusammensetzung auch herumprobiert, hat wohl mal funktioniert... Kennt sich wer mit HTML in VBA aus, HTML Hilfen im Internet haben mir hierbei nicht weitergeholfen :cry:
Code: Alles auswählen
'für HTML-Textnachricht (ggf. mit einem HTML-Editor erzeugen)
11830 strNachricht = "<HTML>" & "<Font Face=Century Gothic>" & strAnrede & " " & strAnsprechpartner & ", <br /><br />" _
                & "<HTML>" & "<Font Face=Century Gothic>" & strText


Diese zusammengesetzte Nachricht wird dann abgefragt:
Code: Alles auswählen
12020      Call PDFBerichtPerMail(strReportName, strWhereCondition, strDateipfadlaufend, _
                        strEmpfänger, strCCEmpfänger, strBetreff, strNachricht, True)


Hier das Modul dazu: (leider gibt es anscheinend die Seite dbwiki.net nicht mehr :cry: )
Code: Alles auswählen
'https://dbwiki.net/wiki/VBA_Tipp:_Bericht_als_PDF_per_Mail_ueber_Outlook_versenden

Public Sub PDFBerichtPerMail(ByVal Berichtsname As String, _
                             ByVal WhereCondition As String, _
                             ByVal Dateipfad As String, _
                             ByVal Empfänger As String, _
                             ByVal CCEmpfänger As String, _
                             ByVal Betreff As String, _
                             ByVal Nachricht As String, _
                             Optional HTML As Boolean = False, _
                             Optional SofortSenden As Boolean = False)
       
       'Bericht per Mail als pdf-Datei-Anhang über Outlook versenden
       'Late-Binding-Variante, kein Verweis auf Microsoft Outlook xx.x Object Library notwendig
       'Quelle: www.dbwiki.net oder www.dbwiki.de
       
       Dim objApp As Object   'Outlook Application
       Dim objItem As Object  'Nachrichten Objekt
       Dim Signatur As String  'Alte Nachricht speichern

       Const olMailItem = 0
       Const olFormatPlain = 1
       Const olFormatHTML = 2
       
       
       'Schritt 1: Bericht als pdf-Datei erzeugen

       'Bericht gefiltert öffnen
4450   DoCmd.OpenReport Berichtsname, acViewPreview, , WhereCondition, acHidden
       
       'pdf-Datei erzeugen
4460   DoCmd.OutputTo acOutputReport, Berichtsname, acFormatPDF, Dateipfad

       'Bericht schließen
4470   DoCmd.Close acReport, Berichtsname, acSaveNo

       
       'Schritt 2: pdf-Datei per Outlook-Anhang versenden
       'Hinweis: Wenn ein Parameterwert direkt aus einem Formularfeld ausgelesen werden soll,
       'muß die Eigenschaft .Value explizit gesetzt werden, z.B. objItem.To = Me!MeinTextfeld.Value
       
       'Erzeugen einer Outlook-Instanz
4480   Set objApp = CreateObject("Outlook.Application")
       
       'Erzeugen einer Mail-Nachricht
4490   Set objItem = objApp.CreateItem(olMailItem)
4500   objItem.GetInspector.Display

       'Alte Nachricht = Signatur speichern
      ' objItem.HTMLBody = Signatur
4510   Signatur = objItem.HTMLBody
       
        'Empfänger
4520   objItem.To = Empfänger
       
       'CC Empfänger
4530   objItem.CC = CCEmpfänger
       
       'Betreff
4540   objItem.Subject = Betreff
       
       'Nachricht im HTML-Format
4550   If HTML = True Then
4560     objItem.BodyFormat = olFormatHTML
4570     objItem.HTMLBody = Nachricht & objItem.HTMLBody
         
       
       'Nachricht im Plaintext-Format
4580   Else
4590     objItem.BodyFormat = olFormatPlain
4600     objItem.Body = Nachricht
4610   End If
       
       'Anhang anfügen
4620   objItem.Attachments.Add Dateipfad
       
       'Mail sofort versenden, ohne Outlook zu öffnen
4630   If SofortSenden = True Then
4640     objItem.Send
       'Mail in Outlook anzeigen, manuell versenden
4650   Else
4660     objItem.Display
4670   End If
       
4680   Set objItem = Nothing
4690   Set objApp = Nothing
       
End Sub
GLG Prinzessin87
------------------------------------------------------------
Wichtig ist, dass man nicht aufhört zu fragen.
(Albert Einstein, 1879-1955)
Prinzessin87
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 220
Registriert: 01. Jul 2016, 17:31

Re: Mail mit VBA generieren mit angehängten PDF

Beitragvon DerHoepp » 23. Aug 2021, 15:16

Hallo Prinzessin,

Code: Alles auswählen
<html>irgendwas<html>

ist kein valides HTML. HTML-Elemente stehen in aller Regel zwischen einem öffnenden und einem schließenden Tag:
Code: Alles auswählen
<html>irgendwas</html>

Dabei ist das html-Tag die allumschließende Klammer für ein gesamtes HTML-Dokument. Ein fast leeres Outlook Mail-Item-Objekt (ohne Signatur und ohne eingeschaltete Nutzung von CSS) sieht im .htmlBody dabei so aus (Einrückungen von mir.:
Code: Alles auswählen
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
    <HEAD>
        <META NAME="Generator" CONTENT="MS Exchange Server version rmj.rmm.rup.rpr">
        <TITLE></TITLE>
    </HEAD>
    <BODY>
        <!-- Converted from text/rtf format -->
        <P><FONT FACE="Calibri">Hier der fast leere Text</FONT>
        </P>
    </BODY>
</HTML>

In deinem Code fehlt also mindestens der schließende Font-Tag. Wenn allerdings CSS in Outlook eingeschaltet ist, solltest du ohnehin auf Font-Tags verzichten und statt dessen entweder die genutzten Formatvorlagen verwenden, oder Inline-CSS nutzen. Beim Umgang mit der Signatur in Outlook, die du nach dem .GetInspector erhältst, möchte ich aber nochmal drauf hinweisen, das das zusammenbasteln des HTML-Bodys mit Verkettungen zu invalidem HTML-Quellcode führt: viewtopic.php?f=165&t=832748

Sei es drum; long story short: Für ein ordentliches Ergebnis empfiehlt es sich erstmal den .HTMLBody zu analysieren, der nach dem .GetInspector im MailItem steht und anschließend deinen zusätzlichen Text mit den richtigen Formatierungen oder CSS-Elementen in den Quelltext an der richtigen Stelle einzufügen. Alternativ kannst du natürlich auch das Word-Objektmodell nutzen. Outlook verwendet Word als Standard-Mail-Editor. Zugriff auf das Objektmodell erhältst du über MailItem.GetInspector.WordEditor

Viele Grüße
derHöpp
DerHoepp
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 9852
Registriert: 14. Mai 2013, 11:08

Re: Mail mit VBA generieren mit angehängten PDF

Beitragvon Prinzessin87 » 25. Aug 2021, 08:50

Vielen Dank für deinen Beitrag,
habe mir deine Verlinkung auch angesehen nur leider die Hälfte verstanden :cry:

Ich habe den Code damals ja selbst aus dem Forum und nicht ganz verstanden, er hat ja ganz gut funktioniert...

Ich habe mal ein paar Grundfragen:

1.) Im Modul wird angegeben das ein Verweis "Microsoft Outlook xx.x Object Library " nicht gebraucht wird - das ist ja gut oder? Bin des öfteren auf probleme gestoßen da in der Firma verschiedene Widnows laufen an den Rechnen und die Anwenderdatei dan bei einigen Problemen machte.

2.) Die Signatur wird ja beim öffnen von Outlook beibehalten oder wird diese neu generiert? Welche Absatz ist das überhaupt im Modul, konnte keinen Zusammenhang feststellen

3.) wäre es besser die Signatur auch über Access zu steuern (Also bei jedem Mitarbeiter seperat hinterlege und diese dann abrufe? geht das dann ohne HTML?

4.) Die Info mit Word im Outlook im Hintergrund hat mir jetzt irgendwie nicht geholfen, was genau sagt mir diese Information und wie kann ich diese nutzen.
Wie nutzt man den "MailItem.GetInspector.WordEditor"?
Muss ganz ehrlich sagen, ich habe von den Modulen jetzt nicht so viel ahnung und hatte hier oft hilfe aus dem Forum, daher sind sie ja so gut auskommentiert :oops:

Vielen Dank im Voraus für deine Mühe. Hoffe du kannst mir hier weiterhelfen

LG
GLG Prinzessin87
------------------------------------------------------------
Wichtig ist, dass man nicht aufhört zu fragen.
(Albert Einstein, 1879-1955)
Prinzessin87
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 220
Registriert: 01. Jul 2016, 17:31

Re: Mail mit VBA generieren mit angehängten PDF

Beitragvon Bitsqueezer » 25. Aug 2021, 10:40

Hallo,

zu 1.): Ja, das macht den Code flexibler, weil das Outlook verwendet wird, was auf dem Zielrechner installiert ist. Mit der Windows-Version hat das nichts zu tun, nur mit der Office-Version. Nachteil ist, daß der Compiler bei Verwendung von "Object" nichts überprüfen kann, Du mußt also Deinen Code gründlich testen, um sicherzustellen, daß alle Eigenschaften und Methoden der verwendeten Objekte funktionieren. Dabei kann es natürlich dazu kommen, daß eine neuere Outlook-Version ältere davon nicht mehr verwenden (eher selten) oder neuere Versionen einen neuen Weg verwenden, um die frühere Funktionalität durchführen zu können. Mal als grobes Beispiel, wenn MS sich entschließen würde, Word als Editor rauszuwerfen und gegen einen ganz anderen zu ersetzen.

zu 2.): Outlook fügt die Signatur in eine neue Nachricht automatisch ein. Der Code speichert daher den HTML-Text der Mail als Variable "Signatur". Er wird dann aber nirgendwo mehr verwendet, das bringt also nix. Stattdessen setzt der Autor hier "objItem.HTMLBody" dazu, also kann man das entweder gegen den Inhalt von "Signatur" ersetzen oder die Zeile (und die Variablendeklaration) mit "Signatur" rausschmeißen.

zu 3.): Nö..:) Denn die Signatur ist ja bei jedem individuell eingestellt und kann jederzeit verändert werden - also wozu das Rad neu erfinden? Etwas Anderes wäre es, wenn Access eine allgemeine Signatur unter die Mail setzen soll, die bei jeder Mail gleich ist und nicht auf einen speziellen Mitarbeiter zielt. Klar geht eine Signatur (auch in einer HTML-Mail) ohne HTML, aber warum auf die Formatierungsmöglichkeiten verzichten?

zu 4.): Das soll Dir sagen, daß hinter "WordEditor" das ganze Objektmodell von Word steckt. Du kannst also alles, was Du mit einem als Word-Application deklarierten Objekt machen könntest (also etwa eine Word-Automation zum Erstellen eines Briefes in Word), mit diesem Objekt auch in einer Outlook-Mail machen.
Da im Ergebnis aber ohnehin so oder so eine HTML-Mail generiert wird, kannst Du auch darauf verzichten und alles selbst mit HTML codieren, wo es notwendig ist. Kommt auf den Aufwand an - eine HTML-Tabelle in HTML zu erzeugen, ist in VBA schon ein ganz schöner Aufwand, wohingegen das Einfügen einer Tabelle über die Word-Methoden sicherlich einfacher ist und durch komplexe CSS-Styles auch schöner (oder besser: einfacher) zu formatieren ist.
Die CSS-Styles werden in einer von Outlook generierten HTML-Mail im Head-Bereich automatisch nach den in Outlook/Word definierten Vorgaben erstellt, weswegen eine HTML-Outlook-Mail selbst ohne Text schon ein paar KB groß ist, weil immer alle Styles eingefügt werden, ob sie verwendet werden oder nicht.
Die Styles kannst Du auch für eigene Formatierungen im HTMLBody einsetzen, um zu wissen, welche es gibt, kannst Du Dir einfach den Quelltext einer Outlook-Mail unter Eigenschaften in Outlook anzeigen lassen/in einen Editor rauskopieren.
Für das alles brauchst Du aber HTML- und CSS-Kenntnisse und mußt eben wissen, welche Styles in dem verwendeten Outlook zur Verfügung stehen.
Auf der anderen Seite kannst Du eben einfach auf das "WordEditor"-Objekt zugreifen und damit einen Text z.B. in fett formatieren lassen und das WordEditor-Objekt kümmert sich dann selbst um die Zuweisung der richtigen Styles.

Welche Eigenschaften und Methoden aus Word Du dazu brauchst, kannst Du einfach in Word ausprobieren: Word starten, die Makroaufzeichnung starten und dann die Operationen durchführen und danach im Makro "spinxen".

Gruß

Christian
Bitsqueezer
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 8495
Registriert: 21. Jun 2007, 12:17

Re: Mail mit VBA generieren mit angehängten PDF

Beitragvon DerHoepp » 25. Aug 2021, 11:01

Hallo noch einmal,

1.) Im Modul wird angegeben das ein Verweis "Microsoft Outlook xx.x Object Library " nicht gebraucht wird - das ist ja gut oder? Bin des öfteren auf probleme gestoßen da in der Firma verschiedene Widnows laufen an den Rechnen und die Anwenderdatei dan bei einigen Problemen machte.

Für die Entwicklung würde ich die Bibliothek in jedem Fall einschalten. Dann hast du alle Konstanten zur Verfügung und bei der Entwicklung zusätzlich die Automatische vervollständigung von Objekten und ihren Eigenschaften. Unterschiedliche Windowsversionen sollten da aber ohnehin kein Problem sein, solang überall Outlook installiert ist.

2.) Die Signatur wird ja beim öffnen von Outlook beibehalten oder wird diese neu generiert? Welche Absatz ist das überhaupt im Modul, konnte keinen Zusammenhang feststellen
3.) wäre es besser die Signatur auch über Access zu steuern (Also bei jedem Mitarbeiter seperat hinterlege und diese dann abrufe? geht das dann ohne HTML?

Die Signatur wird von Outlook normalerweise im Verzeichnis BenutzerName\AppData\Roaming\Microsoft\Signatures\ als HTML-Datei gespeichert. Beim erstellen einer neuen Mail innerhalb der grafischen Benutzeroberfläche "zieht" Outlook sich dann die in den Optionen eingestellte Standardsignatur für das jeweilige Postfach und trägt diese im HTML-Format in den Body der E-Mail ein. Weil das nur in der grafischen Benutzeroberfläche funktioniert, musst du dir in VBA helfen. Der gängige Weg dazu ist es, die Verwendung der grafischen Benutzeroberfläche zu simulieren. Dazu wird die .GetInspector()-Eigenschaft des MailItem-Objektes aufgerufen. Die sorgt dafür, dass Outlook so tut, als wäre die Mail über die grafische Benutzeroberfläche erstellt worden. Ein Inspector ist in der Outlook-VBA-Sprechweise ein Outlookfenster. .GetInspector() gibt dir also das Fenster der zu verfassenden Mail zurück. Weil du die Eigenschaft aber nur aufrufst, damit Outlook die Standard-Signatur einfügst, kannst du den Rückgabewert (das ist ein Objekt vom Typ Inspector) auch einfach fallenlassen, in dem du die Property wie eine Sub verwendest (Das DB-WIKI nutzt stattdessen die .Display-Eigenschaft des Inspector-Objekts, die das Fenster (jetzt mit Standardsignatur) anzeigt). Nachdem du .GetInspector() abgefragt hast, steht die Signatur in der .HTML-Body-Eigenschaft des MailItem.

Eine alternative Methode wäre es, die Standardsignatur als HTML-Quelltext aus dem AppData-Ordner auszulesen, zu modifizieren und anschließend in die .HTML-Body-Eigenschaft einzufügen. Die könntest du natürlich auch in Access ablegen (allerdings auch als HTML, sonst wäre sie nicht formatiert), aber dann musst du Sie an mehreren Stellen pflegen.

Das Problem an beiden/allen drei Methoden ist, dass der HTML-Body ein geschlossenes HTML-Dokument enthält (ein Beispiel des Quelltextes siehst du in dem verlinkten Thread). Hier mal sehr stark vereinfacht:
Code: Alles auswählen
<html>
   <head>
      <title>Eine Beispiel Mail</title>
      <style>
         /* Standard-Schriftart und Größe */
         p {
            font-family:'Arial',sans-serif;
            font-size:14pt;
         }
      </style>
   </head>
   <body>
      <p style="font-family:'Times New Roman';">Mit freundlichen Gr&uuml;&szlig;en</p>
      <p style="font-family:'Times New Roman';">Mia Mitarbeiter</p>
      <p style="font-family:'Times New Roman';"><span style="font-weight:bold;font-family:'Times New Roman';">Formidable Firma</span><br \>
            Weiter Weg 6<br \>
            12345 Ortsrandlage
      </p>
   </body>
</html>


Wenn du jetzt einen Mail-Text davorsetzt:
Code: Alles auswählen
.HTMLBody = "Hallo Karlo Kunde,<br \> Deine Bestellung ist eingegangen und wird von mir bearbeitet, schau dir dazu das Dokument an!" & .HTMLBody

sieht dein .HTMLBody plötzlich so aus:
Code: Alles auswählen
Hallo Karlo Kunde,<br \> Deine Bestellung ist eingegangen und wird von mir bearbeitet, schau dir dazu das Dokument an!<html>
   <head>
      <title>Eine Beispiel Mail</title>
      <style>
         /* Standard-Schriftart und Größe */
         p {
            font-family:'Arial',sans-serif;
            font-size:14pt;
         }
      </style>
   </head>
   <body>
      <p style="font-family:'Times New Roman';">Mit freundlichen Gr&uuml;&szlig;en</p>
      <p style="font-family:'Times New Roman';">Mia Mitarbeiter</p>
      <p style="font-family:'Times New Roman';"><span style="font-weight:bold;font-family:'Times New Roman';">Formidable Firma</span><br \>
            Weiter Weg 6<br \>
            12345 Ortsrandlage
      </p>
   </body>
</html>

Wie du siehst, hast du deinen selbst erstellten Text nicht in das HTML-Dokument integriert, sondern einfach davorgeklatscht. Du bist jetzt davon abhängig, was der Empfänger daraus macht. Ob die Formatierungsangaben so angewandt werden, wie du denkst oder beabsichtigst, ist reiner Zufall. Was du eigentlich erreichen möchtest ist das:
Code: Alles auswählen
<html>
   <head>
      <title>Eine Beispiel Mail</title>
      <style>
         /* Standard-Schriftart und Größe */
         p {
            font-family:'Arial',sans-serif;
            font-size:14pt;
         }
      </style>
   </head>
   <body>
      <p>Hallo Karlo Kunde,<br \>
         Deine Bestellung ist eingegangen und wird von mir bearbeitet, schau dir dazu das Dokument an!
      </p>
      <p style="font-family:'Times New Roman';">Mit freundlichen Gr&uuml;&szlig;en</p>
      <p style="font-family:'Times New Roman';">Mia Mitarbeiter</p>
      <p style="font-family:'Times New Roman';"><span style="font-weight:bold;font-family:'Times New Roman';">Formidable Firma</span><br \>
            Weiter Weg 6<br \>
            12345 Ortsrandlage
      </p>
   </body>
</html>

Der Text ist nun ordentlich integriert und wird in der Absatz-Standard-Formatvorlage dargestellt.
4.) Die Info mit Word im Outlook im Hintergrund hat mir jetzt irgendwie nicht geholfen, was genau sagt mir diese Information und wie kann ich diese nutzen.

Wenn du nicht mit HTML-Quelltexten arbeiten willst, kannst du als weitere Alternative einfach Word benutzen. Outlook arbeitet intern mit Word. Wie schon die Signatur, erhältst du Zugriff auf das Word-Objektmodell allerdings nur über die grafische Benutzeroberfläche von Outlook. Du musst also erstmal wieder mit .GetInspector() das Fenster abrufen. .GetInspector gibt dir ein Inspector-Objekt zurück, dieses hat eine .WordEditor()-Eigenschaft, die ein Word-Document-Object darstellt. Statt also HTML-Quelltexte zu verändern, kannst du ein Worddokument bearbeiten (Code ungetestet):
Code: Alles auswählen
With objItem.GetInspector.WordEditor()
    With .Paragraphs.Add(.Paragraphs(1).Range)
        .Range.Text = "Hallo Karlo Kunde," & vbCrLf & "Deine Bestellung ist eingegangen und wird von mir bearbeitet, schau dir dazu das Dokument an!"
    End With
End With

Damit hast du nebenbei einen gültigen HTML-Quelltext geschrieben, musst dich aber stattdessen ein bisschen in das Word-Objektmodell einarbeiten.

Ich hoffe, ich konnte noch mehr unklarheit reinbringen :D

Viele Grüße
derHöpp
DerHoepp
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 9852
Registriert: 14. Mai 2013, 11:08


Zurück zu Access Forum (provisorisch)

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 11 Gäste