Autor |
Beitrag |
Hänsel
      
Beiträge: 144
|
Verfasst: Sa 08.05.21 14:01
Hallo, habe folgendes Problem:
meine bisherige Einlesung einer csv-Datei ging soweit i.o. Diese sah wie folgt aus:
Quelltext 1: 2:
| SND_NR;EFE;84112595;29h;HCA;Response,Uplink,TPL=S,M-Bus;126;00h;5;19.03.2021 09:04 invalid 0 summer time 0;1289;31.12.20;842;31.12.19;213;91;77;72;55;48;86;30;0;1;1;0;0;0;0;1;0;0;0;0;1;8;58;54;46;73;97;147;57;53;0;00.00.2000 00:00 invalid 0 summer time 0; |
«File completely written» ohne die letzte Zeile.
Jetzt hat der Lieferant der csv-Datei am Ende dies hinzugefügt: «File completely written»
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| while not EoF(tfDatei) do begin slWerte := TStringList.Create; Readln(tfDatei,sZInhalt); slWerte.StrictDelimiter := true; slWerte.DelimitedText := sZInhalt; slWerte.Delimiter :=';'; slWerte.DelimitedText:=sZInhalt; slWerte.QuoteChar := '"'; slWerte.DelimitedText:=sZInhalt; Inc(iZeile); end; CloseFile(tfDatei); |
Durch die letzte Zeile bekomme ich immer wieder eine Fehlermeldung, da die Einlesung erst mit der letzten Zeile endet.
Was habe ich hier falsch gemacht? Bzw. was habe ich bei der Vorbereitung zur Einlesung vergessen?
War kann hier helfen?
Danke im Voraus
Hänsel
Moderiert von Th69: Code-Tags hinzugefügt
Moderiert von Th69: Delphi-Tags hinzugefügt
Moderiert von Th69: Titel geändert (war "Einlesung einer csv-Datei").
|
|
jaenicke
      
Beiträge: 19172
Erhaltene Danke: 1713
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 08.05.21 14:33
Welche Fehlermeldung kommt denn und an welcher Stelle? In dem geposteten Teil des Quelltext sehe ich auf Anhieb nichts Verdächtiges.
Warum weist du eigentlich DelimitedText mehrfach zu? Das ist doch unnötig und langsam.
Prüfst du denn die Daten bevor du sie verarbeitest? Oder gehst du vielleicht einfach davon aus, dass eine bestimmte Anzahl von Spalten vorhanden ist?
|
|
Hänsel 
      
Beiträge: 144
|
Verfasst: So 09.05.21 08:06
Hallo,
es werden beim Einlesen alle Zeilen geprüft, dies funktioniert auch.
Es geht um die letzte Zeile. Bisher war auch die letzte Zeile ein Datensatz. Jetzt wird die Datei mit:
<<File completely written»
beendet. Von der letzten Zeile kommt auch der Fehler bzw. die Fehlermeldung. (Fehler: .... Listenindex außerhalb des Bereiches.)
D.h. es wird hier noch versucht Daten einzulesen, wo keinen mehr sind.
Hänsel
|
|
icho2099
      
Beiträge: 101
Erhaltene Danke: 12
WIN XP, WIN 7, WIN 10
Delphi 6 Prof, Delphi 2005, FPC
|
Verfasst: So 09.05.21 09:46
wenn die letzte Zeile ein bekannter und konstanter String ist, dann prüfe das doch einfach bevor du die Zeile an die Stringliste verfütterst.
|
|
ub60
      
Beiträge: 759
Erhaltene Danke: 121
|
Verfasst: So 09.05.21 12:10
Könntest Du die letzte Zeile nicht einfach so abfangen?
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| if Pos('File completely written', sZInhalt)=0 then begin end else ShowMessage('Ende erreicht'); |
Um Dir ansonsten weiterzuhelfen, wäre eventuell interessant:
- Ist die Zeile 1 die einmalig auftauchende Kopfzeile?
- Ist Zeile 2 eine Datenzeile, die sich (mit anderen Daten mehrfach wiederholt?
- Welche der Daten brauchst Du genau?
Du könntest dann auch mal noch weiteren Quelltext zeigen, so dass man Dir weiterhelfen kann.
Das, was da oben steht, ist nicht sehr sinnvoll bzw. (wie jaenicke schon geschrieben hat) etwas umständlich.
Ich glaube, dass Du mit ein paar mehr Infos auch mehr Hilfe bekommst.
ub60
|
|
jasocul
      
Beiträge: 6385
Erhaltene Danke: 146
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Mo 10.05.21 07:33
Unter der Annahme, dass "echte" Datenzeilen mehr als einen Wert haben, kannst du einfach so vorgehen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| while not EoF(tfDatei) do begin slWerte := TStringList.Create; Readln(tfDatei,sZInhalt); slWerte.StrictDelimiter := true; slWerte.DelimitedText := sZInhalt; slWerte.Delimiter :=';'; slWerte.DelimitedText:=sZInhalt; slWerte.QuoteChar := '"'; slWerte.DelimitedText:=sZInhalt; Inc(iZeile); if slWerte.count > 1 then begin end;
end; CloseFile(tfDatei); |
Eventuell musst du noch deinen Zähler( iZeile) berücksichtigen.
|
|
Blup
      
Beiträge: 171
Erhaltene Danke: 42
|
Verfasst: Mi 12.05.21 10:50
Wenn die Stringliste slWerte erzeugt wird, muss sie natürlich auch wieder freigegeben werden.
Die Eigenschaften für das CSV-Format müssen slWerte nur einmal zugewiesen werden.
Den Inhalt der Zeile aus sZInhalt natürlich auch nur einmal je Zeile.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| iZeile := 0;
slWerte := TStringList.Create; try slWerte.StrictDelimiter := True; slWerte.Delimiter := ';'; slWerte.QuoteChar := '"';
while not EoF(tfDatei) do begin Readln(tfDatei, sZInhalt); Inc(iZeile); if sZInhalt = '«File completely written»' then begin Break; end else begin slWerte.DelimitedText := sZInhalt; end; end; finally slWerte.Free; end;
CloseFile(tfDatei); |
Moderiert von Th69: Delphi-Tags hinzugefügt
|
|
jaenicke
      
Beiträge: 19172
Erhaltene Danke: 1713
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 12.05.21 14:27
Blup hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5:
| if sZInhalt = '«File completely written»' then begin Break; end | |
Das löst das Problem zwar für den konkreten Fall, aber sobald wieder eine Änderung passiert, z.B. wenn dieser Text verändert wird oder eine weitere zusätzliche Zeile hinzu kommt, gibt es wieder ein Problem.
Deshalb ist es sinnvoller das eigentliche Problem auch zu lösen: jaenicke hat folgendes geschrieben : | Prüfst du denn die Daten bevor du sie verarbeitest? Oder gehst du vielleicht einfach davon aus, dass eine bestimmte Anzahl von Spalten vorhanden ist? |
Wie jasocul schon vorgeschlagen hat, sollte schlicht geprüft werden wie viele Spalten eine Zeile hat. Wenn die Anzahl nicht stimmt, ob nun nur eine oder nur 5 statt 6 usw., kann das dann behandelt werden. Natürlich kann man zusätzlich auf den Text prüfen, um diesen bekannten Fall direkt zu behandeln. Aber man sollte beim Import von Daten nie davon ausgehen, dass das Format korrekt ist. Wenn man Fehler gleich richtig behandelt (loggen, melden, ...), findet man das Problem im Fall der Fälle am einfachsten und produziert keine Folgefehler.
|
|
|