Alle PDFs eines Ordners zu einem PDF per Com-Interface verbinden


#1

Hallo,

ich würde gerne die PDFs in pfad1 zu einem PDF (soll in pfad2 liegen) zusammenfassen (per COM Interface).

In der Do-Loop macht der erste "Set Printjob" Probleme:
"Invalid index. Please Check the index Parameter."
Ich verwende zum editieren des Scripts VBSedit.
Die Sprache ist VBScript.
Was mache ich falsch?
Wie kann ich denn das Skript mit Einrückungen posten? Ich dachte das sechste Symbol von links in der Formatierungsleiste?
Leider komme ich alleine nicht mehr weiter und bitte um Hilfe...
Vielleicht kann mir jemand helfen - darüber würde ich mich sehr freuen.
Viele Grüße,
je77

indent preformatted text by 4 spaces

Dim fso,Verz,anzDateien,w,file,files
'hier liegen die zu bearbeitenden PDFs
Const pfad1 = "D:\test\PDFs"
Const pfad2="D:\test\fertig"

Set fso = CreateObject("Scripting.FileSystemObject")
Set objshell=CreateObject("Shell.Application")

'Set printer as default
Set WSHNetwork = CreateObject("WScript.Network")
WSHNetwork.SetDefaultPrinter "PDFCreator"
Set PDFCreatorQueue = CreateObject("PDFCreator.JobQueue")
PDFCreatorQueue.Initialize()

'PDFs in Ordner zählen
Set Verz = fso.GetFolder(pfad1)
anzDateien=Verz.Files.Count

'Wartezeit für Druckaufträge
w=5

Set files=Verz.Files

Do until PDFCreatorQueue.Count=anzDateien
For Each file in files
objShell.ShellExecute "C:\Program Files\PDFCreator\PDFCreator.exe", " /PrintFile=" & pfad1 & "" & file.Name,"", "",1
Set printJob = PDFCreatorQueue.NextJob
printJob.SetProfileByGuid("DefaultGuid")
Next
If not PDFCreatorQueue.WaitForJobs(anzDateien,w) then
MsgBox "Die Druckaufträge erreichten nicht in" & w & "Sekunden die JobQueue."
w=w+5
Else
MsgBox "Es sind " & PDFCreatorQueue.Count & " job(s) in der JobQueue."
PDFCreatorQueue.MergeAllJobs
Set printJob = PDFCreatorQueue.NextJob
printJob.SetProfileByGuid("DefaultGuid")
printJob.ConvertTo(pfad2 & "\gesamt.pdf")
End if
Loop

PDFCreatorQueue.ReleaseCom
WScript.Quit

indent preformatted text by 4 spaces

#2

Hi,

evtl reicht es, das
If not PDFCreatorQueue.WaitForJobs(anzDateien,w)
MsgBox "Die Druckaufträge erreichten nicht in" & w & "Sekunden die JobQueue." vorzuziehen; aktuell greifst Du mit Set printJob = PDFCreatorQueue.NextJob zuerst auf den Job zu und fragst anschließend ab, ob die Queue denn auch schon Jobs enthält, was fehlschlägt, da das Drucken etwas Zeit benötigt.

Beste Grüße

Robin


#3

Hallo, ich habe etwas getüftelt und dieser Code ist herausgekommen.

Dim fso,Verz,anzDateien,w,file,files
'hier liegen die zu bearbeitenden PDFs
Const pfad1 = "D:\test\PDFs" 
Const pfad2="D:\test\fertig"

Set fso = CreateObject("Scripting.FileSystemObject")
Set objshell=CreateObject("Shell.Application")

'Set printer as default 
Set WSHNetwork = CreateObject("WScript.Network")
WSHNetwork.SetDefaultPrinter "PDFCreator" 
Set PDFCreatorQueue = CreateObject("PDFCreator.JobQueue")
PDFCreatorQueue.Initialize

'PDFs in Ordner zählen
Set Verz = fso.GetFolder(pfad1)
anzDateien=Verz.Files.Count

'Wartezeit für Druckaufträge
w=1

Set files=Verz.Files

Do 
	Do 
		For Each file in files
			objShell.ShellExecute "C:\Program Files\PDFCreator\PDFCreator.exe", " /PrintFile=" & pfad1 & "\" & file.Name,"", "",1
		Next
		If not PDFCreatorQueue.WaitForJobs(anzDateien,w) then
			MsgBox "Die Druckaufträge erreichten nicht in" & w & "Sekunden die Warteschlange."
			w=w+5
		Else
			MsgBox "Aktuell sind " & PDFCreatorQueue.Count & " job(s) in der Warteschlange."
			PDFCreatorQueue.MergeAllJobs
			Set printJob = PDFCreatorQueue.NextJob
			printJob.SetProfileByGuid("DefaultGuid")
			printJob.ConvertTo(pfad2 & "\gesamt.pdf")	
		End if
	Loop until printJob.IsFinished
