Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   CSV-Reader. Schnelles lesen von CSV-Dateien (https://www.delphipraxis.net/110025-csv-reader-schnelles-lesen-von-csv-dateien.html)

alzaimar 11. Mär 2008 19:56


CSV-Reader. Schnelles lesen von CSV-Dateien
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

Ich habe mal eine Klasse geschrieben, die CSV-Dateien einliest und die einzelnen Elemente extrahiert. Dabei werden auch in '"' eingeschlossenen Strings korrekt erkannt.

Verwendet wird es so:
Delphi-Quellcode:
Var
  csvReader : TCSVReader;
  sData : TFileStream;

Begin
  sData := TFileStream.Create('Sample.CSV',fmOpenRead);
  csvReader := TCSVReader.Create (sData, ';');
  csvReader.First; // Nach Änderung auf Veranlassung von Grenzgaenger nun notwendig. Dank an 'deadcandance'
  Try
    While not csvReader.Eof Do Begin                                          
      For i:=0 to csvReader.ColumnCount - 1 Do                                
        Memo.Lines.Add (csvReader.Columns[i]);                                
      csvReader.Next;                                                        
    End;    
  Finally
    csvReader.Free;
    sData.Free;
  End;
End;
Es ist ziemlich flott. Vielleicht kann Jemand etwas damit anfangen.

Bugreports und Verbesserungsvorschläge sind natürlich erwünscht.

Bug: Grenzgaenger hat mich auf einen Fehler in der Behandlung von '""' aufmerksam gemacht. Weiterhin wünschte er sich den Quote-Character als Eigenschaft. Bitte sehr.
Erweiterung: ralfschwalbe hätte gern, das die Klasse auch mit UNIX-Umbrüchen umgehen kann. Bitte sehr.
Erweiterung: Noch besser: Man kann nun das EOL-Zeichen und die Länge selbst angeben (z.B. für Unix #10 und 1, Windows: #13 und 2)
Änderung: Laut grenzgaenger hat der Aufruf von 'First' im Konstruktor nix zu suchen. Recht hat er!
Bug: Kater Karlo hat einen Fehler im Konstruktor entdeckt, der bei Streams auftritt, deren Position>0 ist. Weiterhin ist ein überflüssiges privates Feld entfernt worden.

ralfschwalbe 12. Mär 2008 06:39

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hi,

super Sache!

Aber ein Hinweis aus eigener Erfahrung: Du solltest unbedingt noch bedenken, dass es auch csv-Dateien mit UNIX Zeilenumbrüchen gibt!

Nicht das irgendwann mal was "schiefgeht"!

alzaimar 12. Mär 2008 08:55

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hi ralf,

UNIX-Zeilenumbrüche sind nur ein CR, richtig? Das sollte kein Problem sein. Neue Version oben

marabu 12. Mär 2008 09:18

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hi alzaimar,

nimm LF - ist besser so.

Freundliche Grüße

alzaimar 12. Mär 2008 09:25

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo Marabu. Na gut, dann muss ich ja nochmal nachdenken :freak:

grenzgaenger 12. Mär 2008 23:20

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
hallo alzheimer,

vielleicht solltest du von den optionen her MAC, Unix und DOS unterstützen ... die trennzeichen sind wie folgt #13, #10, #13#10... und für kümimüsis #10#13 ;-), welche es eben verwechseln ... :-)

grüsse
GG

Tyrael Y. 13. Mär 2008 08:11

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Ein CSV Feldtrennzeichen kann ',' oder ';' sein.
Verarbeitest du beides oder nur eins von beiden?

U.u. wäre es dann gut als property das Trennzeichen mit angeben zu können.

Union 13. Mär 2008 09:15

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Schau Dir mal den constructor an:
Delphi-Quellcode:
Constructor TCSVReader.Create(aStream: TStream; aDelimiter: Char);
Zitat:

Ein CSV Feldtrennzeichen kann ',' oder ';' sein.
Stimmt eigentlich nicht. CSV-Trennzeichen ist NUR das Komma, (Comma Separated Values), alles andere hat man aus Praktikabilität erfunden. Ursprünglich war das Format nur für Zahlenkolonnen gedacht. Da die Amis nur den Punkt als Dezimaltrennzeichen verwenden, hat man dann eben das Komma als Delimiter benutzt.

alzaimar 13. Mär 2008 09:27

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Zitat:

Zitat von Union
Zitat:

Ein CSV Feldtrennzeichen kann ',' oder ';' sein.
Stimmt eigentlich nicht.

Doch. Das Trennzeichen ist der 'ListSeparator'. Und der ist in anglikanischen Ländern das Komma, bei uns das ';'. Und wenn Du pervers bist, dann kannst Du auch ein '@' nehmen. Einfach in den internationalen Einstellungen der Systemsteuerung setzen. Also macht das schon Sinn, das Trennzeichen vogeben zu können.

Union 13. Mär 2008 09:31

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Naja, vielleicht machen das manche Programme so mit dem ListSeparator. Aber die ganze Geschichte steht hier. Sehr interessant übrigens, dass erst 2005 versucht wird, dieses Uralt-Format zu standardisieren.

alzaimar 13. Mär 2008 09:33

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Zitat:

Zitat von Union
Naja, vielleicht machen das manche Programme so mit dem ListSeparator.

EXCEL macht das so... Aber echt interessant (auch der Wiki-Artikel). Ich dachte, CSV hätte sich MS 1923 ausgedacht. So lange kenn ich das jedenfalls (ungefähr, mein Gedächtnis :gruebel: )

Union 13. Mär 2008 09:40

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Jedenfalls ist Deine Lösung gut und praktikabel. Eigentlich geht es ja nicht um die Therorie, sondern dass man es für bestehende "CSV"-Definitionen verwenden kann. Ich bin auch erst vor kurzem darauf gekommen, als ich zum Debuggen eine "CSV" mit Semikolon ausgegeben habe und der Microsoft LogParser das Format nicht erkannte. Die nennen das dann TSV mit Delimiter =";".

alzaimar 13. Mär 2008 09:45

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Zitat:

Zitat von Union
Jedenfalls ist Deine Lösung gut und praktikabel.

:dancer:
Zitat:

Zitat von Union
Die nennen das dann TSV mit Delimiter =";".

:wall:

Union 13. Mär 2008 10:26

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Und wenn Du noch
Delphi-Quellcode:
SetString(Result, spFirst, spLen);
ersetzt mit
Delphi-Quellcode:
SetLength(result, spLen);
Move(spFirst^, result[1], spLen);
dann wird das auch schnell;)

deadcantdance 12. Dez 2008 14:02

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Kleiner Hinweis. Das o.g. Bespiel funktioniert so nicht ganz.

Beim ersten Durchlauf ist ColumnCount = 0, erst nach dem Aufruf von csvReader.Next wird ColumnCount gesetzt.

Sollte doch dann eigentlich so sein:

Delphi-Quellcode:
Try
  if not csvReader.Eof then
    csvReader.Next;
  While not csvReader.Eof Do Begin                                          
    For i:=0 to csvReader.ColumnCount - 1 Do                                
      Memo.Lines.Add (csvReader.Columns[i]);                                
    csvReader.Next;                                                        
  End;    
Finally
  csvReader.Free;
  sData.Free;
End;
Ansonsten, :thumb:

Viele Grüße,
deadcantdance

alzaimar 14. Dez 2008 19:50

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
In der kleinen Demo fehlt der Aufruf von 'csvReader.First'. Habe ich nachgetragen (siehe Eingangspost).

Kater Karlo 7. Jan 2009 11:29

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
:coder2:
Hi,

ggf. ist es sinnvoll im Constructor vor dem Read die Position des zu lesenden Stream auf Null zu setzen.
Es sei denn es ist beabsichtigt erst ab der aktuellen Stelle einzulesen.

Die Variable fReader: TReader; kann weggelassen werden.

Gruss Kater Karlo

alzaimar 7. Jan 2009 11:54

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo Kater Karlo,

Es ist üblich, das der Aufrufer den Stream an die geeignete Stelle setzt, das muss er bei Verwendung anderer Komponenten (z.B. Crypter/Packer-Streams) auch selbst machen. Bei Instantiierung eines TFileStreams ist die Position eh bei 0.

Bezüglich deines Einwands mit dem Buffer fällt auf, das im Konstruktor ein kleine Ungenauigkeit auftritt, wenn die Position des Streams > 0 ist (wie du richtig bemerkt hast). Das sollte nun behoben sein.

Danke für die Anregungen

Kater Karlo 7. Jan 2009 13:46

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo alzaimar,

ich hätte da noch einige Anregungen:

- Als Eigenschaft den Index der aktuellen Zeile
- Als Eigenschaft die aktuelle Zeile als String
- Veröffentlichen der Column-Information TStringPos

Extended:
- Erkennen von Kommentarzeilen (Zeile beginnt mit # oder über eine Eigenschaft bekannt zugebene Zeichenfolge)

MfG

Kater Karlo

ekoplayer 22. Feb 2009 20:04

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Kann mir einer vielleicht sagen wie ich beide die Datei zum laufen kriege?

Wenn ich sie abspeichern will sagt er mir immer Declaration of class TForm1 is missing or incorrect.

Und bei der zweiten Datei hinterlegt er das

Delphi-Quellcode:
 
csvReader : TCSVReader;
sData : TFileStream;
rot wenn ich es Compilieren will. kann mir wer helfen?

alzaimar 22. Feb 2009 20:38

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Du müsstest die Unit noch einbinden ...

ekoplayer 23. Feb 2009 05:57

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
also ich speicher die Datei csCSV.pas ab und dann erstelle ich ne neue Unit? und unter welchen Namen speicher ich die dann ab bzw. was muss ich daran noc ändern?

alzaimar 23. Feb 2009 06:21

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Dir scheinen die Grundlagen der Programmierung mit Delphi/Pascal/ObjectPascal zu fehlen. Vielleicht wäre ein Crashkurs Delphi etwas für Dich. Danach kannst Du dir die Frage selbst beantworten. So würde das nichts werden.

Du kannst Dir auch die Beispiele anschauen, die bei Delphi dabei sind. Dort werden auch Units verwendet ("verwenden" englisch: 'to use' :zwinker: )

Der_Ventilator 7. Aug 2009 08:42

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Woran könnte es liegen, wenn ich statt des Inhalts der CSV nur rechteckige Kästchen einlesen kann?

Sowas (mit den Editor geöffnet)
Zitat:

132.187.93.175;255.255.255.0;448;8;0;0;005_MT_Schu l;;cache://global/deploy.shtml "HMZ_005_MT_Schul_2-1.ini";
wird im Memo nur als Kästchen angezeigt, hier im Forum mit japanischen Schriftzeichen.

Zitat:

灩摡牤渻瑥慭歳活摯汥漻瑰潩獮瀻數潭敤氻捯潫瑵朻潲灵愻瑵摨浯楡㭮瑳牡灴条㭥敲潳畬楴湯瀻慬晴牯㭭楦敬敳癲 牥昻汩獥牥敶扲歡爻浥瑯捥湯潳敬昻汩獥牥敶灲牯㭴敲潭整潣獮汯灥牯㭴敳楲污画極㭤睨摡牤猻慴畴㭳潭敤㭬慃档 卥穩㭥汃慥䍲捡敨湏散䌻牵敲瑮瑓瑡੥㌱⸲㠱⸷㌹ㄮ㔷㈻㔵㈮㔵㈮㔵〮㐻㠴㠻〻〻〻㔰䵟彔捓畨㭬挻捡敨⼺术潬慢 ⽬敤汰祯献瑨汭∠䵈彚〰張呍卟档汵㉟ㄭ椮楮㬢㈱〸ㅸ㈰㬴䅉㡸㬶⸰⸰⸰㬰⸰⸰⸰㬰⸰⸰⸰㬰㈭㈱㌳〻夻䍋こ㄰㐲 㬵䈰㘷䄷䔴㑁ㄴㄱ䍄㕂䘵〰㤱㤹㈰㐹㜶〻㄰㤹〹㤲㘴㬷协䈠住ⱔ传⁎䥄䭓䔻偓䥒位䌠㜵〲ㄻ〵〰昻污敳主坅䠠协੔ ㌱⸲㠱⸷㌹ㄮ㘷㈻㔵㈮㔵㈮㔵〮㐻㠴㠻〻〻〻㔰䵟彔捓畨㭬挻捡敨⼺术潬慢⽬敤汰祯献瑨汭∠䵈彚〰張呍卟档汵㉟ ㄭ椮楮㬢㈱〸ㅸ㈰㬴䅉㡸㬶⸰⸰⸰㬰⸰⸰⸰㬰⸰⸰⸰㬰㈭㈱㌳〻夻䍋こ㄰㐲㬲䕂䅂ㄴ䔹㑁㘴ㄱ䍄䘹
Verwendet mit BDS 2009

Das CSV wurde mit einem Webinterface erstellt und gespeicht, leider bekomme ich auch nur Kästchen, wenn ich mit Notepad eine test.csv erstelle und selbst mit Daten fülle.

franktron 7. Aug 2009 09:34

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Zitat:

Zitat von Der_Ventilator
Woran könnte es liegen, wenn ich statt des Inhalts der CSV nur rechteckige Kästchen einlesen kann?

Sowas (mit den Editor geöffnet)
Zitat:

132.187.93.175;255.255.255.0;448;8;0;0;005_MT_Schu l;;cache://global/deploy.shtml "HMZ_005_MT_Schul_2-1.ini";
wird im Memo nur als Kästchen angezeigt, hier im Forum mit japanischen Schriftzeichen.

Zitat:

灩摡牤渻瑥慭歳活摯汥漻瑰潩獮瀻數潭敤氻捯潫瑵朻潲灵愻瑵摨浯楡㭮瑳牡灴条㭥敲潳畬楴湯瀻慬晴牯㭭楦敬敳癲 牥昻汩獥牥敶扲歡爻浥瑯捥湯潳敬昻汩獥牥敶灲牯㭴敲潭整潣獮汯灥牯㭴敳楲污画極㭤睨摡牤猻慴畴㭳潭敤㭬慃档 卥穩㭥汃慥䍲捡敨湏散䌻牵敲瑮瑓瑡੥㌱⸲㠱⸷㌹ㄮ㔷㈻㔵㈮㔵㈮㔵〮㐻㠴㠻〻〻〻㔰䵟彔捓畨㭬挻捡敨⼺术潬慢 ⽬敤汰祯献瑨汭∠䵈彚〰張呍卟档汵㉟ㄭ椮楮㬢㈱〸ㅸ㈰㬴䅉㡸㬶⸰⸰⸰㬰⸰⸰⸰㬰⸰⸰⸰㬰㈭㈱㌳〻夻䍋こ㄰㐲 㬵䈰㘷䄷䔴㑁ㄴㄱ䍄㕂䘵〰㤱㤹㈰㐹㜶〻㄰㤹〹㤲㘴㬷协䈠住ⱔ传⁎䥄䭓䔻偓䥒位䌠㜵〲ㄻ〵〰昻污敳主坅䠠协੔ ㌱⸲㠱⸷㌹ㄮ㘷㈻㔵㈮㔵㈮㔵〮㐻㠴㠻〻〻〻㔰䵟彔捓畨㭬挻捡敨⼺术潬慢⽬敤汰祯献瑨汭∠䵈彚〰張呍卟档汵㉟ ㄭ椮楮㬢㈱〸ㅸ㈰㬴䅉㡸㬶⸰⸰⸰㬰⸰⸰⸰㬰⸰⸰⸰㬰㈭㈱㌳〻夻䍋こ㄰㐲㬲䕂䅂ㄴ䔹㑁㘴ㄱ䍄䘹
Verwendet mit BDS 2009

Das CSV wurde mit einem Webinterface erstellt und gespeicht, leider bekomme ich auch nur Kästchen, wenn ich mit Notepad eine test.csv erstelle und selbst mit Daten fülle.

Das Zauberwort Heist Unicode :wink:

Der_Ventilator 7. Aug 2009 11:17

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Heist das, der normale Windowseditor speichert unter Windows XP im Unicodeformat, mit dem ein Memo nix anfangen kann?

franktron 7. Aug 2009 12:07

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Zitat:

Zitat von Der_Ventilator
Heist das, der normale Windowseditor speichert unter Windows XP im Unicodeformat, mit dem ein Memo nix anfangen kann?

Neine D2009 scheint das aber zu meinen und liest es im Unicodeformat ein und dann kommt soein mist dabei raus

BoolString 7. Aug 2009 21:05

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Sehr cool! Ich muss viel mit CSV Dateien arbeiten (wobei wir die inzwischen als Char-Separated-Values betiteln ;-) Ich hab inzwischen viele Routinen geschrieben, die immer leichte Varianten und Abweichungen prozessieren.

Was du vielleicht noch überarbeiten soltest wären:
- Property ab welcher Zeile die eigentlichen CSV Daten anfangen (häufig gibt es einen Header, der komplett anders aufgebaut ist und davor steht).
- eine Comment Property, die alle Zeilen enthält, die nicht als Daten eingelesen werden sollen (z.B. die Zeilen des Headers).
- Property für die Anzahl der Elemente pro Zeile (manchmal verrutschen Werte, wenn Messwerte nicht vorliegen, was zu Problemen führt, wenn man alles in eine Tabelle oder für weitere Berechnungen in eine Matrix schreibt).
- Für manche Anwendungen ist es interessant, bei der internen Verarbeitung die Delimiter am Anfang einer Zeile zu löschen.
- Für andere Anwendungen ist es interessant, mehrere aufeinanderfolgende Delimiter wie einen einzigen zu interpretieren.
- eine Möglichkeit eine Zeile anzugeben, welche Spaltenüberschriften trägt (diese sind häufig anders zu prozessieren als die darauffolgenden Daten); quasi die Column Headers.
- evtl. tatsächlich eine Option zur Unicode-Behandlung.


Bin ja echt gerade am Überlegen, ob ich meine Routinen nicht endlich mal auf eine schicke Klasse umschreiben sollte (man bastelt ja immer so seine Provisorien und die halten dann ewig). Dein Ansatz würde sich mit einigen Anpassungen sehr schön eignen!

Liebe Grüße aus ><)))°> Town

