AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

CSV-Datei in Stringgrid bringen

Ein Thema von peschai · begonnen am 4. Jun 2009 · letzter Beitrag vom 11. Nov 2009
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#1

CSV-Datei in Stringgrid bringen

  Alt 4. Jun 2009, 06:38
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
Peter Schaible
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#2

Re: CSV-Datei in Stringgrid bringen

  Alt 4. Jun 2009, 06:52
Hallo,

Das hier könnte funktionieren. Ich habe es nicht getestet, aber laut Code könnte es klappen.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.858 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: CSV-Datei in Stringgrid bringen

  Alt 4. Jun 2009, 08:59
Hallo peschai,

könntest Du die besagte CSV-Datei mal als Anhang dranhängen?

Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#4

Re: CSV-Datei in Stringgrid bringen

  Alt 4. Jun 2009, 09:50
[OT]
hieß so etwas nicht mal ASCII delimited?
und das mit dem "Comma" ist ja auch so eine Sache
[/OT]
Gruß
K-H
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: CSV-Datei in Stringgrid bringen

  Alt 4. Jun 2009, 09:56
[OT]
Zitat von p80286:
[OT]
hieß so etwas nicht mal ASCII delimited?
und das mit dem "Comma" ist ja auch so eine Sache
[/OT]
Gruß
K-H
CSV = Comma Separated Values; da im englischen sprachraum ein Komma statt dem Semikolon verwendet wird
[/OT]
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#6

Re: CSV-Datei in Stringgrid bringen

  Alt 26. Okt 2009, 22:31
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...
Peter Schaible
  Mit Zitat antworten Zitat
Benutzerbild von Lannes
Lannes

Registriert seit: 30. Jan 2005
Ort: Münster
745 Beiträge
 
Delphi 3 Professional
 
#7

Re: CSV-Datei in Stringgrid bringen

  Alt 26. Okt 2009, 23:23
Hallo,

Zitat von peschai:
Das ist im RFC für die CSV aussdrücklich berückssichtigt, also möglich. Excel kann das.
das halte ich aber für ein Gerücht Excel kann sie ausgeben aber nicht richtig einlesen(bei neueren Excel-Versionen > 2000 kA).

Nur die Quotes zu überprüfen reicht nicht:
Code:
Hallo;1;"dad
sdfsfaf";"aa"""
Hallo;1;"dad
sdfsfaf""";aa
Wieviel Zeilen sind das?
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#8

Re: CSV-Datei in Stringgrid bringen

  Alt 27. Okt 2009, 07:25
Zitat von peschai:
Der Trick ist, ...
sich Post #2 zu Herzen zu nehmen, kurz drüberschauen und einfach auskodieren;
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;
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#9

Re: CSV-Datei in Stringgrid bringen

  Alt 27. Okt 2009, 13:09
@Lannes
Zitat von Lannes:
Hallo,

Zitat von peschai:
Das ist im RFC für die CSV aussdrücklich berückssichtigt, also möglich. Excel kann das.
das halte ich aber für ein Gerücht :roll: Excel kann sie ausgeben aber nicht richtig einlesen(bei neueren Excel-Versionen > 2000 kA).

Nur die Quotes zu überprüfen reicht nicht:
Code:
Hallo;1;"dad
sdfsfaf";"aa"""
Hallo;1;"dad
sdfsfaf""";aa
Wieviel Zeilen sind das?
zwei

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.
  Mit Zitat antworten Zitat
Benutzerbild von peschai
peschai

Registriert seit: 15. Feb 2004
Ort: Göppingen
270 Beiträge
 
Delphi XE5 Professional
 
#10

Re: CSV-Datei in Stringgrid bringen

  Alt 6. Nov 2009, 05:32
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:
dad#13#10sdfsfaf
Die 3.Zelle der 2.Zeile hat also den Inhalt
Zitat:
dad#13#10sdfsfaf"
Das lässt sich sehr effizient in einer normalen Stringlist ohne Fremdkomponente realisieren

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 ? ...
Peter Schaible
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz