VB-Homepage Tipp 421

Zusammenspiel VB,VBA und Acrobat - aut. Erstellen von PDF Dateien

Wieder mal ein Thema, das nicht die breite Menge der Programmierer interessiert, aber wer sich mit dem Thema automatisieren von Vorgängen zur PDF Erstellung befasst, der wird sicher froh sein, in der Tipp DB dazu etwas zu finden.

Eine konkrete Aufgabenstellung war für mich der Anlass zu dieser Thematik.
Dabei sollte eine umfangreiche Sammlung von Dokumenten, die in Office Formaten vorlag, in PDF Dateien umgewandelt werden und mit einer Kopie der original Verzeichnisstruktur im Intranet des Unternehmens verfügbar gemacht werden.
Hier waren folgende Punkte zu realisieren.
1. Dynamisches Auslesen der Verzeichnisstruktur und erstellen einer identischen Struktur auf dem Intranetserver, inklusive Übernahme der enthaltenen Dateien.
2. Unter zu Hilfenahme des Internet Explorer Strukturobjekts, Nachbildung der Struktur inklusive Verlinkung der Dokumente.
Automatisiertes Erstellen einer HHC Datei. Eine feine Sache :-)
3. automatisiertes Konvertieren aller Dokumente ins PDF Format und löschen der original Office Dokumente. Außerdem automatisiertes erstellen einer dazugehörigen HTM Datei, in der das Plugin "PDF" geladen wird.

Ich glaube Sie können nachvollziehen, das dies schon eine Herausforderung war.
In diesem Zusammenhang ist mir also einiges zum Zusammenspiel zwischen VB, VBA und Adobe Acrobat zwischen die Hände gekommen, von dem ich einiges hier wieder geben möchte.
Grundvorraussetzung ist natürlich die Installation von Adobe Acrobat! und für die hier aufgeführten Beispiele die Installation von Office95 oder 98.

Fangen wir einfach mit einem VB Projekt an.
Hier geht es um die automatisierte Konvertierung von
Word Dokumenten ins PDF Format.
Dabei erfolgt die Übergabe der Anweisungen via DDE.

1. Erstellen Sie sich ein neues VB Projekt und fügen Sie einen
Commandbutton (Command1) und eine Textbox (Text1) hinzu.

2. Fügen Sie unter Verweise Ihrem Projekt die Microsoft Word 8.0 Object Library
hinzu.

3. Allgemein/ConvertFile
Function ConvertFile(strSourceFileName As String) As String
On Error GoTo ErrorHandler

Dim msWord As Word.Application
Set msWord = GetObject(Class:="Word.Application.8")

msWord.Visible = True
msWord.ActivePrinter = "Acrobat Distiller"
msWord.Documents.Open strSourceFileName
msWord.ActiveDocument.PrintOut
msWord.ActiveDocument.Close False

Set msWord = Nothing
ConvertFile = True
Exit Function

ErrorHandler:
' Wenn Word noch nicht läuft, wird es gestartet
If Err.Number = 429 Then
   Set msWord = CreateObject("Word.Application.8")
   Err.Clear
   Resume
End If

If IsCriticalError Then
   ConvertFile = False
   Exit Function
Else
   Resume
End If

End Function

4. Allgemein/IsCriticalError           'nur Fehlerprüfung
Private Function IsCriticalError() As Boolean

Dim strErrorMessage As String

Select Case Err.Number
   Case Else
       strErrorMessage = "Fehlermeldung" & Trim(Str(Err.Number))
       IsCriticalError = True
       Exit Function
End Select

IsCriticalError = False

End Function

5. Command1/Click
Private Sub Command1_Click()

Dim strFileToConvert As String
Dim strFolder As String

strFolder = trim(Text1.text)                          'Verzeichnisangabe aus Textbox
strFileToConvert = Dir(strFolder + "*.doc")     'Dokumenttyp

'solange Durchlaufen, bis alle Dokumente abgearbeitet
While strFileToConvert <> ""

   'Konvertierung nach PDF
   If (ConvertFile(strFolder + strFileToConvert) = False) Then
      'Fehler beim konvertieren aufgetreten.
      Exit Sub
   End If

   'nächste Datei ermitteln
   strFileToConvert = Dir
Wend

End Sub

6. Starten Sie Ihr Projekt und tragen in die Textbox den Pfad (mit abschließendem Backslash) in die Textbox. Wenn Sie nun den Commandbutton anklicken, werden alle *.doc Dateien nach PDF konvertiert.

####################################################