Jan

alzaimar 8. Aug 2009 07:21

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo Jan,

Ich halte deine Vorschläge für nicht unbedingt sinnvoll, denn sie lassen sich bereits durch die vorhandenen Eigenschaften implementieren bzw. gehören imho nicht in die Klasse:
Du kannst zum Überspringen der ersten Zeilen die 'Next' Methode ein paar mal aufrufen. Weiterhin gibt dir die Eigenschaft 'ColumnCount' für jede Zeile die Anzahl der Zellen/Spalten zurück.
Die Prozessierung bzw. Behandlung des Inhaltes (=Interpretation) obliegt nicht der CSV-Klasse, sondern der benutzenden Anwendung. Die Darstellung als Matrix bzw. Dataset müsste diese Funktionalitäten bereitstellen: Hier geht es nur um das schnelle und korrekte Einlesen von Daten im CSV-Format.

Einzig die Unicode-Behandlung wäre eine Option. Wobei es dann sinnvoller wäre, eine neue Klasse dafür zu implementieren. So wie ich das sehe, müssten die String/Var/PChar-Variablendeklarationen durch ihre Unicode-Pendants ersetzt und an der Stelle 'GetMem' die Anzahl mit 2 multipliziert werden.

BoolString 9. Aug 2009 22:35

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Ich habe mir deinen Code mal etwas genauer angesehen. Mit einigen Punkten hast du recht. Das lag wohl an meiner ersten, eher oberflächlichen, Inspektion :oops: Die Interpretation war natürlich nicht Teil meines Vorschlags. Das habe ich wohl etwas Missverständlich ausgedrückt. Ist klar, daß sich jede Anwendung die Daten dann in ihr eigenes Datenhandlingkonstrukt stopfen muss.

