internet2107
Goto Top

Ordnerstruktur lesen, Dateien - Neue Ordnerstruktur

Ich verzweifle etwas an folgender Sache.

Ich habe eine vorgebene Ordnerstruktur, in der sich Dateien befinden. Diese Dateien sollen im Hintergrund per Word geöffnet werden, dann als .docx abgespeichert werden.

Jedoch darf die Ordnerstruktur nicht verändert werden.
Im Klartext also:

$quelle = "c:\beispiel\dateien"

Im Ordner "dateien" befinden sich als Beispiel Unterordner, wie:
"......\dateien\X123\test.dfa"
"......\dateien\X124\test.dfa"
"......\dateien\X125\test.dfa"

Nach der Bearbeitung müssen sie am Ziel aber genauso wieder erscheinen, ebenso die geänderten Dateien darin gespeichert werden.

$ziel = "d:\bearbeitet\pdf"
"......\docx\X123\test.pdf"
"......\docx\X124\test.pdf"
"......\docx\X125\test.pdf"

Wie kann ich das per Code umsetzen?

$quelle = "c:\beispiel\dateien"  
$ziel = "d:\bearbeitet\docx"  
$test= dir $quelle -Include *.* -Recurse | foreach {
$zielDir = $_.DirectoryName.Replace($quelle,$ziel)
new-item -ItemType Directory -Path $zielDir -Force
$filepath = ??????????????????
}

foreach ($docxfile in $test)
   {               
$objword = New-Object -ComObject word.application
$selection = $objword.Selection
$selection.Font.Name = Arial
$selection.Font.Size =9
$printout_pagesize = "A4"  
$selection.PageSetup.PaperSize = [Microsoft.Office.Interop.Word.WdPaperSize]::$printout_pagesize
$selection.PageSetup.Orientation = $printout_page_set
$doc.SaveAs([ref]$filepath, [ref]17) #17 steht für PDF
$doc.Saved = $true
$doc.Close()
$objword.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objword)

    }

Mein Hauptproblem liegt also darin, dass die Dateien die im Quellordner geöffnet und dann über Word bearbeitet werden, auch genauso wieder im richtigen Zielordner abzuspeichern, so dass die Ordnerstruktur Quelle/Ziel gleich ist face-sad

Content-Key: 255703

Url: https://administrator.de/contentid/255703

Printed on: April 19, 2024 at 12:04 o'clock

Member: colinardo
colinardo Nov 24, 2014 updated at 13:42:07 (UTC)
Goto Top
Moinsens,
hatte ich dir hier schon geschrieben wie du dies bewerkstelligst:
Powershell: Dateien suchen, Ordner, Unterordner
Genauer gesagt dort in der Zeile 16 face-wink

Hier mit gleichzeitiger Änderung der Erweiterung zu *.pdf:
$filepath = "$zielDir\$($_.Basename).pdf"
anders für dich vielleicht verständlicher geschrieben
$filepath = $zielDir + "\" + $_.Basename + ".pdf"
Grüße Uwe

p.s. schau dir doch mal alle Eigenschaften eines File-Objektes an, dann stehst du bei solchen Aufgaben nicht immer wie der Ochs vorm Berg face-wink
Member: internet2107
internet2107 Nov 24, 2014 at 18:45:27 (UTC)
Goto Top
Danke erstmal, Uwe.

Nur leider klappt es nicht. Es klappt nicht so, wie es sein soll.
Er legt die Ordner an, er fängt an die Dateien zu formatieren, dann aber kommt schon mal ein Fehler, dass er alle Dateien in einem Ordner speichert und nicht so, wie er sie ausliest.
Also Beispiel: Im ersten Ordner sind 20 Dateien, also müsste er auch im Zielordner wieder 20 Dateien haben. Im zweiten sind 18 Dateien, also müssten im zweiten Zielordner auch 18 sein.
Es sind aber plötzlich im ersten Zielordner alle Dateien enthalten, also auch aus allen anderen Ordnern.

Man möge mir verzeihen, aber ich bin leider nicht so ein Hardcore Programmierer und erfahren, wie du und viele andere hier.

$pfad_allgemein = "c:\quelle"  
$pfad_allgemein_pdf = "d:\bearbeitet"  
$pfad_allgemein_pdf_a = "d:\bearbeitet\pdfa""  

dir -Path $pfad_allgemein -Include *.df1, *.dx1, *.ff1 -recurse | foreach {
$zielDir = $_.DirectoryName.Replace($pfad_allgemein, $pfad_allgemein_pdf)
$zielDir_pdfa = $_.DirectoryName.Replace($pfad_allgemein, $pfad_allgemein_pdf_a)
Write-Host "Zielverzeichnis " $zielDir  
new-item -ItemType Directory -Path $zielDir -Force
new-item -ItemType Directory -Path $zielDir_pdfa -Force
		
}