Für meine Zwecke fand ich diese Herangehensweise nicht so günstig, da ich vorher schon getestet hatte, daß das Adobe eigene Makro "DoPrintWithLinks"
genau das tat, was ich erreichen wollte. Die Vorlage PDFMaker.dot, wird ja standardmäßig bei der Installation von Acrobat und dem Vorhandensein von MS Word in das STARTUP Verzeichnis kopiert und somit bei jedem Word Start automatisch mit geladen. Der Aufruf sollte aber dennoch aus VB heraus erfolgen, da die anderen Aktionen auch von dort liefen. Also habe ich folgende Schritte realisiert.

1. Erstellen eines eigenes Makros in der Normal.dot. Damit es auch immer verfügabr ist.

unter Normal/Initialization

Sub makeDOCtoPDF()

Application.DisplayAlerts = wdAlertsNone   'keine Fehlermeldungen, da aut. Lauf
AdobePDFMaker.DoPrintWithLinks              'Aufruf Acrobat Makro
ThisDocument.Close                               'Schließen des Dokuments
Application.Quit                                     'Schließen von Word

End Sub

2. Nun zum VB Projekt. Dabei habe ich hier ist die Konvertierungsfunktion aus dem Gesamtprojekt herausgefiltert. Der Aufruf erfolgt über einen Commandbutton (Command1) dem Sie Ihrem Projekt hinzufügen müssen. Desweiteren wollen ist der Ablauf so aufgebaut, daß immer erst ein Prozess beendet wird, bevor der neue beginnt. Dafür nutzen wir die API Funktionen OpenProcess und GetExitCodeProcess.

Allgemein/Deklarationen
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Const STILL_ACTIVE = &H103

Command1/Click
Dim AppDir As String
Dim Progname As String, Dateiname As String
Dim ProcessId As Long, hProcess As Long, nRet As Long

Const fdwAccess = &H100000
Pfadangabe = "F:\PDFTest\"            '<- passen Sie hier Ihren Pfad an

Command1.Enabled = False             'Damit der Vorgang sichtbar wird

'erster Durchlauf
x = Dir(Pfadangabe & "*.doc")

If x <> "" Then
   'Aufruf von Word mit Dateiname/pfad der zu konvertierende Datei
   'und zu startendem Makro
   If x <> "" Then
      ProcessId = Shell("winword /mmakeDOCtoPDF " & """" & Pfadangabe & x & """", vbMinimizedNoFocus)
   Else 'keine Worddateien im Verzeichnis
      Exit Sub '--- ggf auch goto
   End If

   'Abwarten bis Prozess beendet
   hProcess = OpenProcess(fdwAcess, False, ProcessId)
   Do
      GetExitCodeProcess hProcess, nRet
      DoEvents
   Loop While nRet = STILL_ACTIVE

   'löschen des Worddokuments
   Kill Pfadangabe & x                       'Quell Worddokument nicht erhalten

End If

'alle weiteren Durchläufe
Do While x <> ""

   'nächste Datei ermitteln
   x = Dir
   'Aufruf von Word mit Dateiname/pfad der zu konvertierende Datei
   'und zu startendem Makro
   If x <> "" Then
      ProcessId = Shell("winword /mmakeDOCtoPDF " & """" & Pfadangabe & x & """", vbMinimizedNoFocus)
   Else 'keine Datei mehr zum konvertieren vorhanden
      Exit Do
   End If

   'Abwarten bis Prozess beendet (nur Win95/98 - NT geht anders)
   hProcess = OpenProcess(fdwAcess, False, ProcessId)
   Do
      GetExitCodeProcess hProcess, nRet
      DoEvents
   Loop While nRet = STILL_ACTIVE

   'löschen des Worddokuments
   Kill Pfadangabe & x                       'Quell Worddokument nicht erhalten

Loop

Command1.Enabled = True

Erstellen Sie sich für einen Test ein Verzeichnis mit mehreren Word Dateien, denken Sie daran, das in der gegenwärtigen Einstellungen, die Worddateien gelöscht werden. Passen Sie den Pfad im Projekt an und starten Sie dieses.
Wenn Sie nun die Aktion über den Commandbutton ausführen, so werden alle Worddateien im angegebenen Verzeichnis ins PDF Format konvertiert und anschließend gelöscht.

Zum Schluß sollen noch ein paar Internetressourcen zum Thema folgen

Adobe Deutschland
Adobe CodeCut
Adobe Forum

Übrigens, sollten Sie während des Ablaufes der Konvertierung eine Fehlermeldung erhalten, das die Datei nicht konvertiert werden kann, weil Sie angeblich im Reader oder Distiller geöffnet ist und Sie genau wissen, das ist nicht der Fall, dann schauen Sie sich mal den Pfad oder Dateinamen an, ob dieser ein Komma enthält. Mit Leerzeichen und Punkten kommt der Distiller gut zurecht, für die Übergabe langer Pfad/Dateiangaben sollten Sie diese in Hochkomma übergeben.


Tipp-Download

Quelle :

Zurück zur Übersichtsseite