metal008
Goto Top

Ordner mit mehreren csv. Dateien in eine Excel Datei zusammenfassen

Hallo,
ich stehe vor folgendem Problem.
Ich möchte enorme Datenmengen in eine Excel, oder auch Access Datei zusammenfassen.
Ich habe mehrere Ordner mit jeweils über 7000 csv. Dateien, die innerhalb eines Ordners gleich aufgebaut sind (Marktdaten verschiedener Jahre).
Ich benötige ein Makro, welches sehr ressourcensparend die csv. Dateien einliest und die ursprünglichen Ordner, jeweils in eine einzelne Arbeitsmappe integriert.
Hierfür sollen die csv. Datein eingelesen und untereinander aufgelistet werden.
Die csv. Dateien beinhalten in der ersten Zeile jeweils die Überschriften, die nicht jedes Mal mitkopiert werden sollen.
Zudem soll die Zeile 6596 nicht mitkopiert werden, da diese nur die Anzahl der gesamten Zeilen anzeigt. Die durch das Löschen entstandenen, leeren Zeilen, sollen gelöscht werden, sodass eine nahtlose Datentabelle entsteht.

3613deb2b7af7f89bb63096219a728e2

Die Spaltentrennung erfolgt mit Semikolons.

Über Ihre Hilfe bin ich sehr dankbar.

VG
Metal008

Content-Key: 285960

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

Printed on: April 18, 2024 at 03:04 o'clock

Mitglied: 114757
114757 Oct 18, 2015, updated at Oct 22, 2015 at 11:09:22 (UTC)
Goto Top
Member: Metal008
Metal008 Oct 22, 2015 updated at 11:08:52 (UTC)
Goto Top
Hallo,

vielen Dank jodel32. Ich habe für mich den folgenden Code herausgesucht, der freundlicherweise von "colinardo" bereitgestellt wurde.
Jedoch möchte ich, dass automatisch aus den .csv Dateien die Daten nur ab Zeile 8 in die Arbeitsmappe kopiert werden. Es müsste also eine Automatik im Code implementiert werden, die alle Zeilen mit Daten ab Zeile 8 (,da davor Überschrift) und außer der letzten (,da Prüfsumme) . Hintereinander kopiert. Außerdem werden nur die ersten 158 .csv Dateien eingelesen. Dann wird der Fehler 400 angezeigt. Es wäre nett, wenn Sie den Code dahingehend ändern könnten.

VG
Metal008

Sub ImportCSVFromFolder()
    Dim wsTemp As Worksheet, wsTarget As Worksheet, curCell As Range, CSVPFAD As String, fso As Object, f As Object, strCSVDelimiter As String
    
    With Application.FileDialog(msoFileDialogFolderPicker)
        .InitialFileName = "C:\"  
        .Title = "Ordnerauswahl"  
        .ButtonName = "Auswahl..."  
        .InitialView = msoFileDialogViewList
        If .Show = -1 Then
            CSVPFAD = .SelectedItems(1)
        Else
            Exit Sub
        End If
    End With
    
    'Legt das CSV-Trennzeichen für die Dateien fest  
    strCSVDelimiter = ";"  
    
    Set fso = CreateObject("Scripting.Filesystemobject")  
    Application.DisplayAlerts = False
    Application.ScreenUpdating = False
    
    'Zielarbeitsblatt für die importierten Daten  
    Set wsTarget = Worksheets(1)
    wsTarget.Name = "Zusammenfassung"  
    'temporäres Arbeitsblatt für den Import der Daten erstellen  
    Set wsTemp = Worksheets.Add(After:=Worksheets(Worksheets.Count))
    
    'Inhalt des Zusammenfassungsblattes löschen  
    wsTarget.UsedRange.Clear
    
    'Startausgabezelle festlegen  
    Set curCell = wsTarget.Range("A1")  
    For Each f In fso.GetFolder(CSVPFAD).Files
        If LCase(fso.GetExtensionName(f.Name)) = "csv" Then  
            'Temporäres Sheet löschen  
            wsTemp.UsedRange.Clear
            'CSV-Daten in Temporäres Sheet importieren  
            With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & f.Path, Destination:=wsTemp.Range("$A$1"))  
                .Name = "import"  
                .FieldNames = True
                .AdjustColumnWidth = True
                .RefreshPeriod = 0
                .TextFilePlatform = xlWindows
                .TextFileStartRow = 1
                .TextFileParseType = xlDelimited
                .TextFileTextQualifier = xlTextQualifierDoubleQuote
                .TextFileOtherDelimiter = strCSVDelimiter
                .Refresh BackgroundQuery:=False
                .Delete
            End With
            
            With wsTemp
                'Daten in Zielsheet kopieren  
                .UsedRange.Copy curCell
            End With
            'Ausgabezeile eins nach unten schieben  
            Set curCell = wsTarget.Cells(wsTarget.UsedRange.Rows.Count + 2, 1)
        End If
    Next
    'Temporäres Sheet löschen  
    wsTemp.Delete
    'Spalten anpassen  
    wsTarget.Columns.AutoFit
    
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
    MsgBox "Vorgang beendet!", vbInformation  
    Set fso = Nothing
End Sub
Mitglied: 114757
114757 Oct 22, 2015, updated at Nov 05, 2015 at 14:52:35 (UTC)
Goto Top
Geht doch viel schneller mit Powershell
$folder = 'C:\csv'  
$out = 'C:\zusammenfassung.csv'  
gci $folder -Filter *.csv | %{
    $raw = ((gc $_.FullName) | select -Skip 7)
    $raw[0..($raw.GetUpperBound(0)-1)] | ConvertFrom-CSV -Delimiter ";" -Header 1,2,3,4,5,6,7  | export-csv $out -Append -Delimiter ";" -Notype -Encoding UTF8  
}
Gruß jodel32
Member: Metal008
Metal008 Oct 22, 2015 updated at 13:46:36 (UTC)
Goto Top
Danke für die rasche Antwort.

für ein paar Dateien hat es geklappt. Nun bekomme ich folgende Fehlermeldung:
Wenn ich -Force hinzufüge bleiben einige Spalten der Zusammenfassung einfach leer. Wie mir schein weisen einige csv Dateien Formatierungsfehler auf. (aus Zahlen wurde Ein Datum).
Zudem erzeugt der Code aus ursprünglich ca. 800 Zeilen nun über 1000 Zeilen

export-csv : CSV-Inhalt kann nicht an folgende Datei angefügt werden: C:\Users\Jan Ole\Desktop\Neuer
Ordner\zusammenfassung.csv. Das angefügte Objekt hat keine Eigenschaft, die der folgenden Spalte entspricht: 335.0.
Soll der Ablauf mit nicht übereinstimmenden Eigenschaften fortgesetzt werden, fügen Sie den Parameter "-Force" hinzu,  
und wiederholen Sie den Vorgang.
In Zeile:5 Zeichen:76
+ ... iter ";"  | export-csv $out -Append -Delimiter ";" -Notype -Encoding  ...  
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (335.0:String) [Export-Csv], InvalidOperationException
    + FullyQualifiedErrorId : CannotAppendCsvWithMismatchedPropertyNames,Microsoft.PowerShell.Commands.ExportCsvComman
   d
Mitglied: 114757
114757 Oct 22, 2015 updated at 13:54:45 (UTC)
Goto Top
Zitat von @Metal008:

Danke für die rasche Antwort.

für ein paar Dateien hat es geklappt. Nun bekomme ich folgende Fehlermeldung:
Wenn ich -Force hinzufüge bleiben einige Spalten der Zusammenfassung einfach leer. Wie mir schein weisen einige csv Dateien Formatierungsfehler auf. (aus Zahlen wurde Ein Datum).
Zudem erzeugt der Code aus ursprünglich ca. 800 Zeilen nun über 1000 Zeilen
Der Code geht davon aus das in Zeile 8 die Überschriften der Spalten stehen ! Ist das nicht der Fall und dort stehen schon die eigentlichen Daten musst du die Überschriften der Spalten dem Befehl Convertfrom-CSV mit dem Parameter -Header 1,2,3,4,5,6 mitteilen. in diese, Beispiel hat dann die CSV 6 Spalten durchnummeriert von 1 bis 6.

Da du hier keine Beispieldaten postest und ob die CSV im Inhalt (Spaltenmässig abweichen) face-sad ist das wie immer Glaskugelbowling ... Geht hier ansonsten einwandfrei.
Deswegen läuft bei dir bestimmt der Code von @colinardo auch nicht weil du uns irgendwo was verschweigst, oder deine CSV nicht konsistent aufgebaut sind oder Fehler enthalten. Das können wir hier ja leider nicht sehen!
Member: Metal008
Metal008 Oct 22, 2015 updated at 14:24:47 (UTC)
Goto Top
Anbei mal ein Bild des csv Anfangs und des Endes. Spalte A - G Enthalten Daten. Die Überschrift Zeile 1-7 und die Prüfsumme (Die letzte Zeile mit Daten) soll nicht mitkopiert werde.

http://fs5.directupload.net/images/151022/c24gds38.png