Bezüglich der 'Lösche Delimiter am Anfang' und 'Mehrere aufeinanderfolgende als einen Delimiter interpretieren' ermöglicht es gleichzeitig Datenfiles mit fester Spaltenbreite zu importieren. Hier werden ja die ungenutzten Zeichen meist mit Leerzeichen aufgefüllt. Durch die angesprochenen Properties könnte man die dann mit verarbeiten (Deli:=SPACE; LöscheAnfangsDelis:=True; MuliDeliAsOne:=True).
Ist aber nur ein Vorschlag; letztlich hast du natürlich recht, daß dies nicht CSV Dateien im eigentlichen Sinn sind. Es wäre aber eine Option diese gleich mit zu 'erschlagen' und sicherlich eine Aufwertung deines Codes. Ist ja aber nur ein Vorschlag; du hast ja danach gefragt ;-)

Liebe Grüße

Jan

alzaimar 10. Aug 2009 07:38

Re: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo Jan,
Das von Dir beschriebene Datenformat (konstante Spaltenbreite) sind nicht nur keine CSV-Datei "im eigentlichen Sinne", sondern überhaupt nicht.

Um Daten mit konstanter Spaltenbreite zu importieren, sollte sich ein anderer Reader implementieren lassen, der dies wesentlich eleganter und vor allem performanter lösen kann: Er benötigt ja nur die Spaltenbreite, den linken Abstand sowie optional ein Füllzeichen. So ein Reader funktioniert intern völlig anders als ein CSV-Reader, wieso sollte man also einen CSV-Reader dafür 'aufwerten' (ich würde das eher 'verwässern' nennen)? Eine Klasse sollte genau einem Zweck dienen (hier: Lesen von CSV-Dateien).