Loop until printJob.IsSuccessful

PDFCreatorQueue.ReleaseCom
WScript.Quit

Ich möchte das die Wartezeit immer um 5 Sekunden erhöht wird falls die printjobs nicht "finished" und "successfull" sind. Ich habe den Code bisher im Einzelschrittverfahren getestet und er tut was er soll.
Ich bitte um Kommentare/Vorschläge ob das so okay ist...
Dankeschön...
Viele Grüße, je77


#4

Hallo, ich bin's nochmal...
Wenn ich das Skript in einem Durchlauf durchlaufen lasse, dann steigt er bei der Zeile "Loop until printJob.IsFinished" aus.
Für Vorschläge bin ich sehr dankbar...
Viele Grüße,
je77


#5

Hi,

es ist nicht notwendig, das Timeout manuell pro Job anzupassen, Du könntest stattdessen direkt einfach z.B. 60 Sekunden nehmen; wenn der Job früher eintrifft, wird das Warten abgebrochen.

Beste Grüße

Robin


#6

Hi Robin,
vielen Dank für den Hinweis!! So klappt es bestens, ich habe die Wartezeit sehr hoch gesetzt und die Erhöhung der Wartezeit (w=w+5) entfernt.:

Dim fso,Verz,anzDateien,w,file,files,printJob
'hier liegen die zu bearbeitenden PDFs
Const pfad1 = "D:\test\PDFs" 
Const pfad2="D:\test\fertig"

Set fso = CreateObject("Scripting.FileSystemObject")
Set objshell=CreateObject("Shell.Application")

'Set printer as default 
Set WSHNetwork = CreateObject("WScript.Network")
WSHNetwork.SetDefaultPrinter "PDFCreator" 
Set PDFCreatorQueue = CreateObject("PDFCreator.JobQueue")
PDFCreatorQueue.Initialize

'PDFs in Ordner zählen
Set Verz = fso.GetFolder(pfad1)
anzDateien=Verz.Files.Count

'Wartezeit für Druckaufträge
w=60

Set files=Verz.Files

Do 
	Do 
		For Each file in files
			objShell.ShellExecute "C:\Program Files\PDFCreator\PDFCreator.exe", " /PrintFile=" & pfad1 & "\" & file.Name,"", "",1
		Next
		If not PDFCreatorQueue.WaitForJobs(anzDateien,w) then
			MsgBox "Die Druckaufträge erreichten nicht in" & w & "Sekunden die Warteschlange."
		Else
			MsgBox "Aktuell sind " & PDFCreatorQueue.Count & " job(s) in der Warteschlange."
			PDFCreatorQueue.MergeAllJobs
			Set printJob = PDFCreatorQueue.NextJob
			printJob.SetProfileByGuid("DefaultGuid")
			printJob.ConvertTo(pfad2 & "\gesamt.pdf")	
		End if
	Loop until printJob.IsFinished
Loop until printJob.IsSuccessful

PDFCreatorQueue.ReleaseCom
WScript.Quit

Eine Frage hätte ich noch:
Bei mir öffnet sich der Acrobat Professional während des PDF-Erzeugens - kann man das irgendwie abstellen? Ich setze per Code den PDFCreator als Standarddrucker und habe als "Öffnen mit" immer PDFCreator eingestellt. Was kann ich tun?
Viele Grüße, je77


#7

Das Öffnen des Acrobat ist korrekt, war ein Misverständnis von mir!
Der Code reicht dann so:

Dim fso,Verz,anzDateien,w,file,files,printJob
'hier liegen die zu bearbeitenden PDFs
Const pfad1 = "D:\test\PDFs" 
Const pfad2="D:\test\fertig"

Set fso = CreateObject("Scripting.FileSystemObject")
Set objshell=CreateObject("Shell.Application")

'Set printer as default 
Set WSHNetwork = CreateObject("WScript.Network")
WSHNetwork.SetDefaultPrinter "PDFCreator" 
Set PDFCreatorQueue = CreateObject("PDFCreator.JobQueue")
PDFCreatorQueue.Initialize