$DATDateien = gci -Path $pfad_allgemein -Include *.df1, *.dx1, *.ff1 -recurse
ForEach ($used_dat in $DATDateien)
		{
			$objword = New-Object -ComObject word.application
			$objword.visible = $false
			$filepath = Join-Path -Path $zielDir -ChildPath ($used_dat.name + ".pdf")  
			$doc = $objword.documents.Open($used_dat.FullName)
			
			$objword.selection.pagesetup.topmargin = 30
			$objword.selection.pagesetup.leftmargin = 20
			$objword.selection.pagesetup.rightmargin = 10
			$objword.selection.pagesetup.bottommargin = 30
			$selection = $objword.Selection
			$selection.Font.Name = $schriftart
			$selection.Font.Size = $schriftart_groesse_allgmein
			$printout_pagesize = "wdPaper$seite_groesse"  
			$selection.PageSetup.PaperSize = [Microsoft.Office.Interop.Word.WdPaperSize]::$printout_pagesize
			$selection.PageSetup.Orientation = $printout_page_set
					
			$doc.SaveAs([ref]$filepath, [ref]17) #17 steht für PDF
			$doc.Saved = $true
			
			$doc.Close()
			$objword.Quit()
			[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objword)
			
		}

......
hier geht er dann zum zweiten Schritt, zur Umwandlung pdfa....
		
Member: colinardo
colinardo Nov 24, 2014 updated at 20:54:34 (UTC)
Goto Top
hier ging es ja erst einmal nur um eine Grundsatzfrage deinerseits nämlich deine Zeile mit den Fragezeichen ...mehr hatte ich mir nicht angesehen.
Er legt die Ordner an, er fängt an die Dateien zu formatieren, dann aber kommt schon mal ein Fehler, dass er alle Dateien in einem Ordner speichert und nicht so, wie er sie ausliest.
weil du in deinem ersten Code die erste Schleife nicht um deinen kompletten Code legst face-wink in dem du das File zum PDF wandelst ! D.h. $zielDir hat nach deiner ersten Schleife immer den selben Inhalt.

Also machst du es z.B. nach diesem Schema ...
$pfad_allgemein = "c:\quelle"  
$pfad_allgemein_pdf = "d:\bearbeitet"  
$pfad_allgemein_pdf_a = "d:\bearbeitet\pdfa"  

$DATDateien = gci -Path $pfad_allgemein -Include *.df1, *.dx1, *.ff1 -recurse

$objword = New-Object -ComObject word.application
$objword.visible = $false
$objword.DisplayAlerts = $false

foreach($used_dat in $DATDateien){

        $zielDir = $used_dat.DirectoryName.Replace($pfad_allgemein, $pfad_allgemein_pdf)
        Write-Host "Zielverzeichnis "$zielDir  
        If(!(Test-Path $zielDir)){new-item -ItemType Directory -Path $zielDir -Force}

	$filepath = Join-Path -Path $zielDir -ChildPath ($used_dat.name + ".pdf")  
	$doc = $objword.documents.Open($used_dat.FullName)
			
	$objword.selection.pagesetup.topmargin = 30
	$objword.selection.pagesetup.leftmargin = 20
	$objword.selection.pagesetup.rightmargin = 10
	$objword.selection.pagesetup.bottommargin = 30
	$selection = $objword.Selection
	$selection.Font.Name = $schriftart
	$selection.Font.Size = $schriftart_groesse_allgmein
	$printout_pagesize = "wdPaper$seite_groesse"  
	$selection.PageSetup.PaperSize = [Microsoft.Office.Interop.Word.WdPaperSize]::$printout_pagesize
	$selection.PageSetup.Orientation = $printout_page_set
					
	$doc.SaveAs([ref]$filepath, [ref]17) #17 steht für PDF
	$doc.Saved = $true
	$doc.Close()
}

$objword.DisplayAlerts = $true
$objword.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objword)
Viel Erfolg
Member: internet2107
internet2107 Nov 25, 2014 at 06:56:06 (UTC)
Goto Top
Guten Morgen und DANKE, Uwe.
OK. Soweit hast du meinen Tag schon mal gerettet, denn im ersten Schritt läuft es nun so wie es soll.

Aber, es wäre ja schön, wenn ich nicht gerade am zweiten Schritt verzweifel und ich verstehe nicht wieso und warum es nicht geht.

Im Schritt (Code) oben erstellt er ja aus den Dateien nun richtig PDFs, erstellt die Ordner und legt die PDF auch in der Ordnerstruktur ab.
Im zweiten Schritt aber soll er aus den PDFs, PDFa umwandeln.

Im Grunde genommen ist es dasselbe wie oben, nur halt eine andere Arbeitsfolge. Statt Word->PDF, nun PDF->PDFa

Ich habe also nur einen leicht geänderten Code, aber er macht einen Fehler. Obwohl er ja aus dem Ordner (wo im ersten Schritt die generierten PDF liegen), sucht und bearbeitet, speichert er aber auch die geänderteten PDFa nun im selben Ordner.
Und ich finde zum Teufel komm raus den Fehler nicht.. es ist ggrrrrrrr.

###### Ab hier Konvertierung von pdf nach pdf/a

$oPDFCreator = New-Object -ComObject "PDFCreator.clsPDFCreator"  
$oPDFCreatorfiles = gci -Path $pfad_allgemein_pdf -Include *.pdf -Recurse
	
foreach ($pdf_a in $oPDFCreatorfiles)
{
$zielDirpdfa = $pdf_a.DirectoryName.Replace($pfad_allgemein_pdf, $pfad_allgemein_pdf_a)

If (!(Test-Path $zielDirpdfa)) { new-item -ItemType Directory -Path $zielDirpdfa -Force }
		
		$filename_pdfa = Join-Path -Path $zielDirpdfa -ChildPath ($pdf_a.name + ".pdf")  
		
$filename = $pdf_a.FullName

Start-Sleep -m 10000 # 10 Sekunden

if (Test-Path $pdftool_x86)
{
Start-Process $pdftool_x86 ('/IF"' + $filename + '" /OF"' + $filename_pdfa + '" /NoStart /OutputSubFormat"PDF/A-1b"')  
}
else
{
Start-Process $pdftool_x64 ('/IF"' + $filename + '" /OF"' + $filename_pdfa + '" /NoStart /OutputSubFormat"PDF/A-1b"')  
}
([System.Runtime.InteropServices.Marshal]::ReleaseComObject($oPDFCreator) -gt 0)
		
}
Member: colinardo
colinardo Nov 25, 2014 at 09:23:14 (UTC)
Goto Top
Und ich finde zum Teufel komm raus den Fehler nicht.. es ist ggrrrrrrr.
wäre schön wenn du mal die Fehlermeldungen posten würdest, sonst muss ich mir hier immer den Hals verbiegen face-sad

Mache alles immer Schritt für Schritt und gebe Variablen auf der Konsole aus, dann findest du deinen Fehler schon.

PDFCreator verwende ich nicht, deshalb kann ich dir da gerade nicht weiterhelfen, sehe auch nirgends das dieser irgendwo in deinem Code Verwendung findet...und woher die Variable $pdftool_x86 etc. kommen kann ich deinem Code auch nicht entnehmen, sorry. Eventuell Fehlen hier Leerzeichen hinter /IF und /OF.

p.s. geht jetzt eigentlich wieder am Thema des Threads vorbei, und mutiert zu einem Multi-Fragen-Thread !
Member: internet2107
internet2107 Nov 25, 2014 at 09:52:41 (UTC)
Goto Top
Zitat von @colinardo:

wäre schön wenn du mal die Fehlermeldungen posten würdest, sonst muss ich mir hier immer den Hals verbiegen face-sad

PDFCreator verwende ich nicht, deshalb kann ich dir da gerade nicht weiterhelfen, sehe auch nirgends das dieser irgendwo in deinem
Code Verwendung findet...und woher die Variable $pdftool_x86 etc. kommen kann ich deinem Code auch nicht entnehmen, sorry.
Eventuell Fehlen hier Leerzeichen hinter /IF und /OF.


Tja.. das ist ja das Problem face-smile. Es kommt keine Fehlermeldung, sonst würde ich sie gerne posten.
Wie gesagt, macht er ja all das, was er soll. Praktisch. Theoretisch aber alles im Startordner.
Und eben das verstehe ich nicht.

Zu deiner Frage:
Hinter: $pdftool_x86 steht = 'C:\Program Files\PDFCreator\PDFCreator.exe'

Also:
Mit diesem Befehl sage ich ihm ja, lies alle PDFs in diesem Ordner mache damit etwas.

$oPDFCreatorfiles = gci -Path $pfad_allgemein_pdf -Include *.pdf -Recurse 

Und dann sage ich ihm ja, ändere das Zielverzeichnis (noch mal) und lege (noch mal) dieselbe Ordnerstruktur im zweiten Zielordner an, also hierbei PDFa.
!!! Aber genau das macht er nicht !!!
Er legt die Ordner noch mal, weil ( -force ), im zweiten Quellordner an und schreibt die PDFa ebenso in den Quellordner, so dass ich nun im Ordner PDF auch die PDFa-Files habe.
Also:
name_der_datei.dx1.pdf (weil in Schritt 1 über Word zu PDF generiert)
name_der_datei.dx1.pdf.pdf (weil in Schritt 2 von PDF zu PDFa generiert)