http://fs5.directupload.net/images/151022/to7ezwb9.png
Mitglied: 114757
114757 Oct 22, 2015 at 14:29:55 (UTC)
Goto Top
Zitat von @Metal008:

Anbei mal ein Bild des csv Anfangs und des Endes. Spalte A - G Enthalten Daten.
Code ist oben angepasst so das alle CSV 7 Spalten haben müssen
Die Überschrift Zeile 1-7 und die Prüfsumme (Die letzte Zeile mit Daten) soll nicht mitkopiert werde.
Das war schon implementiert ...
Bitte keine externen Bilder verlinken, das Forum hat eine Bilderuploadfunktion im Ursprungsbeitrag!
Member: Metal008
Metal008 Oct 25, 2015 at 10:30:48 (UTC)
Goto Top
Hallo,

vielen Dank. Nun hat es endlich geklappt.

VG
Metal008
Member: Metal008
Metal008 Oct 25, 2015 at 19:53:43 (UTC)
Goto Top
Wie kann man den Zeitstempel 2012-01-01T00:15:00+01:00 in per Makro in TT-MM-JJJJ HH:MM:SS umwandeln ?
die + 01:00 ist Universal Time Coordinated + 1 h.

VG
Metal008
Mitglied: 114757
114757 Oct 25, 2015 updated at 20:12:09 (UTC)
Goto Top
Get-Date '2012-01-01T00:15:00+01:00' -Format 'dd-MM-yyyy HH:mm:ss'  
Google kaputt ??
Member: Metal008
Metal008 Oct 27, 2015 at 10:26:08 (UTC)
Goto Top
Ich hatte gegooglet, habe jedoch nichts gefunden. Ich habe versucht den Code in Excel zu verwenden und in den powershellcode einzufügen.
beides ging nicht.

Sorry, ich habe leider keinerlei Wissen auf diesem Gebiet.

VG
Metal008
Mitglied: 114757
114757 Oct 27, 2015, updated at Nov 05, 2015 at 14:52:49 (UTC)
Goto Top
Zitat von @Metal008:
Ich hatte gegooglet, habe jedoch nichts gefunden. Ich habe versucht den Code in Excel zu verwenden
Geht nicht ist ja auch PS Code
und in den powershellcode einzufügen.
beides ging nicht.
"Was" ging nicht ? Mein Code oben geht einwandfrei ... Du musst schon sagen was du machen willst ...

Beispiel:
Wenn in Spalte 7 das Ursprungs-Datum mit TZ Info steht wird es so in dein gewünschtes Format umgewandelt:
$folder = 'C:\csv'  
$out = 'C:\zusammenfassung.csv'  
gci $folder -Filter *.csv | %{
    $raw = ((gc $_.FullName) | select -Skip 7)
    $csv = $raw[0..($raw.GetUpperBound(0)-1)]| ConvertFrom-CSV -Delimiter ";" -Header 1,2,3,4,5,6,7  
    $csv | %{$_.7 = get-date $_.7 -Format 'dd-MM-yyyy HH:mm:ss'}  
    $csv | export-csv $out -Append -Delimiter ";" -Notype -Encoding UTF8  
}
Member: Metal008
Metal008 Oct 27, 2015 at 10:58:42 (UTC)
Goto Top
In Spalte 3,5 und 6 sind Datum + Uhrzeit ( 2012-01-01T00:15:00+01:00 ). Ich habe den Code nun angewendet und die Zusammenstellung der Dateien klappt. Jedoch behält er das Datum bei. (habe im Code aus der 7 eine 6 gemacht).

$folder = 'C:\Users\Neuer Ordner'  
$out = 'C:\Users\Neuer Ordner\zusammenfassung.csv'  
gci $folder -Filter *.csv | %{
    $raw = ((gc $_.FullName) | select -Skip 7)
    $csv = $raw[0..($raw.GetUpperBound(0)-1)]| ConvertFrom-CSV -Delimiter ";" -Header 1,2,3,4,5,6,7  
    $csv | %{$_.6 = get-date $_.6 -Format 'dd-MM-yyyy HH:mm:ss'}  
    $csv | export-csv $out -Append -Delimiter ";" -Notype -Encoding UTF8  
}


Excel erkennt in der Ursprungsdatei nicht, dass es sich um ein Datum plus Zeitangabe handelt. Ich möchte, dass das Format so umgewandelt wird, dass dies der Fall ist, da ich andernfalls keine Diagramme mit den Daten erstellen kann.

