![]() |
Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Guten Tag,
in meinem Programm, möchte ich aus einer CSV-Datei (mit 2 Spalten) nur die Werte aus der 2.Spalte speichern und verarbeiten. Beispiel wäre aus allen Zahlen der 2.Spalte die höchste zu bestimmen. Hat jemand dafür einen Ansatz bzw. Lösung? Vielen Dank!!! |
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Hallo,
du musst die Datei komplett lesen und die Spalte extrahieren. Ich nehme dafür immer 2 TStringList, eine für die Datei und eine zum Trennen der jeweiligen Zeile (Delimimter, DelimtedText) |
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Hallo,
eine weitere Möglichkeit wäre ein ClientDataSet. Damit kannst über CDS.Fields[x].AsString(?) direkt die "Spalte" ansprechen. Ein ClientDataSet bietet auch die Möglichkeit eine csv-Datei direkt zu laden (LoadFromFile()). Allerdings weiß ich grad nicht ob das Delphi-eigene ClientDataSet sowas auch bietet, da ich nur mit dem DevExpress-MemDataSet arbeite. Ich vermute aber schon. Die Einarbeitung in ein ClientDataSet ist ein wenig höher, bietet aber auf Sicht IMHO besseres Handling/ Programmierbarkeit. |
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Am "Einfachsten" wäre es, eine fertige Lösung für CSV zu verwenden ... alles einzulesen zu lassen und dann nur die zweite Spalte zu nehmen stellt ja kein Problem dar. (außer vielleicht die Datei ist viel zu groß für den Arbeitsspeicher)
Dazu würde z.B. das ClientDataSet zählen oder irgendeine CSV-Komponente. Ja, zwei TStringList für Zeilen und Spalten sind eine gängige einfache Lösung für Sowas (die SuFu hilft), oder ganz modern TFile.ReadAllLines und String.Split mit einer For-In-Schleife, für alle die neuere Klassen/Funktionen verwenden und etwas über Enumeratoren und RecordHelper lernen wollen. :stupid: Zitat:
|
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Danke an alle für die Antworten!
|
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Wäre es bei einer so einfachen Ausgangssituation nicht am einfachsten und schnellsten, die Datei einzulesen, #9 anzuspringen, Wert auslesen, #13#10 anzuspringen und so weiter?
|
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Am Schnellsten vielleicht. (wobei #9 natürlich auch , oder ; oder sonstwas sein kann .. drum nennen es Manche auch DSV statt CSV oder sagen einfach "character" statt "comma")
Mit "am Einfachstes" endet es schon, wenn die Zeilen nicht mit #13#10 enden, sondern eventuell auch mit #10 oder #13. |
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Ich wusste, sowas würde kommen...:thumb:
Ich gehe einfach mal davon aus, dass a) die Dateien vielleicht sogar von ihm selbst stammen b) CSV-Dateien praktisch immer #9 und #13#10 haben und c) er notfalls nachschaut. |
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Drum auch TStringList ... die macht das Trennen der Zeilen (#10, #13 oder #13#10), aber es geht auch ReadLn oder eben z.B. ein PosEx(#13#10).
Und dann nochmal eine weitere TStringList.DelimitedText für das Trennen am "Komma", wofür man auch jede beliebige andere SplitString-Funktion nehmen kann, So man muß sich um fast nichts kümmern und ist alles schon von Haus aus im Delphi vorhanden. :zwinker: ReadAllLines erzeugt ein TArray<string> mit allen Zeilen (wie die erste StringList) Bei diesem Code muß man aber aufpassen, den wenn in irgendeiner Zeile nicht 2 Spalten, also mindestens 1 Delimiter vorkommt, dann knallt es, wenn man so ungeprüft auf das Array zugreift. :oops:
Delphi-Quellcode:
Man könnte das ganze Problem sogar mit einem RegEx lösen, also irgendwie so
for var Values in TFile.ReadAllLines('C:\irgendwo\file.csv') do
MacheWasMitDerZweitenSpalte(Values.Split([#9])[1]);
Delphi-Quellcode:
for var Match in TRegEx.Matches(TFile.ReadAllText('C:\file.csv'), '^[^\t]*\t([^\t]*)', [roMultiLine]) do
DoWithSecondValue(Match.Groups[1]); // Match.Value |
AW: Nur eine Spalte aus CSV-Datei auslesen und verarbeiten
Meine Lösung:
Eine von TStringList abgeleitete Komponente (z,B,.: TStringList_Ex); Uberschreibe
Code:
Wobei cSep dein Separator (hier #09 ist)
function Add(const S: string): Integer;
var sp: Szring; begin Result := GetCount; sp := Part(S, <cSep>, 2); Insert(Result, sp); end;
Code:
Falls NextChar fehlt:
function Part(const sVar: String; const cSep: Char; UV: Integer): String;
var P, S : PChar; i, j : Integer; begin P := Pointer(sVar); S := P; i := 1; j := UV; Inc(j); If P <> nil then begin While (P^ <> #0) do begin If P^ = cSep then begin INC(i); If i = UV then S := P; If i = j then break; end; P := NextChar(P); end; If UV > 1 then INC(s); If (i >= UV) and (UV > 0) then System.SetString(Result, S, P - S) else Result := ''; end; end;
Code:
Wobei, wenn Du nur den größten Wert ermitteln willst, nimm nur daraus die Proceduren:
function NextChar(P: PChar): PChar;
begin Result := P; if (Result <> nil) and (Result^ <> #0) then begin Inc(Result); {$IFDEF UNICODE} if Result^.IsLowSurrogate then Inc(Result); while Result^.GetUnicodeCategory = TUnicodeCategory.ucNonSpacingMark do Inc(Result); {$ENDIF} end; end;
Code:
procedure TStrings.LoadFromFile(const FileName: string);
Code:
und fuer Add
procedure TStrings.LoadFromStream(Stream: TStream; Encoding: TEncoding);
Code:
function Add(const S: string): Integer;
var sp: String; i: Integer begin sp := Part(S, <cSep>, 2); FMax := Max(FMax, StrToIntDef(sP, - MaxInt)); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:51 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-2025 by Thomas Breitkreuz