CSV in ListView lesen
CSV in ListView lesen
Moin,
nach langer Zeit muss ich mich doch mal wieder melden
Ich möchte gerne eine CSV Datei in meine ListView lesen und danach in meiner vorhandenen Datenbank speichern. Ich habe 0 Plan wie ich das angehen soll. Es muss ja irgend wie eine for Schleife gebaut werden und sobald in der CSV ein ; kommt muss er i ein hoch rechnen oder?
bei PHP war es mit explode irgend wie leichter
nach langer Zeit muss ich mich doch mal wieder melden
Ich möchte gerne eine CSV Datei in meine ListView lesen und danach in meiner vorhandenen Datenbank speichern. Ich habe 0 Plan wie ich das angehen soll. Es muss ja irgend wie eine for Schleife gebaut werden und sobald in der CSV ein ; kommt muss er i ein hoch rechnen oder?
bei PHP war es mit explode irgend wie leichter
- af0815
- Lazarusforum e. V.
- Beiträge: 6213
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: CSV in ListView lesen
es gibt viel Möglichkeiten das zu machen. Hängt auch von der Qualität des csv ab
CSV Kann man direkt als Datenbank lesen. http://wiki.freepascal.org/CSV
fpSpreadsheet kann es auch lesen http://wiki.freepascal.org/FPSpreadsheet
In ein StringList selbst einlesen und die richtigen Delimiter setzen http://forum.lazarus.freepascal.org/ind ... ic=17345.0
CSV Kann man direkt als Datenbank lesen. http://wiki.freepascal.org/CSV
fpSpreadsheet kann es auch lesen http://wiki.freepascal.org/FPSpreadsheet
In ein StringList selbst einlesen und die richtigen Delimiter setzen http://forum.lazarus.freepascal.org/ind ... ic=17345.0
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: CSV in ListView lesen
Danke für die schnelle Antwort ^^
Mit der Datenbank das habe ich schon mal gemacht. Aber dort habe ich ein DBGrid genommen weil ich damals schon dran gescheitert bin es in einer ListView zu schreiben. Nur dieses mal muss es in eine ListView ^^
Spreadsheet hatte ich mir auch schon angesehen... aber irgend wie zu kompliziert
Ich schaue mir es mal mit der StringList an. Mal schauen wie das wird
Mit der Datenbank das habe ich schon mal gemacht. Aber dort habe ich ein DBGrid genommen weil ich damals schon dran gescheitert bin es in einer ListView zu schreiben. Nur dieses mal muss es in eine ListView ^^
Spreadsheet hatte ich mir auch schon angesehen... aber irgend wie zu kompliziert
Ich schaue mir es mal mit der StringList an. Mal schauen wie das wird
-
- Beiträge: 1911
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: CSV in ListView lesen
Die Subitems property eines ListItems ist ein TStrings, also müsste sowas gehen:
Die letzen zwei zeilen kannst du dir sogar sparen wenn du die erste spalte einfach unsichtbar machst und nur mit dem subitems arbeitest (mache ich gerne um dort zusätzliche Informationen wie Indexe oder so zu speichern).
Das einzige was du noch separat machen musst ist der Header (also die erste zeile)
Code: Alles auswählen
with ListView1.Items.Add do
begin
SubItems.Delimiter := ',';
SubItems.StrictDelimiter := True;
SubItems.DelimitedText := CSVLine;
Caption := SubItems[0];
SubItems.Delete(0);
end;
Die letzen zwei zeilen kannst du dir sogar sparen wenn du die erste spalte einfach unsichtbar machst und nur mit dem subitems arbeitest (mache ich gerne um dort zusätzliche Informationen wie Indexe oder so zu speichern).
Das einzige was du noch separat machen musst ist der Header (also die erste zeile)
Re: CSV in ListView lesen
Im Anhang findest du ein Beispiel, wie eine CSV-Datei (geklaut von https://cerc.blackboard.com/Page/1189) in ein TListView eingelesen werden kann. Es gibt wahrscheinlich so viele Möglichkeiten wie Programmierer...
Da du offenbar neu in Pascal bist, habe ich die Datei zeilenweise mit Hilfe der klassichen Readln-Anweisungen eingelesen. Jede Zeile steht dann immer in einem String s, der mit dessen Helper-Methode .Split(',') an den Komma-Positionen zerhackt wird (das Gegenstück zum php-Explode); die Teile stehen dann in einem String-Array. Wenn man das mit der 1. Zeile macht, die die Überschriften enthält, hat man alle Informationen, um die Spalten der Listview zu erzeugen. Anschließend liest man den Rest der Datei und verteilt die zerhackten Strings vom Array in die Spalten der ListView, wobei zu beachten ist, dass in der 1.Spalte immer die Caption der ListItems steht, und die folgenden Strings in den SubItems.
P.S.
Die Warf-Methode ist gefällt mir besser als mein Beispiel. Aber ich wollte unbedingt das String.Split erwähnen, da im 1. Beitrag das Fehlen von php's explode bedauert wird.
Da du offenbar neu in Pascal bist, habe ich die Datei zeilenweise mit Hilfe der klassichen Readln-Anweisungen eingelesen. Jede Zeile steht dann immer in einem String s, der mit dessen Helper-Methode .Split(',') an den Komma-Positionen zerhackt wird (das Gegenstück zum php-Explode); die Teile stehen dann in einem String-Array. Wenn man das mit der 1. Zeile macht, die die Überschriften enthält, hat man alle Informationen, um die Spalten der Listview zu erzeugen. Anschließend liest man den Rest der Datei und verteilt die zerhackten Strings vom Array in die Spalten der ListView, wobei zu beachten ist, dass in der 1.Spalte immer die Caption der ListItems steht, und die folgenden Strings in den SubItems.
P.S.
Die Warf-Methode ist gefällt mir besser als mein Beispiel. Aber ich wollte unbedingt das String.Split erwähnen, da im 1. Beitrag das Fehlen von php's explode bedauert wird.
- Dateianhänge
-
- csv_to_listview.zip
- (2.89 KiB) 129-mal heruntergeladen
-
- Beiträge: 201
- Registriert: Do 24. Jan 2013, 21:22
Re: CSV in ListView lesen
Hallo wp_xyz
ich muß dir mal ein dickes Lob aussprechen.
Deine Kern-Routine hast Du super dokumentiert , die kann man in 10,15,20 Jahren noch mal rauskramen und weis sofort was Sache ist.
Genau so wünscht man sich jeden Democode .
Gruß
Frank
ich muß dir mal ein dickes Lob aussprechen.
Deine Kern-Routine hast Du super dokumentiert , die kann man in 10,15,20 Jahren noch mal rauskramen und weis sofort was Sache ist.
Code: Alles auswählen
procedure TForm1.ReadCSVToListView(AFileName: String);
var
F: TextFile;
s: String;
sa: TStringArray;
listitem: TListItem;
i: Integer;
begin
// Neuzeichnen der ListView beim Hinzufügen von neuen Einträgen unterbinden.
// Das würde alles sehr verlangsamen (natürlich nur bei großen Dateien).
ListView1.Items.BeginUpdate;
AssignFile(F, FILE_NAME);
Reset(F);
// TListView hat Spalten nur im Viewstyle vsReport
ListView1.ViewStyle := vsReport;
// Feldnamen einlesen - die stehen in der 1. Zeile
// - Zeile einlesen
ReadLn(F, s);
// - In die einzelnen felder, die durch Komma getrennt sind, aufspalten
sa := s.Split(',');
// - Für jedes Feld eine Spalte erzeugen
for i:=0 to High(sa) do
with ListView1.Columns.Add do begin
Caption := sa[i];
Width := 150;
end;
// Nun den Rest der Datei einlesen
while not EoF(F) do begin
// - Aktuelle Zeile einlesen
ReadLn(F, s);
// - In die einzelnen Felder aufspalten
sa := s.Split(',');
// - ListItem für diesen Record erzeugen
listitem := ListView1.Items.Add;
// - Das 1.feld geht in die Caption des ListItem
listitem.Caption := sa[0];
// - Alle folgenden Felder gehen in die SubItems des ListItem
// Achtung: Nummerierung beginnt hier bei 1, weil 0 ja schon verwendet wurde!
for i := 1 to High(sa) do
listitem.SubItems.Add(sa[i]);
end;
// Neuzeichnen der Listview wieder aktivieren und anstoßen.
ListView1.Items.EndUpdate;
end;
Genau so wünscht man sich jeden Democode .
Gruß
Frank
www.flz-vortex.de
-
- Beiträge: 1911
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: CSV in ListView lesen
Noch ein kleiner tipp, Pack das Begin-End Update in ein Try-Finally:
Sonst bekommst du eventuell in der Funktion einen Fehler (z.B. Datei lässt sich nicht öffnen) und durch die Exception wird EndUpdate nicht aufgerufen, was dazu führt das dein ListView sich nicht mehr aktualisieren kann. Macht also das gesammte Control nutzlos
Code: Alles auswählen
ListView1.Items.BeginUpdate;
try
...
finally
ListView1.Items.EndUpdate;
end;
Sonst bekommst du eventuell in der Funktion einen Fehler (z.B. Datei lässt sich nicht öffnen) und durch die Exception wird EndUpdate nicht aufgerufen, was dazu führt das dein ListView sich nicht mehr aktualisieren kann. Macht also das gesammte Control nutzlos
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: CSV in ListView lesen
Code: Alles auswählen
for i := 1 to High(sa) do
listitem.SubItems.Add(sa[i]);
end;
Was passiert, wenn in den Zeilen mehr Zellen vorhanden sind als im Header? Werden dann Zellinhalte in nicht vorhandene Subitems geschrieben?
Kann ja vorkommen, dass eine CSV fehlerhaft ist.
-
- Beiträge: 1911
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: CSV in ListView lesen
Timm Thaler hat geschrieben:Was passiert, wenn in den Zeilen mehr Zellen vorhanden sind als im Header? Werden dann Zellinhalte in nicht vorhandene Subitems geschrieben?
Kann ja vorkommen, dass eine CSV fehlerhaft ist.
Gibt es weniger Subitems als Colums werden die restlichen Colums leer gefüllt, ich denke mal wenn es mehr gibt wird alles was übersteht einfach ignoriert/nicht gezeichnet (habs aber nicht getestet und hängt natürlich auch vom WS ab)
Re: CSV in ListView lesen
Danke erst mal.
Leider funktioniert es bei mir noch nicht so wie es soll. Meine ListView soll im Caption bereich nicht beschrieben werden. Dazu soll es nur die erste Spalte beschrieben werden und als Split habe ich "
Problem macht mir eigentlich nur die erste Spalte. Eigentlich verstehe ich die For-Schleife so das er dafür sorgt ein nach unten zu gehen. Aber er geht wohl immer nach rechts.
Zur meiner Listview. Die hat ca 17 Spalten aber nur die erste soll beschrieben werden.
oder liegt es an der csv Datei? Die sieht ca. so aus
Text Art; Wort Wort, Schrift, Text"
Text Art; Wort Wort, Schrift, Text"
Text Art; Wort Wort, Schrift, Text"
und so soll es in einer Spalte auch untereinander stehen
Leider funktioniert es bei mir noch nicht so wie es soll. Meine ListView soll im Caption bereich nicht beschrieben werden. Dazu soll es nur die erste Spalte beschrieben werden und als Split habe ich "
Problem macht mir eigentlich nur die erste Spalte. Eigentlich verstehe ich die For-Schleife so das er dafür sorgt ein nach unten zu gehen. Aber er geht wohl immer nach rechts.
Zur meiner Listview. Die hat ca 17 Spalten aber nur die erste soll beschrieben werden.
oder liegt es an der csv Datei? Die sieht ca. so aus
Text Art; Wort Wort, Schrift, Text"
Text Art; Wort Wort, Schrift, Text"
Text Art; Wort Wort, Schrift, Text"
und so soll es in einer Spalte auch untereinander stehen
-
- Beiträge: 1911
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: CSV in ListView lesen
Aphadias hat geschrieben:Danke erst mal.
Leider funktioniert es bei mir noch nicht so wie es soll. Meine ListView soll im Caption bereich nicht beschrieben werden. Dazu soll es nur die erste Spalte beschrieben werden und als Split habe ich "
Problem macht mir eigentlich nur die erste Spalte. Eigentlich verstehe ich die For-Schleife so das er dafür sorgt ein nach unten zu gehen. Aber er geht wohl immer nach rechts.
Zur meiner Listview. Die hat ca 17 Spalten aber nur die erste soll beschrieben werden.
oder liegt es an der csv Datei? Die sieht ca. so aus
Text Art; Wort Wort, Schrift, Text"
Text Art; Wort Wort, Schrift, Text"
Text Art; Wort Wort, Schrift, Text"
und so soll es in einer Spalte auch untereinander stehen
Dafür ist CSV nicht gedacht. Ist es immer einzeilig oder gibt es auch einträge die Mehrzeilig sein können.
Wenn es immer Einzeilig ist, vergiss die " und lies es einfach in eine TStringList ein und Iteriere dann über die Zeilen. Wenn es Mehrzeilig sein kann, kannst du entweder um es effizient zu gestalten einen Parser bauen oder einfach den ganzen Text spliten (und dann trim auf den einzelnen Elementen um die am anfang newlines wegzubekommen) und dann durchzuiterieren. Das braucht dann aber zwei Durchläufe (split muss einmal den gesamten Inhalt durchsuchen und du am ende musst jeden eintrag in den Listview einbauen).
Beispiel für das zweite:
Code: Alles auswählen
var sl: TStringList;
s: string;
begin
sl:=TStringList.Create;
try
sl.LoadFromFile('csvFile');
sl.Delimiter = '"';
sl.StrictDelimiter := True;
sl.DelimitedText := sl.Text;
ListView1.BeginUpdate;
try
for s in sl do
with ListView1.Items.Add do
SubItems.Add(s.Trim);
finally
ListView1.EndUpdate;
end;
finally
sl.Free;
end;
end;
Re: CSV in ListView lesen
Aphadias hat geschrieben:Zur meiner Listview. Die hat ca 17 Spalten aber nur die erste soll beschrieben werden.
Jetzt hast du mich komplett abgehängt: Wieso 17 Spalten, wenn du nur die erste beschreiben willst? Willst du jede Zeile der CSV-Datei unzerlegt komplett in der 1.Spalte anzeigen? Und du willst die Captions nicht beschreiben. Sollen die leer bleiben? Warum nimmst du dann überhaupt den vsReport Style der Listview und nicht vsList? Oder stehen da schon andere Informationen?
Bitte mache eine vernünftige Beschreibung deines Problems, vielleicht eine Skizze dazu. So verstehe ich nur Bahnhof.
- af0815
- Lazarusforum e. V.
- Beiträge: 6213
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: CSV in ListView lesen
Aphadias hat geschrieben:oder liegt es an der csv Datei? Die sieht ca. so aus
Text Art; Wort Wort, Schrift, Text"
Text Art; Wort Wort, Schrift, Text"
Text Art; Wort Wort, Schrift, Text"
Das ist keine CSV, das ist kunterbunter Müll. Und genauso wie beim Müll, den muss man von Hand aus zerlegen, damit man ihn recyclen kann.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: CSV in ListView lesen
wp_xyz hat geschrieben:Aphadias hat geschrieben:Zur meiner Listview. Die hat ca 17 Spalten aber nur die erste soll beschrieben werden.
Jetzt hast du mich komplett abgehängt: Wieso 17 Spalten, wenn du nur die erste beschreiben willst? Willst du jede Zeile der CSV-Datei unzerlegt komplett in der 1.Spalte anzeigen? Und du willst die Captions nicht beschreiben. Sollen die leer bleiben? Warum nimmst du dann überhaupt den vsReport Style der Listview und nicht vsList? Oder stehen da schon andere Informationen?
Bitte mache eine vernünftige Beschreibung deines Problems, vielleicht eine Skizze dazu. So verstehe ich nur Bahnhof.
Ich versuche es mal bildlich zu erklären. Die ListView ist dazu da um Materialien in eine Datenbank zu speichern bzw auszulesen. Diese Materialien haben Chargen Abläufe Nummer usw... Sprich in der 1. Spalte kommt das Material 2. Spalte wieviel davon da sein soll 3. Wie viel da ist 4. Charge usw usw usw.. Die CSV Liste soll nur die Materialien enthalten. Sozusagen möchte ich das beim 1. Start der Nutzer die Materialien alle einlesen kann (aus der CSV-Liste) und danach zu jedem Material die Charge Datum usw einschreiben kann (weil es bei jedem Unterschiedlich ist). Deswegen soll nur die 1. Spalte aufgelistet werden weil der Name des Materials bei jedem gleich ist aber alle anderen Daten immer anders sind. Also eine Vorabmaske zur Arbeitserleichterung.
Die Captions sind schon bei der Erstellung der ListView vorgegeben und brauchen deswegen nicht beschrieben werden. Dort stehen die Reiter drin wie eben erwähnt.....
ist die Erklärung jetzt etwas einsichtiger?
Re: CSV in ListView lesen
Ja, so ist es klar.
Studiere mal das beigefügte Demo. Vielleicht kannst du darauf aufbauen.
Studiere mal das beigefügte Demo. Vielleicht kannst du darauf aufbauen.
- Dateianhänge
-
- forum_listview.zip
- (2.27 KiB) 119-mal heruntergeladen