Zudem sollte man Klassen auch nicht mit Eigenschaften ausstatten, deren Funktionalität sich mit wenigen Aufrufen der Elementaroperationen selbst nachbilden lässt:

Nur leere Zellen am Anfang der Zeile ignorieren:
Delphi-Quellcode:
Var
  bAtBeginningOfLine : Boolean;
  iRealColumn : Integer;
  sCellData : String;
...
csvReader.First;
While not csvReader.Eof Do Begin                                          
  bAtBeginningOfLine := True;
  iRealColumn := 0;
  For i := 0 to csvReader.ColumnCount - 1 Do Begin
    sCellData := csvReader.Columns[i];
    If bAtBeginningOfLine And (sCellData = '') Then Continue;
    bAtBeginningOfLine := False;
    inc (iRealColumn); // Die 'Spaltennummer' ohne leere Zellen am Anfang
    Memo.Lines.Add (sCellData);
  End;
  csvReader.Next;                                                        
End;
Leere Zellen ignorieren:
Delphi-Quellcode:
Var
  iRealColumn : Integer;
  sCellData : String;

...
csvReader.First;
While not csvReader.Eof Do Begin                                          
  iRealColumn := 0;
  For i := 0 to csvReader.ColumnCount - 1 Do Begin
    sCellData := csvReader.Columns[i];
    If sCellData = '' Then Continue;
    inc (iRealColumn); // Die 'Spaltennummer'
    Memo.Lines.Add (sCellData);
  End;
  csvReader.Next;                                                        
End;
Die OOP-konforme Vorgehensweise hier (für Dich) wäre so:
1. Definieren einer abstrakten Basisklasse ("TableReader"), die die elementaren Operationen zum Lesen von Daten aus Dateien bereitstellt (First, ColumnCount, Next, Eof, Columns).
2. Umschreiben der Klasse CSV-Reader als Nachfolger des "TableReader".
3. Implementieren der Klasse "Constant-Column Reader" als Nachfolger des "TableReader".

Du kannst nun auch weitere 'TableReader' implementieren, z.B. die eine SYLK-Datei einlesen, oder direkt mit BIFF arbeiten, oder XML, JSON etc. Der Vorteil ist, das Du diverse schlanke, wartbare und performante Klassen hast, die ohne Probleme erweiterbar und optimierbar sind. Bei einer eierlegenden Wollmilchsauklasse ("God Class") ist dies nicht der Fall.

Gruß zurück.

Triple Crown 7. Sep 2011 13:25

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo!

Vielen Dank für die Unit!!!

Hat bei mir mit
WIN 7 /Lazarus 0.9.30/ FPC 2.4.2
geklappt.

Gruß!
Andreas

Monday 29. Aug 2012 12:49

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hi,

funktioniert super! Danke! Selbst große Datenmenge packt der Reader in kürzester Zeit!

