![]() |
CSV-Datei in Stringgrid bringen
Hallo Delphianer,
CSV-Datei in Stringgrid bringen mit Feldern welche auch einen Zeilenwechsel beinhalten Es gibt viele Lösungsansätze im Internet oder hier um das zu tun, aber überall fehlt mir ein Wichtigkeit, welche ich entweder in den Lösungen übersehen habe oder ...? Es geht um Feldinhalte mit Zeilenumbrüche. Also nicht der Zeileumbruch am Ende einer CSVZeile, sondern um mögliche Zeileumbrüche innerhalb eines Feldes. Das ist im RFC für die CSV aussdrücklich berückssichtigt, also möglich. Excel kann das. Fast alle berücksichtigen nur die Sonderverarbeitung von Delimiter, Quote aber vernachlässigen mögliche Zeilumbrüche in Feldern selbst. Wie mache ich das aber elegent in Delphi ? Wie bringe ich folgende CSV-Datei in ein Stringgrid (4Spalten,7Zeilen, 2Zellen mit Zeileumbruch)? Hinweis: Daß ich im Stringgrid den Zeilewechsel nicht sehe ist nicht relevant. Inhalt der Test.csv: SpalteA;SpalteB;"SpalteC";"SpalteD" 1A;1B;1C;1D "2A";2B;"2C";"2D" ;;; 4A;"4BMitUmbruch 4BVonNeuerZeile";"4CMitSeparatorUndQuote;""";4D 5A;5B;5C;"5DMitUmbruchInLetzerSpalte 5DVonNächsterZeile" 6A;6B;6C;6D |
Re: CSV-Datei in Stringgrid bringen
|
Re: CSV-Datei in Stringgrid bringen
Hallo peschai,
könntest Du die besagte CSV-Datei mal als Anhang dranhängen? Bis bald Chemiker |
Re: CSV-Datei in Stringgrid bringen
[OT]
hieß so etwas nicht mal ASCII delimited? und das mit dem "Comma" ist ja auch so eine Sache [/OT] Gruß K-H |
Re: CSV-Datei in Stringgrid bringen
[OT]
Zitat:
[/OT] |
Re: CSV-Datei in Stringgrid bringen
Hallo Delphianer,
zuersteinmal Danke für die Antworten und dann eine Entschuldigung für das späte reagieren nun... ... aber dafür beantworte ich meine Frage nun selbst und villeicht hilft es ja jemand anders. Frage war: Wie kann ich eine CSV-Datei mit Zeilenumbrüchen innerhalb von Zellen richtig einladen ? Lösung wie folgt: Der Trick ist, daß bei einer CSVZeile mit einem Zeilenumbruch innerhalb einer Zelle die Anzahl der Quotes ungerade ist. Nachdem ich diese Einfachheit erkannt hatte, war die Lösung einfach: CSV Datei in Stringgrid einladen und dann Zeilenweise durchgehen. Addiere die nächste Zeile solange die Anzahl der Quotes ungerade ist. Ciao... |
Re: CSV-Datei in Stringgrid bringen
Hallo,
Zitat:
Nur die Quotes zu überprüfen reicht nicht:
Code:
Wieviel Zeilen sind das?
Hallo;1;"dad
sdfsfaf";"aa""" Hallo;1;"dad sdfsfaf""";aa |
Re: CSV-Datei in Stringgrid bringen
Zitat:
Delphi-Quellcode:
Uses csCSV, Math; // Math nur wegen 'Max'
var csvReader: TCSVReader; data: TStringStream; sl: TStringList; i, r: Integer; begin StringGrid1.RowCount := 1; StringGrid1.ColCount := 1; sl := TStringlist.Create; // Für das Beispiel try // Füllen mit Test-CSV sl.Add('SpalteA;SpalteB;"SpalteC";"SpalteD"'); sl.Add('1A;1B;1C;1D'); sl.Add('"2A";2B;"2C";"2D"'); sl.Add(';;;'); sl.Add('4A;"4BMitUmbruch'); sl.Add('4BVonNeuerZeile";"4CMitSeparatorUndQuote;""";4D'); sl.Add('5A;5B;5C;"5DMitUmbruchInLetzerSpalte'); sl.Add('5DVonNächsterZeile"'); sl.Add('6A;6B;6C;6D'); data := TStringStream.Create(sl.Text); // der TCSVReader erwartet einen InputStream csvReader := TCSVReader.Create(data); try csvReader.Delimiter := ';'; csvReader.Quote := '"'; csvReader.EOLChar := #13; // In unserer 'Datei' werden die Zeilen durch #13#10 getrennt csvReader.EOLLength := 2; // #13 trennt also, aber die EOL-Länge ist 2 csvReader.First; while not csvReader.Eof do begin // Die CSV-Zeilen können unterschiedlich viele Spalten beinhalten StringGrid1.ColCount := Max(stringGrid1.ColCount, csvReader.ColumnCount + 1); // Eine Hilfsvariable (nicht Refactoring-konform, aber etwas lesbarer) r := StringGrid1.RowCount - 1; // Spaltenbezeichnung '1','2' usw. gilt aber nicht für die Überschrift if r > 0 then StringGrid1.Cells[0, r] := IntToStr(r); // Einlesen der Spalten for I := 0 to csvReader.ColumnCount - 1 do StringGrid1.Cells[i + 1, r] := csvReader.Columns[i]; // Nächste CSV-Zeile einlesen csvReader.Next; // Nur, wenn wir noch nocht am Ende sind, eine Zeile hinzuzählen if not csvReader.Eof then StringGrid1.RowCount := StringGrid1.RowCount + 1; end; // Zum Schluss wieder eine Zeile abziehen (komisches Verhalten des StringGrid) StringGrid1.RowCount := StringGrid1.RowCount - 1; finally csvReader.Free; data.Free; end; finally sl.free; end; end; |
Re: CSV-Datei in Stringgrid bringen
@Lannes
Zitat:
Allgemeingültig ist dieses "Anzahl der Quotes ungerade" wohl nicht, aber vielleicht reicht es peschai ja so. Richtig wäre es auf jeden Fall mit "IstInQuote" zu arbeiten, damit dann auch gleich das/die Trennzeichen richtig verarbeitet Wird/werden. Gruß K-H Ach ja mein Excel (2003) kann CSV, wenn ich ihm sage was was ist. Die Automatik ist meist nicht dazu in der Lage. |
Re: CSV-Datei in Stringgrid bringen
Hallo Leute,
doch es ist wirklich so einfach und allgemeingültig und keineswegs eine Einschränkung Die Überprüfung einer Zeile auf ungerade Anzahl der Quotes ist die Beantwortung der Frage "IstInQuote". Trennzeichen innerhalb Quotes sind durch die Quotes neutralisiert und spielen damit keine Rolle Quotes selber innerhalb Text werden verdoppelt, damit sind sie gerade und spielen ebenfalls keine Rolle. Nehmen wir das Beispiel und stellen wir uns vor, daß ein in eine StringList geladen wurde. Hallo;1;"dad sdfsfaf";"aa""" Hallo;1;"dad sdfsfaf""";aa 1.) Nimm erste QuellZeile -> Hallo;1;"dad 2.) Zähle Quotes -> 1 ungerade 3.) da ungerade MUSS Zeilenumbruch in letzter "QuellZeilenzelle" vorliegen, also nächste Zeile dazunehmen -> Hallo;1;"dad#13#10sdfsfaf";"aa""" 4.) Zähle Quotes -> 6 gerade 5.) da gerade ist also erste Ziel-CSVZeile komplett eingelesen. Nächste QuellZeile nehmen -> Hallo;1;"dad 6.) Zähle Quotes -> 1 ungerade 7.) da ungerade MUSS Zeilenumbruch in letzter "QuellZeilenzelle" vorliegen, also nächste Zeile dazunehmen -> Hallo;1;"dad#13#10sdfsfaf""";aa 8.) Ergebnis also zwei echte Zeilen Hallo;1;"dad#13#10sdfsfaf";"aa""" Hallo;1;"dad#13#10sdfsfaf""";aa Die 3.Zelle der 1.Zeile hat also den Inhalt Zitat:
Zitat:
Das Beispiel mit dem TCSVReader verwendet im Prinzip eine ähnlichen Ansatz indem er schaut ob pro Zeile die Spaltenanzahl stimmt. Wenn nicht, dann nimm nächste Zeile dazu ... -> aber es könnte sein, daß der Ansatz über die TStringlist effizienter ist ? ... :roll: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz