none
Frage zu Get-childitem RRS feed

  • Frage

  • Hallo zusammen.

    Ich habe folgendes Problem und wäre über Hilfe sehr dankbar.
    Ich einem Ordner habe ich unzählige Dateien, die bei einem Datenexport geschrieben werden. Der Export erzeugt dann verschiedene *.xlsb-Dateien (Excel). Die Daten sehen dann z.B. so aus:

    Beispiel1_10001.xlsb
    Beispiel1_10002.xlsb
    Beispiel1_10003.xlsb
    Beispiel1_10003.xls

    Ebenso liegt in diesem Ordner aber auch eine Datei, die dann die Endung *.xls enthält. Diese Datei wurde von der Softwareausgabe als Export erzeugt und umfasst demnach den Export der letzten .xlsb-Datei, in diesem Fall z.B. der Beispiel1_10003.xlsb.

    Ich erzeuge nun aus der *.xls-Datei ein PDF, was auch klappt. Nur verlangen es die Vorschriften, dass nicht die *.xls Datei in PDF umgewandelt wird, sondern es MUSS die letzte *.xlsb-Datei verwendet werden, da man ja nicht 100% sicher sein kann, dass der Datenexport von xlsb auf xls einwandfrei richtig war.

    Nun meine Frage:
    Wie kann ich bitte per get-childitem die richtige und demnach letzte xlsb-Datei verwenden, indem ich per Befehl nur den Text der xls-Datei in eine Variable speichere, also (nehme den Text Beispiel1_10003 und hänge die Endung xlsb dran) ?. Dann weiß ich, dass die richtige Datei habe und kann diese dann nach PDF umwandeln.

    Freitag, 4. Juli 2014 11:36

Antworten

  • Hallo agenosko!

    Du hast die *.xlsb Dateien schon in der Variablen $b, da macht es keinen sin diese Dateien noch einmal einzulesen.

    Du benutzt hier Where-Object völlig falsch.
    Where-Object arbeitet mit den Objekten die über die Pipeline (Symbol | ) kommen. Du vergleichst in Where-Object nicht den Inhalt der Pipeline sondern immer die 2 Arrays. Das muss schief gehen.

    Ich würde es So machen

    # zeige nur XLS Dateien
    $XLSDateien = Get-ChildItem "Pfad_zu_den_Dateien" -include *.xls -recurse
    
    # zeige nur XLSB Dateien
    $XLSBDateien = Get-ChildItem "Pfad_zu_den_Dateien" -include *.xlsb -recurse
    
    # Für jede *.xls Datei in der Liste (Array) wird etwas gemacht
    ForEach($xls in $XLSDateien) {
        
        # Für jede *.xlsb Datei in der Liste (Array) wird etwas gemacht
        ForEach($xlsb in $XLSBDateien){
            
            # vergleichen ob die Aktuell verarbeitete *.xls Datei den selben Namen hat
            # wie die Aktuell verarbeitete *.xlsb Datei
            If($xls.BaseName -eq $xlsb.BaseName){
                # passende Datei ausgeben
    
                $xlsb
            }
        }
    }

    P.S. Bitte nutze die Möglichkeit in diesem Forum Code als Code einzufügen!
    (Das Symbol mit den Spitzen Klammern <> im Editor Fenster)


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    • Als Antwort vorgeschlagen Peter Kriegel Montag, 7. Juli 2014 10:01
    • Als Antwort markiert agenosko Dienstag, 8. Juli 2014 04:52
    Montag, 7. Juli 2014 06:03

Alle Antworten

  • Moin,

    gehen wir davon aus, dass die xls-Datei die Einzige im Ordner ist?

    Dann ginge vielleicht etwas wie:

    $file = Get-ChildItem *.xls
    $newfile = $var.BaseName + ".xlsb"
    Get-ChildItem $newfile

    Viele Grüße
    Olaf

    Freitag, 4. Juli 2014 12:09
  • $ThisFileMustBeConvertedToPDF = Get-ChildItem *.xlsb | sort LastWriteTime -Descending | Select-Object -First 1
    

    Freitag, 4. Juli 2014 12:45
  • Vielen Dank zu beiden Antworten, nur leider habe ich vergessen zu schreiben, dass im Ordner auch ggf. mehrere .xls Dateien enthalten sind, dazu auch der "Master", also die jeweilige .xlsb Datei.
    Um es demnach besser zu verdeutlichen, ist im Extremfall dieses Listing vorhanden. Darum nützt ggf. Das Sortieren des "LastwrtiteTime" weniger, oder sehe ich das falsch ?

    Beispiel1_10001.xlsb

    Beispiel1_10002.xlsb

    Beispiel1_10003.xlsb

    Beispiel1_10003.xls
    

Beispiel1_10011.xlsb
    
Beispiel1_10012.xlsb
    
Beispiel1_10013.xlsb

    Beispiel1_10013.xls


    Beispiel1_10021.xlsb

    Beispiel1_10022.xls

    Beispiel1_10023.xlsb
    Beispiel1_10023.xls
    Freitag, 4. Juli 2014 16:17
  • Um meinen aktuellen Code mal zu posten, der ja auch soweit einwandfrei funktioniert und die XLS jeweils ins PDF umwandelt, Code-Ausschitt 

    $path = $folder.Self.Path
    	$xlFixedFormat = "Microsoft.Office.Interop.Excel.xlFixedFormatType" -as [type]
    		$excelFiles = Get-ChildItem -Path $path -include *.xls -Recurse
    		#$excelFiles = Get-ChildItem -Path $path -include *.xlsb -Recurse | select -last 1
    		$objExcel = New-Object -ComObject excel.application
    	$objExcel.visible = $false
    	
    	foreach ($wb in $excelFiles)
    		{
    			
    		$filepath = Join-Path -Path $pfad_allgemein_pdf -ChildPath ($wb.BaseName + ".pdf")
    		$workbook = $objExcel.workbooks.open($wb.fullname, 3)
    		$ExcelWorkSheet = $objExcel.WorkSheets.item("1")
    		$ExcelWorkSheet = $objExcel.WorkSheets.item("2")
    		$ExcelWorkSheet = $objExcel.WorkSheets.item("3")
    		$ExcelWorkSheet = $objExcel.WorkSheets.item("4")
    		$ExcelWorkSheet = $objExcel.WorkSheets.item("5")
    		$ExcelWorkSheet = $objExcel.WorkSheets.item("6")
    		
    		foreach ($ExcelWorkSheet in $objExcel.WorkSheets)
    		{
    			$usedRange = $ExcelWorkSheet.UsedRange
    			$objExcel.WorkSheets.item("3").PageSetup.Orientation = 2
    			$objExcel.WorkSheets.item("3").PageSetup.Orientation = 2
    				$objExcel.WorkSheets.item("2").Columns.Font.Size = $schriftart_groesse_log
    				$objExcel.WorkSheets.item("2").pagesetup.bottommargin = 30
    				$ExcelWorkSheet.PageSetup.PrintTitleRows = "$1:$1"
    				$ExcelWorkSheet.PageSetup.HeaderMargin = $objExcel.InchesToPoints(0.04)
    			$ExcelWorkSheet.PageSetup.FooterMargin = $objExcel.InchesToPoints(0.04)
    			$ExcelWorkSheet.pagesetup.topmargin = 30
    			$ExcelWorkSheet.pagesetup.leftmargin = 20
    			$ExcelWorkSheet.pagesetup.rightmargin = 10
    			$ExcelWorkSheet.pagesetup.bottommargin = 30
    			$ExcelWorkSheet.UsedRange.Columns.AutoFit() | Out-Null
    			$ExcelWorkSheet.UsedRange.Columns.Font.Name = "$schriftart"
    			$ExcelWorkSheet.UsedRange.Columns.Font.Size = $schriftart_groesse_allgmein
    			$ExcelWorkSheet.pageSetup.CenterHeader = "&9 &N"
    			$ExcelWorkSheet.pageSetup.CenterFooter = "Worksheet: &B"
    			$ExcelWorkSheet.pageSetup.LeftFooter = "&9 Page &S of &A"
    				$ExcelWorkSheet.pageSetup.RightFooter = "&9 &D"
    				$ExcelWorkSheet.pagesetup.printheadings = $true
    				
    				
    		}
    				
    		$workbook.Saved = $true
    		"saving $filepath"
    		$workbook.ExportAsFixedFormat($xlFixedFormat::xlTypePDF, $filepath)
    		$objExcel.Workbooks.close()
    		$objExcel.quit()
    			
    		}
    	[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objExcel)
    	#Ende

    Wie man ja oben sehen kann, liest er ja jeweils eine der im Ordner befindlichen xls-Dateien ein und verarbeitet diese. Die XLS Datei hat aber auch einen gleichnamigen XLSB-Master. Der Idealfall wäre also, wenn ich es schaffen würde, den Dateinamen der Datei zwischen zu speichern, um dann wiederum zu sagen, nimm den Dateinamen ohne das xls und lese dafür mit dem Dateinamen die xlsb Datei ein und verarbeite sie. Und hierbei tue ich mich etwas schwer :(

    Freitag, 4. Juli 2014 16:28
  • Vorausgesetzt, du hast dich bei der Auflistung der Dateinamen einmal vertippt (zu Beispiel1_10021.xlsb passt nicht Beispiel1_10022.xls), passt dann doch eher die Lösung von Olaf. Ich hab sie mal in eine Schleife gepackt:

    Get-ChildItem *.xls | %{
        $xlsb_file = $_.BaseName + '.xlsb'
        if (Test-Path $xlsb_file) { Write-Host "Convert-Xlsb2Pdf", $xlsb_file }
    }
    Die Konvertierung in PDF würde ich der Übersicht halber in eine Funktion auslagern. Ich hab sie in meinem Beispiel mal Convert-Xlsb2Pdf genannt.
    Freitag, 4. Juli 2014 17:28
  • Hallo und guten Tag. Sorry, dass ich mich erst heute wieder melde, habe aber erst heute dazu Zeit gehabt, den letzten Vorschlag mal zu testen.

    Leider klappt es noch nicht so wie es sein sollte. Er nimmt leider immer die falschen Dokumente, bzw. nimmt auch XLSB, die nicht als PDF exportiert werden sollen.

    Kann man es nicht so machen, z.B:
    $excelFiles = Get-ChildItem -Path $path -include *.xls -Recurse | where { $_.basename + '.xlsb' }

    Er soll ja nichts Anderes machen, als den Text bis zur Endung der .xls nehmen, dann schauen, welche .xlsb- Datei in dem Ordner hat denselben Namen und verarbeitet dann die xlsb-Datei.
    Mit der XLS-Datei klappt alles einwandfrei, so wie es sein soll. Nur tue ich mich absolut schwer dem Code zu vermitteln, nimm die gleichnamige XLSB-Datei und verarbeite diese.


    Sonntag, 6. Juli 2014 11:33
  • Hat jemand noch eine Idee, wie ich es richtig filtern kann ?. Meine Idee ist nun gewesen, die Ordner einzulesen und das er einmal nur nach *.xls Dateien und im zweiten Fall nur nach *.xlsb Dateien sucht. Macht er auch richtig. Der letzte Schritt soll dann sein, dass er mir nur die *.xlsb Dateien anzeigt, die denselben Namen (ohne Endung) haben, wie die *.xls Datei.
    Er zeigt mir aber dennoch immer eine Datei zuviel an, also es kommt immer wieder eine Datei hinzu, die als *.xls Datei nicht vorhanden ist.

    # zeige nur XLS Dateien
    $a = Get-ChildItem "Pfad_zu_den_Dateien" -include *.xls -recurse

    # zeige nur XLSB Dateien
    $b = Get-ChildItem "Pfad_zu_den_Dateien" -include *.xlsb -recurse

    # Ausgabe nur XLSB, die denselben Namen hat (ohne Endung) wie die XLS
    Get-ChildItem "Pfad_zu_den_Dateien" - filter *.xlsb | Where-Object { $a.basename -eq $b.basename}


    Ich verzweifle langsam :(

    Montag, 7. Juli 2014 04:58
  • Hallo agenosko!

    Du hast die *.xlsb Dateien schon in der Variablen $b, da macht es keinen sin diese Dateien noch einmal einzulesen.

    Du benutzt hier Where-Object völlig falsch.
    Where-Object arbeitet mit den Objekten die über die Pipeline (Symbol | ) kommen. Du vergleichst in Where-Object nicht den Inhalt der Pipeline sondern immer die 2 Arrays. Das muss schief gehen.

    Ich würde es So machen

    # zeige nur XLS Dateien
    $XLSDateien = Get-ChildItem "Pfad_zu_den_Dateien" -include *.xls -recurse
    
    # zeige nur XLSB Dateien
    $XLSBDateien = Get-ChildItem "Pfad_zu_den_Dateien" -include *.xlsb -recurse
    
    # Für jede *.xls Datei in der Liste (Array) wird etwas gemacht
    ForEach($xls in $XLSDateien) {
        
        # Für jede *.xlsb Datei in der Liste (Array) wird etwas gemacht
        ForEach($xlsb in $XLSBDateien){
            
            # vergleichen ob die Aktuell verarbeitete *.xls Datei den selben Namen hat
            # wie die Aktuell verarbeitete *.xlsb Datei
            If($xls.BaseName -eq $xlsb.BaseName){
                # passende Datei ausgeben
    
                $xlsb
            }
        }
    }

    P.S. Bitte nutze die Möglichkeit in diesem Forum Code als Code einzufügen!
    (Das Symbol mit den Spitzen Klammern <> im Editor Fenster)


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    • Als Antwort vorgeschlagen Peter Kriegel Montag, 7. Juli 2014 10:01
    • Als Antwort markiert agenosko Dienstag, 8. Juli 2014 04:52
    Montag, 7. Juli 2014 06:03
  • DANKE!!!!!!!!

    Das war's. Nun klappt es so, wie es sein soll !!. Super. Schönen Tag und schöne Woche
    Montag, 7. Juli 2014 06:18