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;