Zudem wäre es wünschenswert, wenn Spalte 4 als (Zahlen Werte) importiert wird, die nicht mit einem Dezimalkomma, sondern einem Punkt als Dezimaltrennzeichen getrennt werden.
Mitglied: 114757
114757 Oct 27, 2015 updated at 14:40:09 (UTC)
Goto Top
Jedoch behält er das Datum bei. (habe im Code aus der 7 eine 6 gemacht).
Nö, geht hier problemlos.
Für ein eingedeutschtes Excel nimmst du als Format einfach dd.MM.yyyy HH:mm:ss
Zudem wäre es wünschenswert, wenn Spalte 4 als (Zahlen Werte) importiert wird,
Einfach ein Replace des Kommas durch einen Punkt machen face-wink
http://ss64.com/ps/replace.html
Member: Metal008
Metal008 Nov 04, 2015 at 18:39:58 (UTC)
Goto Top
Vielen Dank es geht face-smile

Ich habe nun gemerkt, dass die Datein sehr mächtig werden.

1. Gibt es eine Möglichkeit, dass automatisch alle Unterordner und Unterunterordner ... ebenfalls durchsucht werden ?

2. Es wäre dann zusätzlich wünschenswert, wenn ausgehend von Spalte 2 die Daten gefiltert (nach DE oder AT) werden und

jeweils eine Arbeitsmappe für "DE" und eine für "AT" erstellt wird, in die jeweils die Zeilen kopiert werden.

Spalte1_______ Spalte 2 ....
wert 1de______ DE
wert 1at_______AT
wert 2de ______DE
wert 2at ______AT


in

Arbeitesmappe DE:

Spalte1_________Spalte 2 ....
wert 1de _______ DE
wert 2de _______ DE
...

Arbeitesmappe AT:

Spalte1 ________Spalte 2 ....
wert 1at _______AT
wert 2at________AT
...


Vielen Dank
Mitglied: 114757
114757 Nov 04, 2015, updated at Nov 05, 2015 at 14:01:30 (UTC)
Goto Top
$folder = 'C:\Ordner'  
$outAT = 'C:\Ausgabe\AT.csv'  
$outDE = 'C:\Ausgabe\DE.csv'  
gci $folder -Filter *.csv -recurse | %{
    $raw = ((gc $_.FullName) | select -Skip 7)
    $csv = $raw[0..($raw.GetUpperBound(0)-1)]| ConvertFrom-CSV -Delimiter ";" -Header 1,2,3,4,5,6,7  
    $csv | %{$_.6 = get-date $_.6 -Format 'dd.MM.yyyy HH:mm:ss'}  
    $csv | ?{$_.2 -eq 'AT'} | export-csv $outAT -Append -Delimiter ";" -Notype -Encoding UTF8  
    $csv | ?{$_.2 -eq 'DE'} | export-csv $outDE -Append -Delimiter ";" -Notype -Encoding UTF8  
}
Gruß jodel
Member: Metal008
Metal008 Nov 04, 2015 at 19:11:43 (UTC)
Goto Top
Unglaublich, wie schnell einem hier geholfen wird. Vielen Dank.

Es werden nun zwei Dateien erzeugt und die Unterordner werden auch durchsucht.
Dennoch wird dieser Fehlercode erzeugt:

Export-Csv : Das Argument für den Parameter "Path" kann nicht überprüft werden. Das Argument ist NULL oder leer. Geben  
Sie ein Argument an, das nicht NULL oder leer ist, und führen Sie den Befehl erneut aus.
In Zeile:10 Zeichen:23
+     $csv | export-csv $out -Append -Delimiter ";" -Notype -Encoding U ...  
+                       ~~~~
    + CategoryInfo          : InvalidData: (:) [Export-Csv], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.ExportCsvCommand
Mitglied: 114757
114757 Nov 04, 2015 updated at 19:24:19 (UTC)
Goto Top
Uups da hab ich vergessen die alte Export-Zeile rauszunehmen ...ist korrigiert. Zu viel am Hut heute :...hechel
Member: Metal008
Metal008 Nov 04, 2015 at 19:57:07 (UTC)
Goto Top
Mist habs selber übersehen, jedoch wird mir nun dieser Fehler angezeigt:

Es ist nicht möglich, eine Methode für einen Ausdruck aufzurufen, der den NULL hat.
In Zeile:6 Zeichen:5
+     $csv = $raw[0..($raw.GetUpperBound(0)-1)]| ConvertFrom-CSV -Delim ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) , RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull


Was bedeutet das ?


Zudem habe ich bemerkt, dass der Zeitstempel falsch umgewandelt wird.
Aus 2012-01-10T05:00:41+01:00 wird 10.01.2012 05:00 . Die Sekunden und Minuten werden irgendwie nicht übernommen.