foreach ($pdf_a in $oPDFCreatorfiles)
{
$zielDirpdfa = $pdf_a.DirectoryName.Replace($pfad_allgemein_pdf, $pfad_allgemein_pdf_a)

If (!(Test-Path $zielDirpdfa)) { new-item -ItemType Directory -Path $zielDirpdfa -Force }
		
		$filename_pdfa = Join-Path -Path $zielDirpdfa -ChildPath ($pdf_a.name + ".pdf")  

Was ich nicht verstehe: Wir geben ihm einen Quellordner ($pfad_allgemein_pdf) und sagen ihm den weiteren Zielordner ($pfad_allgemein_pdf_a), was ja mit dem Befehl in der Schleife oben zu sehen ist.
$zielDirpdfa = $pdf_a.DirectoryName.Replace($pfad_allgemein_pdf, $pfad_allgemein_pdf_a)
Aber ????????
Member: colinardo
colinardo Nov 25, 2014 updated at 10:26:27 (UTC)
Goto Top
Mach es doch wie oben bereits geschrieben alles in einer einzigen Schleife zusammen:
Also ungetestet (da kein PDF Creator vorhanden) etwa so.
$pfad_allgemein = "c:\quelle"  
$pfad_allgemein_pdf = "d:\bearbeitet"  
$pfad_allgemein_pdf_a = "d:\bearbeitet\pdfa"  

$pdftool_x86 = "$($env:ProgramFiles)\PDFCreator\PDFCreator.exe"  
$pdftool_x64 = "$(${env:ProgramFiles(x86)})\PDFCreator\PDFCreator.exe"  

$DATDateien = gci -Path $pfad_allgemein -Include *.df1, *.dx1, *.ff1 -recurse

$oPDFCreator = New-Object -ComObject "PDFCreator.clsPDFCreator"  
$objword = New-Object -ComObject word.application
$objword.visible = $false
$objword.DisplayAlerts = $false

foreach($used_dat in $DATDateien){
    
    # Pfade setzen ------
    $zielDir = $used_dat.DirectoryName.Replace($pfad_allgemein, $pfad_allgemein_pdf)
    $zielDir_pdf_a = $used_dat.DirectoryName.Replace($pfad_allgemein,$pfad_allgemein_pdf_a)

    If(!(Test-Path $zielDir)){new-item -ItemType Directory -Path $zielDir -Force}
    If(!(Test-Path $zielDir_pdf_a)){new-item -ItemType Directory -Path $zielDir_pdf_a -Force}

	$filepath_pdf = Join-Path -Path $zielDir -ChildPath ($used_dat.name + ".pdf")  
	$filepath_pdf_a = Join-Path -Path $zielDir_pdf_a -ChildPath ($used_dat.name + ".pdf")  
    # ---------------------

    # Word-Umwandlung -------------
	$doc = $objword.documents.Open($used_dat.FullName)
	$objword.selection.pagesetup.topmargin = 30
	$objword.selection.pagesetup.leftmargin = 20
	$objword.selection.pagesetup.rightmargin = 10
	$objword.selection.pagesetup.bottommargin = 30
	$selection = $objword.Selection
	$selection.Font.Name = $schriftart
	$selection.Font.Size = $schriftart_groesse_allgmein
	$printout_pagesize = "wdPaper$seite_groesse"  
	$selection.PageSetup.PaperSize = [Microsoft.Office.Interop.Word.WdPaperSize]::$printout_pagesize
	$selection.PageSetup.Orientation = $printout_page_set
	$doc.SaveAs([ref]$filepath_pdf, [ref]17) #17 steht für PDF
	$doc.Saved = $true
	$doc.Close()
    # ----------------------------
    
    # PDFa umwandlung ------------

    if (Test-Path $pdftool_x86){
        Start-Process $pdftool_x86 ('/IF"' + $filepath_pdf + '" /OF"' + $filepath_pdf_a + '" /NoStart /OutputSubFormat"PDF/A-1b"')  
    }else{
        Start-Process $pdftool_x64 ('/IF"' + $filepath_pdf + '" /OF"' + $filepath_pdf_a + '" /NoStart /OutputSubFormat"PDF/A-1b"')  
    }
    # -----------------------------
}

$objword.DisplayAlerts = $true
$objword.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objword)
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($oPDFCreator)

Und zur Info, das "clearen" der COM-Objekte bei jedem Schleifendurchlauf solltest du nicht machen, das kostet unnötig Zeit. Einmal am Anfang erstellen und zum Schluss einmal freigeben, reicht face-wink

p.s. Nutze zur besseren Strukturierung, Codeeinrückungen, so verlierst du nicht den Überblick ...du hast vermutlich nur einen Flüchtigkeitsfehler in deinem Code...


so i`m out here now, check the doc's !

Viel Erfolg noch
Grüße Uwe