Outlook-Workshop - PDF-Datei erstellen, als ZIP senden

Immer wieder mal gefragt: Wie kann man eine Arbeitsmappe (oder Tabelle) als PDF speichern?

Wärend man ab Office 2007 die integrierte Funktion ExportAsFixedFormat nutzen kann, haben wir diese Möglichkeit in älteren Office-Versionen nicht. Auch ist nicht immer bekannt, welches ZIP-Programm andere Anwender nutzen. In diesem Tutorial lernen wir, wie wir eine PDF-Datei erstellen und diese als ZIP-Archiv gepackt über Outlook versenden können.

Was wir benötigen:

1. Microsoft Outlook
2. Den kostenlosen PDF-Creator von PDFForge
3. Das kostenlose DotNetZip von cheeso

Beide Programme herunterladen und installieren. Dann können wir mit der Programmierung beginnen. Da der PDF-Creator nicht selbstständig PDF-Dateien als ZIP-Archiv packen kann, müssen wir uns einer externen Routine bedienen. Hierfür eignet sich m.E. die DotNetZIp besser, da wir dann nicht für alle erdenklichen ZIP-Programme eine passende ZIP-Routine erstellen müssen und uns somit einiges an Programmierarbeit sparen können. Ab Officw 2007 können wir zwar "ExportAsFixedFormat" einsetzen. Aber wer auch für ältere Office-Versionen programmieren muss, kommt mit externen Hilfsprogrammen weiter.

----------------------------------------
Zum Erstellen der PDF-Datei, des ZIP-Archives und der Outlook-Mail nutzen wir jeweils getrennte Funktionen. Das hat den Vorteil dass die Funktionen (auf Wunsch) auch jeweils separat genutzt werden können. Die erforderlichen Parameter werden dabei von der aufrufenden Prozedur übergeben.

----------------------------------------
Beginnen wir mit dem Modulkopf. In diesem den folgenden Code. Option Private Module ist immer dann zu setzen, wenn die Funktioen und Makros nicht im Makrodialog und Funktionsassistenten gezeigt werden sollen. Die Funktion "Sleep" benötigen wir für die Wartezeiten bei der Erstellung der PDF-Datei.

Option Private Module
Option Explicit
#If Win64 And VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
#Else
Public Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
#End If



----------------------------------------

Kommen wir nun zur aufrufenden Prozedur. In dieser legen wir fest, was als PDF-Datei exportiert und dann als ZIP-Archiv gepackt werden soll. Im Beispiel wird die aktive Arbeitsmappe ausgegeben. Im ersten Schritt trennen wir die Dateiendung vom Dateinamen. Dieser Dateiname wird für die PDF-Datei und das ZIP-Archiv genutzt. Im zweiten Schritt legen wir den Pfad für die Dateien fest. Im letzen Schritt beauftragen wir das Erstellen der PDF-Datei.

Public Sub AktiveMappeAlsZIPFileSenden()
Dim FileName   As String
Dim FilePath   As String
Dim FileFormat As String

FileName = Left(ActiveWorkbook.Name, InStr(1, ActiveWorkbook.Name, ".") - 1)
FilePath = ActiveWorkbook.Path & "\"

CreatePDFFile FilePath, FileName
End Sub


----------------------------------------

Zuerst erstellen wir die PDF-Datei. Hierbei erstellen wir das PDFCreator-Objekt per Late-Binding, also zur Laufzeit der Prozedur. Pfad und Dateiname werden von der "Hauptprozedur" übergeben.

Rem PDF-Datei erstellen 
Public Function CreatePDFFile(PDFPath As String, PDFName As String)

Dim PDFCreator1 As Object

