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. |