Kombinieren von txt bzw. csv Dateien

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Kombinieren von txt bzw. csv Dateien

    Guten Abend,

    Ich wollte mal fragen ob es möglich ist, mehre txt bzw. csv Dateien aus einem Verzeichnis miteinander zu kombiniere und dann als neue Datei, in einem anderen Verzeichnis auszugeben?

    Es soll nur der Header bzw. die erste Zeile der ersten Datei und bei den übrigen Dateien ab der zweiten Zeile kombiniert werden und kann dabei die Spaltenanzahl automatisch ermittelt werden?

    Ich vermute mal das es irgendwie mit dem Streamwriter gemacht werden kann, mir fehlt aber die Erfahrung und der Fundus worauf ich achten muss.

    Freue mich über Rückmeldung und Hinweise.

    Grüße Sam
    @Sam85 Egal, welchen Aufbau sie haben: Ja. Dafür gibt es die .AppendXXX()-Funktionalität.
    Die andere Frage ist: Ist es sinnvoll, solch Dateien aneinander anzuhängen?
    Du kannst sie alle einlesen, im Programm den Datenaufbau vereinheitlichen und dann als eine Datei abspeichern.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @VB1963 exakt, der Aufbau ist immer identisch.

    @RodFromGermany in gewisser Weise gebe ich dir Recht:
    Da ich die Daten aber in Monaten erhalte und sie dann erst in ein Jahr umwandeln will und dann die Jahre wiederum auch zusammenfassen will,
    war das meine Grundidee. Oder gibt es eine bessere Alternative?
    @Sam85 Dann hast Du 2 Abläufe, die Du entsprechend implementieren musst, wenn ich das richtig verstanden habe:
    Konvertiere { 12 Monate zu Jahr },
    Archiviere { Jahr }.
    Das müssten wir etwas präziser spezifizieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja der Spaltenheader ist identisch sowohl bei Monaten als auch bei Jahren. Ich hatte es vorher mit einem Batch gemacht.
    (dabei kenne ich mich leider auch nicht aus und gebe einfach mal die Referenz hier her dostips.com/forum/viewtopic.php?f=3&t=7723&p=51324#p51324).
    Den Batch muss ich halt jedesmal neu kopieren wenn ein Jahr hinzukommt. Ansonsten klappt das aber auch ganz gut. Wenn es aber mit VB besser und schneller geht, bevorzuge ich diese Alternative.
    Jetzt habe ich aber festgestellt, dass ich das Jahr so nicht mehr switchen kann (habe ich da bereits etwas falsch eingestell?) bzw. ich muss erst in den datetimepicker reinklicken (Jahr anwählen). Kann ich
    das auch direkt fokussieren? ?(
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class z_csvbatch
    2. Private Sub z_csvbatch_Load(sender As Object, e As EventArgs) Handles Me.Load
    3. With dtp_year
    4. .Format = DateTimePickerFormat.Custom
    5. .CustomFormat = "yyyy"
    6. .ShowUpDown = True
    7. .ShowCheckBox = True
    8. End With
    9. With cb_data
    10. .Items.Add("Position")
    11. .Items.Add("Kopf")
    12. End With
    13. End Sub
    14. Private Sub b_exit_Click(sender As Object, e As EventArgs) Handles b_exit.Click
    15. Application.Exit()
    16. End Sub
    17. Private Sub b_run_Click(sender As Object, e As EventArgs) Handles b_run.Click
    18. Dim Jahr As String = dtp_year.Text
    19. Dim Data As String = cb_data.Text
    20. Dim Text1 As String = "Year " & Jahr & " " & Data & " executed."
    21. Dim Text2 As String = "All " & Data & " executed."
    22. Dim bat_year As String = "Y:\statistik\" & Data & "\" & Jahr & "\run.cmd"
    23. Dim bat_all As String = "Y:\statistik\" & Data & "\AllYears\run.cmd"
    24. If dtp_year.Checked = True Then
    25. Process.Start(bat_year)
    26. MsgBox(Text1)
    27. ElseIf dtp_year.Checked = False Then
    28. Process.Start(bat_all)
    29. MsgBox(Text2)
    30. End If
    31. End Sub
    32. End Class



    Spoiler anzeigen

    @echo off
    setlocal DisableDelayedExpansion

    ECHO Set working directory
    pushd "%~dp0"

    ECHO Set Y2017 file
    set "Y2017=Y:\statistik\Kopf\AllYears\Y2017.out"

    REM Get header from first file and count files
    set "n=0"
    set "header="
    for %%i in (*.csv) do (
    if not defined header for /f "usebackq tokens=* delims=" %%j in ("%%i") do if not defined header set "header=%%j"
    set /A n+=1
    )

    (
    echo %header%

    set "i=0"
    for %%i in (*.csv) do (

    set /A i+=1
    for /f %%j in ('set /a i') do echo Processing file %%j/%n%: "%%i" > CON

    < "%%i" (

    REM skip the headers
    more +1

    )

    )
    ) > "%Y2017%"

    for %%f in ("%Y2017%") do move /Y "%%f" "%%~DPNf.csv"

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Sam85“ ()

    Sam85 schrieb:

    Kann ich das auch direkt fokussieren?
    Klar.
    Ändere die Tab-Reihenfolge Deiner Controls (Ansicht - Aktivierreihenfolge), da musst Du als erstes Dein Ziel-Control anklicken,
    oder
    Du schreibst in die Form_Shown:

    VB.NET-Quellcode

    1. Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    2. Button2.Focus()
    3. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Sam85 schrieb:

    Da ich die Daten aber in Monaten erhalte und sie dann erst in ein Jahr umwandeln will und dann die Jahre wiederum auch zusammenfassen will,
    war das meine Grundidee. Oder gibt es eine bessere Alternative?
    Im Grunde siehe Post#3.
    Prinzipiell ists heikel, wenn man redundante Daten erzeugt.
    Also wenn du Monats-Dateien zu Jahres-Dateien zusammenfasst, solltest du sicherstellen, dass anschließend nur noch die Jahres-Dateien genutzt werden.
    Und wenn du JahresDateien zu Jahrhundert-Dateien zusammenfasst, solltest du sicherstellen, dass anschließend nur noch die Jahrhundert-Dateien genutzt werden.
    Du merkst: nicht unproblematisch.
    Daher Rods Hinweis: Lass die Dateien wie sie sind, lege sie allenfalls in ein durchdachtes Ordner-System ab, und strick evtl. lieber dein Proggi so, dass es aus den vielen Dateien einen gewünschten Zeitbereich eben einlesen kann - sei es aus einer Datei oder auch aus 20 Dateien.
    Also dass nicht die Dateien selbst zusammengeführt werden, sondern nur die daraus ausgelesenen Daten.

    Vlt erklärst du auch nochmal genauer, um was es ganz konkret geht.
    Evtl. ist nämlich auch eine Db angesagt, weil eine Db kann auch sehr sehr viele Datensätze aufnehmen, wo csv-Dateien zu groß und unhandlich werden würden.
    Und zur Auswertung bestimmter Zeitbereiche hat man da nochmal ganz annere Möglichkeiten.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ahhh ok...also im Grunde ist es wie gesagt, ich habe mehrere Dateien, die am Ende ein Ganzes werden sollen, zumindest für das Auswerten. Derzeit nutze ich dafür PowerBI. Die Daten werden monatlich ausgelesen, bedürfen aber hin und wieder, in den Datensätzen, manueller Korrektur.

    Ist es also machbar, die Dateien so zu verbinden, dass sie in einer DB ein ganzes ergeben, ohne sie als solches zusammenzufasssen? (Man merkt ich bin neu, sollte dass nichts spektakuläres sein :D).

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Sam85“ ()

    Im Allgemeinen kannst du schon mehrere Dateien auslesen und in einer DataTable zusammen setzen. Du arbeitest dann danach nicht mehr in/mit den Dateien, sondern mit den Kopien der Daten aus den Dateien. Was du dann damit machst ist ja mal grundsätzlich wurscht. Du kannst das ganze auch in eine DB speichern.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Sam85 schrieb:

    Ist es also machbar, die Dateien so zu verbinden, dass sie in einer DB ein ganzes ergeben, ohne sie als solches zusammenzufasssen?
    Das tolle an einer Db wäre, darin wären alle Datensätze zusammengefasst, also ein Ganzes.
    Gleichzeitig bietet DB dir aber auch die Möglichkeit, beliebige Ausschnitte wieder herauszuholen, ob nun monatsweise, Jahresweise, Jahrzehnte, oder auch einzelne, und auch noch ganz annere Filter sind denkbar - also was immer du wolle.
    Die Dateien kannste dann löschen, nachdem du sie in die Db eingelesen hast.

    Also alles ganz wunnebar, nur 1 Haken: Du musst lernen, wie's geht, und das ist nicht ganz einfach.
    Was hingegen einfach ist, ist es falsch zu machen, also du findest ungeheuer viel Material zu Datenbänkerei im INet, und wohl 90% davon ist nicht Stand der Technik, und behindert sogar, dir den Stand der Technik anzueignen.
    Mit Stand der Technik meine ich die Themen "typisiertes Datenmodell" und "databinding-getriebene Oberfläche".
    Beide Begriffe sind dir womöglich vollkommen neu, aber das ändert nix dran, dass das der notwendige Lernstoff ist, um eine Software von einigermassen Qualität zu erstellen.

    Und dieser Lernstoff wird dir nicht nur im aktuellen Projekt unerhört nützlich sein, sondern man darf sagen: für dein ganzes weiteres Programmierer-Dasein, in wohl jedem Projekt, was über 300 Zeilen hinausgeht.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Gibt es gute, bzw. zu empfehlende Lektüre zu den Themen databinding-getriebene Oberfläche oder typisiertes Datenmodell?

    Das hört sich ziemlich gut..zwar wollte ich erstmal nur auswerten aber das große Ganze ist sicher wichtig zu verstehen und noch besser wenn man es selber programmieren kann. :)
    vier Views-Videos Das bietet imo einen ziemlichen Rundum-Schlag dessen, was man mit dieser Technologie insgesamt alles so treiben kann.
    Aber geht natürlich weit hinaus über das, was du eiglich brauchst - du brauchst ja nur eine einzige Tabelle (die dann aber enorm viele Datensätze enthalten wird)
    Also für diesen deinen "Simpel-Fall" speziell habich kein Tut.

    Ich täte dir empfehlen, ühaupt mal DatasetOnly so weit dir anzulernen, dass du eine typisierte DataTable im Dataset anlegen kannst, dass du eine solche - noch ohne DB - befüllen und Abspeichern kannst, dass du ein Datagridview daran anbinden kannst, sodass ein User Datensätze eingeben, ändern, löschen kann.
    Siehe dazu Daten laden, speichern, verarbeiten - einfachste Variante

    Nächster Schritt wäre, eine ebenso strukturierte Db aufzubauen, und die Befüllung deines Datasets von der vorherigen DatasetOnly-Befüllung umzustellen auf Befüllung aus der DB. Die Befüllung sollte mit DataAdaptern erfolgen - diese können nicht nur befüllen, sondern rückspeichern auch vorgenommene Änderungen.
    Bis hierher arbeitest du noch nur mit paar Test-Datensätzen, und lädtst immer den kompletten Datenbestand.

    Nächster Schritt wären Import-Funktionen, welche deine csv-Dateien einlesen, daraus ordentliche Datensätze bilden, die in die Db geschrieben werden.
    Ab hier arbeitet deine Anwendung mit tausenden von Datensätzen.

    Nächster Schritt wäre, die Befüllung zu differenzieren, dass du - wie oben angepriesen - beliebige Zeit-Abschnitte angeben kannst, die du angucken und bearbeiten willst. Diese Differenzierung betrifft nur die Befüllung - das Rückspeichern der Änderungen kann unverändert bestehen bleiben.

    Wie gesagt: Ist viel zu lernen, aber dann hast du eine solide Basis, auf der du recht gewaltig was aufbauen kannst, wie zB iwelche Analyse-Tools, mit denen man noch ganz annere Auswertungen vornehmen kann, als nur bestimmte Zeit-Abschnitte anzuzeigen.