Außerdem werden die Daten aus der CSV Datei des "obersten Ordners" dreimal in die neue erzeugte Datei geladen.
Mitglied: 114757
114757 Nov 05, 2015 updated at 14:53:00 (UTC)
Goto Top
Außerdem werden die Daten aus der CSV Datei des "obersten Ordners" dreimal in die neue erzeugte Datei geladen.
Wenn du die CSV im gleichen Ordner ausgibst den du ausliest, wie deine vorgerigen Pfade aussahen, kein Wunder...

Die anderen Sachen kannst du mit minimalem lesen der Doku selber herausfinden, anstatt uns hier deine Arbeit machen zu lassen!
Member: Metal008
Metal008 Nov 05, 2015 at 14:01:21 (UTC)
Goto Top
Danke für den Hinweis mit dem Ordner. Das eine Schleife gebildet wird war mir nicht bewusst.

Das Skript ist für ein Uni Fach. Ich hatte bereits im Internet geschaut, jedoch nichts gefunden, welches mir geholfen hat.

Aber vielen Vielen Dank für die unglaublich schnelle und kompetente Hilfe.
Member: Metal008
Metal008 Mar 14, 2016 at 19:33:13 (UTC)
Goto Top
Hallo ich habe die Probleme nun überwunden.

Ich habe nun ein anderes Problem, welches an die ursprüngliche Problematik anschließt.

Ich habe 6 Spalten mit vielen Zeilen an Daten.

In Spalte 3 befindet sich der "TimeStamp" auf den sich die Messwerte beziehen. In Spalte 5 der PublicationTimeStamp und in Spalte 6 der ModificationTimeStamp. Es gibt nun mehrere Zeilen mit dem gleichen "TimeStamp" Spalte 3, jedoch unterschiedlich aktuelle PublicationTimeStamps und ModificationTimeStamps.

Ich benötige einen Filter, der doppelte Einträge in Spalte 3 (TimeStamp) erkennt und nach Aktualität( Spalte 5 und 6 )untersucht. In die neue csv. Datei soll jeweils nur der aktuelle Timestamp, anhand von Spalte 5 und 6 geschrieben werden.

Der aktuelle Code in dem diese Funktion eingebunden werden soll ist:

$folder = 'C:\Users\ICH\Desktop\Import'  
$outEW = 'C:\Users\ICH\Desktop\Export\EW.csv'  
$outEN = 'C:\Users\ICH\Desktop\Export\EN.csv'   
$outRT = 'C:\Users\ICH\Desktop\Export\RT.csv'  
$outVE = 'C:\Users\ICH\Desktop\Export\VE.csv'  
gci $folder -Filter *.csv -recurse | %{
    $raw = ((gc $_.FullName) | select -Skip 7) 
    $csv = $raw[0..($raw.GetUpperBound(0)-1)]| ConvertFrom-CSV -Delimiter ";" -Header 1,2,3,4,5,6,7   
    $csv | %{$_.3 = get-date $_.3 -Format 'MM/dd/yyyy HH:mm:ss'}   
    $csv | %{$_.5 = get-date $_.5 -Format 'MM/dd/yyyy HH:mm:ss'}   
    $csv | %{$_.6 = get-date $_.6 -Format 'MM/dd/yyyy HH:mm:ss'}   
    $csv | ?{$_.2 -eq 'Auto'} | export-csv $outEW -Append -Delimiter ";" -Notype -Encoding UTF8   
    $csv | ?{$_.2 -eq 'Katze'} | export-csv $outEN -Append -Delimiter ";" -Notype -Encoding UTF8   
    $csv | ?{$_.2 -eq 'Hannes'} | export-csv $outRT -Append -Delimiter ";" -Notype -Encoding UTF8   
    $csv | ?{$_.5 -eq 'Wurst'} | export-csv $outVE -Append -Delimiter ";" -Notype -Encoding UTF8   
}

Vielen Dank im Voraus.

LG Metal 008
Mitglied: 114757
114757 Mar 15, 2016 updated at 08:02:28 (UTC)
Goto Top
Zitat von @Metal008:

Ich benötige einen Filter, der doppelte Einträge in Spalte 3 (TimeStamp) erkennt
select -Unique ist dein Freund für doppelte Einträge
und nach Aktualität( Spalte 5 und 6 )untersucht. In die neue csv. Datei soll jeweils nur der aktuelle Timestamp, anhand von Spalte 5 und 6 geschrieben werden.
sort-object ist dein Freund