'PDFs in Ordner zählen
Set Verz = fso.GetFolder(pfad1)
anzDateien=Verz.Files.Count

'Wartezeit für Druckaufträge
w=240
Set files=Verz.Files

For Each file in files
	objShell.ShellExecute "C:\Program Files\PDFCreator\PDFCreator.exe", " /PrintFile=" & pfad1 & "\" & file.Name,"", "",1
Next
If not PDFCreatorQueue.WaitForJobs(anzDateien,w) then
	MsgBox "Die Druckaufträge erreichten nicht in" & w & "Sekunden die Warteschlange."
Else
	MsgBox "Aktuell sind " & PDFCreatorQueue.Count & " job(s) in der Warteschlange."
	PDFCreatorQueue.MergeAllJobs
	Set printJob = PDFCreatorQueue.NextJob
	printJob.SetProfileByGuid("DefaultGuid")
	printJob.ConvertTo(pfad2 & "\gesamt.pdf")	
End if

PDFCreatorQueue.ReleaseCom
WScript.Quit

Die Druckaufträge kommen aber in einer willkürlichen Reihenfolge an. Ich habe eine variable Anzahl an PDFs in pfad1. 1 PDF hat den Namen 0.pdf, danach kommen mal 2, mal 3, mal 5, also eine variable Anzahl an PDFs in dem Ordner. Kann man die irgendwie sortieren? So dass 0 zuerstkommt und dann die anderen PDFs? Wichtig wäre, dass 0 immer zuerst ist - die Reihenfolge der restlichen PDFs ist nicht so wichtig...
Über Hilfe würde ich mich sehr freuen...
Viele Grüße,
je77


#8

Hi,

wenn Du ausschließlich PDFs konvertierst, kannst Du statt /PrintFile /PdfFile verwenden, dann konvertiert der PDFCreator direkt, ohne zwischendurch noch über den Adobe Reader zu Drucken. Das geht zum einen schneller und sollte zum anderen auch dafür sorgen, dass die Dateien in der richtigen Reihenfolge abgearbeitet werden. Beim Drucken kommt es immer darauf an, welches Dokument zuerst fertig gedruckt wurde (also nicht zwangsläufig in welcher Reihenfolge die Druckaufträge gestartet worden).

Beste Grüße

Robin


#9

Hallo Robin,
das mit dem /PdfFile klappt bestens...
Dass mit der Reihenfolge, dass 0 zuerst ist, klappt noch nicht.
Du sagst selbst wenn ich die Dateien 0,8,12 habe und wenn ich automatisch Präfix-Nullen per Programmierung (wegen der Reihenfolge) einfügen würde, also 0, 08, 12, dann ist es nicht garantiert, das 0 zuerst ist?
Es gibt also keine Möglichkeit bei einem Druck immer eine Seite zuerst (die 0) im Pdf zu haben?
Verstehe ich das richtig?
Viele Grüße,
je77


#10

Aus Sicht des PDFCreators sollte die Benennung der Dateien keine Rolle spielen, diese sollten in der Reihenfolge verarbeitet bzw. zusammengefügt werden, in welcher diese mit /PdfFile an den PDFCreator übergeben werden.
Mit /PrintFile werden die Dokumente zwischendurch noch gedruckt, so dass z.B.

/PrintFile="Großes Dokment mit vielen Bildern.pdf"
/PrintFile="nurText.pdf

dazu führen kann, dass "nurText.pdf" zuerst fertig gedruckt ist und daher auch zuerst in der PDF auftaucht.


#11

Hallo Robin,
das mit der Reihenfolge wann etwas fertig gedruckt (mit Printfile) habe ich verstanden.
Wie kann ich denn die Reihenfolge in der die files mit /pdffile an den PDFCreator übergeben werden steuern?
Das müsste doch nur mit Präfix-Nullen und eines Ansprechens über den Dateinamen gehen, oder?


#12

Ja,
an sich sollte das gehen; aber wie genau VBS bzw. "For Each file in files" die Reihenfolge bildet, weiß ich leider auch nicht mit Sicherheit.


#13

Dankeschön...
Ich werde mich mal darum kümmern.
Ich kann aber erst am Donnerstag damit weitermachen...
Ich wünsche dir einen schönen Feiertag!
Und ich würde mich freuen wenn ich noch etwas Rücksprache mit dir (oder anderen) halten könnte...
Viele Grüße,
je77


#14

