Hallo Swiffer,
so, ich hab da mal was zusammengezimmert. Aufgrund der Problematik pdf und der Umstellung auf "aus Text Datei lesen" hat es mich mehr Zeit gekostet als erwartet.
Aber naja, das ist eher mein Problem und animiert höchstens zu einem etwas üppigeren Trinkgeld. ![]()
Also. Ich habe es jetzt so gemacht wie gewünscht.
Ghostscript wandelt die QR-pdf in txt-Dateien. pdftoolkit merged die pdf, da nitro keinerlei Doku zu Commandline Switches oder einer API hat.
Das Script erwartet auf dem ausführenden Rechner die Installation der 2 Programme.
https://ghostscript.com/releases/gsdnld.html
https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/
jeweils in der 32-bit Version (zwecks Kompatibilität)
Die Pfade und so sind anpassbar.
Probier es einfach mal aus. Hab auch so Sachen wie optionales archivieren mit reingepackt, da ich die Qualität der Daten nicht einschätzen kann.
Natürlich kannst du mit dem Script machen was du möchtest. Es ist deins.
Bezüglich Trinkgeld kannst du das an mein paypal schicken. (o.zimmermann@pc-wizards.de) mit der E-Mail Adresse sollte das funktionieren.
Wie gesagt, meine "Range" kennst du. Dass ich mehr als 2-3 Std. gebraucht habe ist baer wie gesagt mein Problem.
Bin halt ein netter Mensch
wenn etwas nicht passt einfach melden ![]()
Ach ja, ein schönes Wochenende wünsche ich...
#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>
Opt("WinTitleMatchMode", 2)
Opt("MustDeclareVars", 1)
#cs
Bedingungen:
Download und Installation folgender Programme im Standardverzeichnis
pdftkfree ==> https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/pdftk_free-2.02-win-setup.exe
Ghostscript ==> https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10021/gs10021w32.exe
#ce
; Variablen, die angepasst werden können
Global $sTitel = "merge PDF-Tool"
Global $sPathRechnungPDF = "C:\RG ohne EZ"
Global $sPathQRPDF = "C:\QR EZ"
Global $sPathQRTxt = $sPathQRPDF & "\txt"
Global $sDestinationIP = "192.168.150.34" ; um die IP pingen zu können (Test Verfügbarkeit)
Global $sPathDestinationPDF = "\\" & $sDestinationIP & "\NAS Zuhause synch verschlüsselt\Firma\Rechnungen"
Global $sPathRechnungArchiv = $sPathRechnungPDF & "\Archiv"
Global $sPathQRArchiv = $sPathQRPDF & "\Archiv"
Global $sRegExSuchString = ".*(\d{4}-\d{4}).*" ; der Suchstring extrahiert aus dem Rechungsnamen nnnn-nnnn
Global $nScanPause = 120 ; Zeit in Sekunden als Pausenangabe bis zum nächsten Scan des Source Ordners, beginnt mit Pause!
Global $bArchivieren = 1 ; wenn aktiviert dann wird jede pdf in "Archiv" kopiert vor merge
; Installationen von Ghostscript und pdftk prüfen
Global $aEnvPath = StringSplit(EnvGet("Path"), ';')
For $i = 1 To $aEnvPath[0]
If StringInStr($aEnvPath[$i], "gs\gs") Then
If FileExists($aEnvPath[$i] & '\gswin32c.exe') And FileExists($aEnvPath[$i] & '\gsdll32.dll') Then
Global $sPathToMergeTool = $aEnvPath[$i] & '\gswin32c.exe'
ExitLoop
Else
ShellExecute("https://ghostscript.com/releases/gsdnld.html")
Exit MsgBox(262144 + 16, $sTitel, "Die zur Ausführung benötigte Datei: " & $aEnvPath[$i] & '\gswin32c.exe' & " konnte nicht gefunden werden." & @CRLF & @CRLF & "Installieren Sie die 32-bit Version von GhostScript und starten Sie dieses Script dann erneut.")
EndIf
EndIf
Next
If FileExists("C:\Program Files (x86)\PDFtk\bin\pdftk.exe") And FileExists("C:\Program Files (x86)\PDFtk\bin\libiconv2.dll") Then
Global $sPathToMergeTool = 'C:\Program Files (x86)\PDFtk\bin\pdftk.exe'
Else
ShellExecute("https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/")
Exit MsgBox(262144 + 16, $sTitel, "Die zur Ausführung benötigte Datei: C:\Program Files (x86)\PDFtk\bin\pdftk.exe konnte nicht gefunden werden." & @CRLF & @CRLF & "Installieren Sie die 32-bit Version von GhostScript und starten Sie dieses Script dann erneut.")
EndIf
; Das Script erwartet die Dateien pdftk.exe & die libiconv2.dll im Scriptverzeichnis
Global $sPathToGSWin32cTool = @ScriptDir & '\gswin32c.exe' ; Das Script erwartet die Dateien gswin32c.exe & gsdll32.dll im Scriptverzeichnis
; interne Variablendeklaration
Global $command, $PID, $sTxt, $sQRFilePDF, $hRechnungPDF, $sSearchString, $sRechnungFileName, $aQRListePDF, $aQRListeTxt, $nTimer, $Error, $ErrorMsg, $bQRFound = 0, $sAkt_Searchtxt, $bfirstStart = 1
; prüfen, ob die Ordner existieren, eine Berechtigungs-Prüfung innerhalb der Ordner wird nicht durchgeführt (Schreibrechte)
If DriveGetType($sPathRechnungPDF) = "Network" Then
If Ping($sPathRechnungPDF, 500) = 0 Then Exit MsgBox(262144 + 16, $sTitel, "Der Ordner " & $sPathRechnungPDF & " konnte nicht erreicht werden!" & @CRLF & "Die Anwendung wird beendet.")
EndIf
If DriveGetType($sPathQRPDF) = "Network" Then
If Ping($sPathQRPDF, 500) = 0 Then Exit MsgBox(262144 + 16, $sTitel, "Der Ordner " & $sPathQRPDF & " konnte nicht erreicht werden!" & @CRLF & "Die Anwendung wird beendet.")
EndIf
If DriveGetType($sDestinationIP) = "Network" Then
If Ping($sDestinationIP, 500) = 0 Then Exit MsgBox(262144 + 16, $sTitel, "Der Pfad " & $sDestinationIP & " konnte nicht erreicht werden!" & @CRLF & "Die Anwendung wird beendet.")
EndIf
If Not FileWrite($sPathRechnungPDF & "\Testdatei.tmp", "") Then Exit MsgBox(262144 + 16, $sTitel, "Der Ordner " & $sPathRechnungPDF & " konnte nicht erreicht werden!" & @CRLF & "Die Anwendung wird beendet.")
FileDelete($sPathRechnungPDF & "\Testdatei.tmp")
If Not FileWrite($sPathQRPDF & "\Testdatei.tmp", "") Then Exit MsgBox(262144 + 16, $sTitel, "Der Ordner " & $sPathQRPDF & " konnte nicht erreicht werden!" & @CRLF & "Die Anwendung wird beendet.")
FileDelete($sPathQRPDF & "\Testdatei.tmp")
If Not FileWrite($sPathDestinationPDF & "\Testdatei.tmp", "") Then Exit MsgBox(262144 + 16, $sTitel, "Der Ordner " & $sPathDestinationPDF & " konnte nicht erreicht werden!" & @CRLF & "Die Anwendung wird beendet.")
FileDelete($sPathDestinationPDF & "\Testdatei.tmp")
If $bArchivieren Then
If Not FileExists($sPathRechnungArchiv) Then DirCreate($sPathRechnungArchiv)
If Not FileExists($sPathQRArchiv) Then DirCreate($sPathQRArchiv)
EndIf
If Not FileExists($sPathQRPDF & "\txt") Then DirCreate($sPathQRPDF & "\txt") ; Unterordner für die zu durchsuchenden txt-Dateien erstellen
; HotKey, der die Anwendung beendet (funktioniert bei au3 wie auch bei exe)
HotKeySet("!x", "_Exit")
$nTimer = TimerInit() ; aktuelle Systemzeit holen und die Pausezeit addieren, damit wird sofort die Schleife durchlaufen und erst nach 1 Durchlauf pausiert
While Sleep(10) ; 10ms schlafen um Prozessor zu entlasten
If $bfirstStart = 1 Or TimerDiff($nTimer) > $nScanPause * 1000 Then ; solange gegen die Pausezeit prüfen, bis überschritten, dann nach PDF-Datei suchen
$bfirstStart = 0
ConsoleWrite("geht los" & @CRLF)
$nTimer = TimerInit() ; aktuelle Systemzeit holen, damit wieder gegen die Pausezeit verglichen werden kann
$hRechnungPDF = FileFindFirstFile($sPathRechnungPDF & "\*.pdf") ; sucht in dem angebenen Ordner nach pdf-Datei/en
If $hRechnungPDF = -1 Then ; keine pdf-Datei gefunden
FileClose($hRechnungPDF) ; Such-Handle $hRechnungPDF wieder schließen
ContinueLoop ; keine Datei gefunden, Loop von vorn beginnen und von Anfang mit Pause
Else ; mind. 1 Datei wurde gefunden
$bQRFound = 0
While 1 ; Loop der alle zu durchsuchenden Dateien durchgeht und wenn alle durch, dann Schleife verlassen
$sRechnungFileName = FileFindNextFile($hRechnungPDF) ; erste/nächste pdf-Datei aus dem Such-Handle $hRechnungPDF der Variable zuweisen
If @error Then ExitLoop ; keine Datei mehr vorhanden, Loop Abbruch
ConsoleWrite("pdf-Datei wird verarbeitet: " & $sRechnungFileName & @CRLF)
$sSearchString = StringRegExpReplace($sRechnungFileName, $sRegExSuchString, "$1") ; Suchstring auf den RegEx im Dateinamen reduzieren
; Fileliste aller QR pdf-Dateien inkl. Unterordner erstellen, in denen gesucht werden soll, Ordner Archiv und txt sind excluded
; Prüfung bei jedem Durchlauf, damit die txt bei Rechnungsstellung auch vorhanden ist
$aQRListePDF = _FileListToArrayRec($sPathQRPDF, "*.pdf||Archiv;txt", 1, 1, 1)
If @error > 0 Then ContinueLoop ; wenn keine pdf-Datei gefunden wurde, dann den Loop neu starten da keine Datei zum anhängen vorhanden ist
For $s = 1 To $aQRListePDF[0] ; wenn eine pdf-Datei noch nicht als txt-Datei vorhanden, dann erstellen
If Not FileExists($sPathQRPDF & "\txt\" & StringRegExpReplace($aQRListePDF[$s], "(.pdf)", ".txt")) Then
; mit Ghostscript die Datei in eine txt-Datei konvertieren und im Unterordner txt abspeichern
RunWait('"' & $sPathToGSWin32cTool & '" -sDEVICE=txtwrite -sOutputFile="' & $sPathQRTxt & "\" & StringRegExpReplace($aQRListePDF[$s], "(.pdf)", ".txt") & '" -dBATCH -dNOPAUSE "' & $sPathQRPDF & "\" & $aQRListePDF[$s] & '"', "", @SW_HIDE)
EndIf
Next
; Fileliste aller txt-Dateien erstellen, in denen gesucht werden soll
$aQRListeTxt = _FileListToArrayRec($sPathQRTxt, "*.txt||", 1, 1, 1)
$Error = @error ; Fehlercode abfangen und in Datei schreiben um diesen weiter zu verarbeiten
If $Error > 0 Then ; wenn Fehler, dann melden und Anwendung beenden
Switch $Error
Case 1
$ErrorMsg = "Path not found or invalid"
Case 2
$ErrorMsg = "Invalid Include parameter"
Case 3
$ErrorMsg = "Invalid Exclude parameter"
Case 4
$ErrorMsg = "Invalid Exclude_Folders parameter"
Case 5
$ErrorMsg = "Invalid $iReturn parameter"
Case 6
$ErrorMsg = "Invalid $iRecur parameter"
Case 7
$ErrorMsg = "Invalid $iSort parameter"
Case 8
$ErrorMsg = "Invalid $iReturnPath parameter"
Case 9
$ErrorMsg = "No files/folders found"
EndSwitch
Exit MsgBox(262144 + 64, $sTitel, "Die Liste mit Dateien die durchsucht werden sollen, konnte nicht erstellt werden." & @CRLF & _
"Der Fehlercode aus _FileListToArrayRec lautet:" & $ErrorMsg & @CRLF & @CRLF & "Die Anwendung wird beendet!")
EndIf
If $aQRListePDF[0] <> $aQRListeTxt[0] Then Exit MsgBox(262144 + 16, $sTitel, "Die Anzahl der QR-pdf Dateien stimmt nicht mit der Anzahl QR Txt-Dateien überein!" & @CRLF & "Das Script wird beendet!")
For $i = 1 To $aQRListeTxt[0] ; alle vorhandenen txt-Dateien in $sPathQRTxt nach dem Suchstring der Rechnung durchsuchen
$sTxt = FileRead($sPathQRTxt & "\" & $aQRListeTxt[$i])
If StringInStr($sTxt, $sSearchString) > 0 Then ; Suchstring in einer txt-Datei gefunden
$bQRFound = 1
; $sRechnungFileName = aktueller Dateiname der RechnungsPDF
; $aQRListeTxt[$i] = aktueller Dateiname der txt-Datei die durchsucht wird
; $sQRFilePDF = aktuelle QR pdf-Datei die zur gefundenen txt-Datei gehört
$sQRFilePDF = StringRegExpReplace($aQRListeTxt[$i], "(.txt)", ".pdf")
; mit gefundener Datei mergen und Output nach Destination
$command = '"' & $sPathToMergeTool & '" "' & $sPathRechnungPDF & '\' & $sRechnungFileName & '" "' & $sPathQRPDF & '\' & $sQRFilePDF & '" cat output "' & $sPathDestinationPDF & '\' & StringReplace($sRechnungFileName, '.pdf', '+.pdf') & '"'
;ConsoleWrite($command & @CRLF)
$PID = Run($command, "", @SW_SHOW, 2)
Sleep(5000)
If FileExists($sPathDestinationPDF & '\' & StringReplace($sRechnungFileName, '.pdf', '+.pdf')) = 1 Then
ConsoleWrite($sPathDestinationPDF & '\' & StringReplace($sRechnungFileName, '.pdf', '+.pdf') & " gemerged und abgelegt" & @CRLF & @CRLF)
If $bArchivieren Then
; Rechnung in Archiv kopieren wenn Archiv aktiviert
FileCopy($sPathRechnungPDF & "\" & $sRechnungFileName, $sPathRechnungArchiv)
; gefundene pdf-Datei in Archiv kopieren, da die Fund-Datei nach merge gelöscht wird, wenn Archiv aktiviert
FileCopy($sPathQRPDF & "\" & $sAkt_Searchtxt, $sPathQRArchiv)
EndIf
FileDelete($sPathRechnungPDF & "\" & $sRechnungFileName)
FileDelete($sPathQRTxt & "\" & $aQRListeTxt[$i])
FileDelete($sPathQRPDF & "\" & $sQRFilePDF)
ExitLoop
Else ; merge-PDF nicht vorhanden, etwas ist beim zusammenführen schief gelaufen, Prüfung auf Return Code der Konsolenausgabe ist aufwendiger
ConsoleWrite($sPathDestinationPDF & '\' & $sSearchString & "+.pdf nicht gefunden" & @CRLF)
MsgBox(262144 + 16, $sTitel, "Die Datei " & $sPathRechnungPDF & "\" & $sSearchString & ".pdf konnte nicht mit " & $sPathQRPDF & '\' & StringReplace($sAkt_Searchtxt, ".txt", ".pdf") & " zusammengeführt werden" & @CRLF & "Das Skript wartet, bis das Fenster geschlossen wird.")
EndIf
EndIf
Next
WEnd
EndIf
If $bQRFound = 0 Then
If MsgBox(16 + 1, $sTitel, "Der Dateiname " & $sSearchString & " der Rechnung konnte in keiner Datei in " & $sPathQRPDF & " gefunden werden!") = 2 Then Exit
ExitLoop
EndIf
FileClose($hRechnungPDF)
EndIf
WEnd
Func _Exit()
FileDelete($sPathQRTxt & "\*.txt")
Exit
EndFunc ;==>_Exit
Alles anzeigen