Set PDFCreator1 = CreateObject("PDFCreator.clsPDFCreator")
    With PDFCreator1
        If .cStart("/NoProcessingAtStartup") = False Then
            MsgBox "Can't initialize PDFCreator.", vbCritical + _
                vbOKOnly, "PrtPDFCreator"
            Exit Function
         End If
           .cOption("UseAutosave") = 1
           .cOption("UseAutosaveDirectory") = 1
           .cOption("AutosaveDirectory") = PDFPath
           .cOption("AutosaveFilename") = PDFName & ".pdf"
           .cOption("AutosaveFormat") = 0
           .cClearCache
    End With

ActiveWorkbook.PrintOut copies:=1, ActivePrinter:="PDFCreator"

    Do Until PDFCreator1.cCountOfPrintjobs = 1
             DoEvents
             Sleep 1000
    Loop
             Sleep 1000
             PDFCreator1.cPrinterStop = False
    Do Until PDFCreator1.cCountOfPrintjobs = 0
             DoEvents
    Loop
             PDFCreator1.cClose
             
CreateZIPFile PDFPath, PDFName
End Function


----------------------------------------

Nach dem Erstellen der PDF-Datei wird automatisch die Funktion zum Erstellen des ZIP-Archives aufgerufen. Wer möchte kann eine Abfrage einbauen, ob überhaupt ein ZIP-Archiv erstellt werden soll.

Rem PDF-Datei in ZIP-Archiv packen 
Public Function CreateZIPFile(ZIPPath As String, ZIPName As String)
Dim ZipApp      As Object
Dim ZIPPassword As String

ZIPPassword = ""

Set ZipApp = CreateObject("Ionic.Zip.ZipFile")
    With ZipApp
       If ZIPPassword <> "" Then
         .Encryption = 3
         .Password = ZIPPassword
       End If
         .AddFile (ZIPPath & ZIPName & ".pdf")
         .Name = ZIPPath & ZIPName & ".zip"
         .Save
         .Dispose
    End With
    
CreateEmail ZIPPath & ZIPName & ".zip", ZIPPath, ZIPName
End Function


Nach dem Erstellen der Outlook-Mail werden die PDF-Datei und das ZIP-Archiv automatisch gelöscht. Wer das nicht möchte kann die beiden Kill-Befehle löschen oder ausdokumentieren.

Es kann vorkommen dass sich technisch bedingt Fehler zwischen dem Erstellen einiger Funktionen einstellen. Dies kann ins besondere bei langsamen Rechnern ergeben. Dies kann z.B. dann auftreten, wenn die Email schneller erstellt wird als das ZIP-Archiv fertig ist. Setzen Sie in solchen Fällen ein Sleep vor dem Aufruf der nächsten Prozedur. Bei modernen Rechnern dürfte dies eigentlich nicht mehr vorkommen. Aber wer weiss....

Natürlich können Sie diese Prozeduren auch in Word einsetzen.

Mit der DotNetZip ist es auch möglich, eine Arbeitsmappe zur Laufzeit als ZIP-Archiv zu packen. Mit den meisten ZIP-Programmen (z.B. WinZip) ist dies nicht möglich, da sie auf geöffnete Dateien nicht zugreifen können.

Public Sub ArbeitsmappeAlsZIPArchiv()
Dim ZipApp      As Object
Dim ZIPPassword As String
Dim FileName    As String
Dim FilePath    As String
Dim FileFormat  As String

FileName = Left(ActiveWorkbook.Name, InStr(1, ActiveWorkbook.Name, ".") - 1)
FilePath = ActiveWorkbook.Path & "\"
ZIPPassword = ""

ActiveWorkbook.Save

Set ZipApp = CreateObject("Ionic.Zip.ZipFile")
    With ZipApp
       If ZIPPassword <> "" Then
         .Encryption = 3
         .Password = ZIPPassword
       End If
         .AddFile (ActiveWorkbook.FullName)
         .Name = FilePath & FileName & ".zip"
         .Save
         .Dispose
    End With
End Sub


Viel Spaß und Erfolg mit diesen (neuen) Möglichkeiten!