Hallo, jetzt klappt alles!!
Die Dateinamen haben sich geändert:
Zuerst kommt ein PDF "000.pdf". Dann eine variable Anzahl von PDFs - die Nummerierung ist 3-stellig und beginnt mit "100.pdf".
Beim mergen der Dateien wurde trotzdem die Reihenfolge durcheinander geworfen.
Ich habe den Fehler gefunden:
Man muss eine Pause von 2 Sekunden nach dem PDF-printen der jeweiligen Dateien einfügen - so kommt nichts mehr durcheinander und die Reihenfolge ist chronologisch.

Ich möchte mich recht herzlich bei Robin.W für seine Unterstützung bedanken - ohne ihn wäre das Problem nicht zu lösen gewesen!!!

Nun ist das Projekt abgeschlossen.

Viele Grüße und einen schönen Tag, je77

Hier der Code:

Dim fso,Verz,anzDateien,w,file,files,printJob,objshell,PDFCreatorQueue,WSHNetwork
'hier liegen die zu bearbeitenden PDFs
Const pfad1 = "D:\test\PDFs" 
Const pfad2="D:\test\fertig"

Set fso = CreateObject("Scripting.FileSystemObject")
Set objshell=CreateObject("Shell.Application")

'Set printer as default 
Set WSHNetwork = CreateObject("WScript.Network")
WSHNetwork.SetDefaultPrinter "PDFCreator" 
Set PDFCreatorQueue = CreateObject("PDFCreator.JobQueue")
PDFCreatorQueue.Initialize

'PDFs in Ordner zählen
Set Verz = fso.GetFolder(pfad1)
Set files=Verz.Files
anzDateien=files.Count

'Wartezeit für Druckaufträge in Sekunden
w=240

For Each file in files
	objShell.ShellExecute "C:\Program Files\PDFCreator\PDFCreator.exe", " /PdfFile=" & pfad1 & "\" & file.Name,"", "",1
	'Pause 2 Sekunden
	WScript.Sleep(2000)
Next
If not PDFCreatorQueue.WaitForJobs(anzDateien,w) then
	MsgBox "Die Druckaufträge erreichten nicht in" & w & "Sekunden die Warteschlange."
Else
	MsgBox "Aktuell sind " & PDFCreatorQueue.Count & " job(s) in der Warteschlange."
	PDFCreatorQueue.MergeAllJobs
	Set printJob = PDFCreatorQueue.NextJob
	printJob.SetProfileByGuid("DefaultGuid")
	printJob.ConvertTo(pfad2 & "\gesamt.pdf")	
End if

PDFCreatorQueue.ReleaseCom
WScript.Quit

#15

Hallo,
ich habe den Code nochmal bearbeitet.
Der ShellExecute Befehl mit "PdfFile" machte manchmal Probleme.
Deswegen habe ich den ShellExecute Befehl nochmals verändert.

Option Explicit
Dim fso,Verz,anzDateien,w,file,files,printJob,objshell,PDFCreatorQueue,WshNetwork,r,wshShell
'hier liegen die zu bearbeitenden PDFs
Const pfad1 = "C:\...\PDFs" 
Const pfad2 = "C:\...\fertig"
Const Titel="Titel"

Set fso = CreateObject("Scripting.FileSystemObject")
Set objshell=CreateObject("Shell.Application")
Set wshShell=WScript.CreateObject("WScript.Shell")

'Set printer as default 
Set WshNetwork = CreateObject("WScript.Network")
WshNetwork.SetDefaultPrinter "PDFCreator" 
Set PDFCreatorQueue = CreateObject("PDFCreator.JobQueue")
PDFCreatorQueue.Initialize

'PDFs in Ordner zählen
Set Verz = fso.GetFolder(pfad1)
Set files=Verz.Files
anzDateien=files.Count

'Wartezeit für Druckaufträge in Sekunden
w=120

For Each file in files
	objshell.ShellExecute pfad1 & "\" & file.Name,"","","print",1
	'Pause 3 Sekunden
	WScript.Sleep(3000)
Next
If Not(PDFCreatorQueue.WaitForJobs(anzDateien,w)) then
	r=wshShell.Popup("Die Druckaufträge erreichten nicht in " & w & " Sekunden die Warteschlange.",5,Titel)
Else
	r=wshShell.Popup("Alle Druckaufträge erreichten die Warteschlange.",5,Titel)
	PDFCreatorQueue.MergeAllJobs
	Set printJob = PDFCreatorQueue.NextJob
	printJob.SetProfileByGuid("DefaultGuid")
	printJob.ConvertTo(pfad2 & "\gesamt.pdf")	
End If

PDFCreatorQueue.ReleaseCom
WScript.Quit