LG

divBy0 17. Jan 2013 13:49

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Hallo,
ich stehe gerade auf dem Schlauch. Die CSV-Datei ist ANSI-kodiert und wird unter XE2 als asiatischer Schriftzeichensalat gelesen.
Hab die Datei schon mit TEncoding nach Unicode, UTF8 und UTF16 konvertiert, bringt mich aber alles nicht weiter.

Kann mich mal bitte jemand in die richtige Richtung schubsen?

p80286 17. Jan 2013 14:57

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Ich hab die Sourcen gerade nicht zur Hand, aber das hört sich an als ob eine Unterscheidung String/Ansistring fällig wäre.

Gruß
K-H

roadrunner-S51 3. Jul 2014 10:05

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Sorry das ich das alte Thema nochmal ausgrabe, aber ich habe das selbe Problem mit den Unicodeformat und hätte gern gewusst, ob mittlerweile eine Lösung existiert...

Dejan Vu 3. Jul 2014 11:19

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Na ja. Der Code geht davon aus, das ein Char genau ein Byte lang ist. Das muss man nur umschreiben/anpassen.

roadrunner-S51 3. Jul 2014 11:40

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
OK, aber genau da steh ich gerade etwas auf dem Schlauch... Hat da jemand vielleicht ein Beispiel oder ähnliches für mich?

Sherlock 3. Jul 2014 12:33

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Eigentlich geht der Code von PChar als einzelnem Zeichen aus. Unter den Delphis ab...ähm...2009? ist das nunmal PWideChar und nicht PAnsiChar. Eventuell sollte die "Bytigkeit" von Zeichen als weiterer Parameter hinzugefügt werden (was den Code nicht wirklich verschlanken würde). Wenn man aber seinen Anwendungsfall genau kennt, dürfte ein explizites Ersetzen sämtlicher PChar durch PAnsiChar die ursprüngliche ANSI-Funktionalität gewährleisten.

Sherlock
(für den dieses "Problem" nur wieder zeigt wie unsinnig es ist einem "Standard"-Typen von Version zu Version andere Basistypen zu verpassen)

Dejan Vu 3. Jul 2014 12:44

AW: CSV-Reader. Schnelles lesen von CSV-Dateien
 
Grob gesehen, fast alle '1' mit 'OneChar' und alle '2' mit 'TwoChar' ersetzen, wobei die beiden Symbole entweder Konstanten sind, die über die Compilerversion mit 1/2 oder 2/4 vorbelegt werden, oder eben als Properties.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:47 Uhr.
Seite 1 von 2  1 2      

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