CSV-Textdatei: Zeile entfernen

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Robert
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 36
Registriert: Mo, 13. Feb 2006 12:47

CSV-Textdatei: Zeile entfernen

Beitrag von Robert »

Hallo,

ich habe eine CSV-Datei und möchte die erste Zeile (also bis zur Endemarkierung) entfernen, sodass die zweite Zeiler zur ersten wird usw.

Der einzige Weg, der mir dazu einfällt, wäre über eine temporäre Datei, in welcher ich Zeile für Zeile, mit Ausßnahme der ersten, die Werte übernehme.

Gibt es da noch eine elegantere / einfachere Lösung? Gut wäre ja, wenn man, wie in einem Texteditor, die gewünschte Zeile markieren kann und dann ENTF drückt.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

also du hast eine Text Datei und willst die erste Zeile weg haben ?

1. Was spricht gegen den Texteditor ?

2. Erstellst du die Datei selbst und willst, dass die erste leere Zeile nicht entsteht, dann nutze ?? statt ? bei der Erstellung der ersten Zeile oder besser baue den String komplett selbst:

Code: Alles auswählen

cTXT := ""
cTXT += "Feld1,Feld2,Feld3"+chr(13)+chr(10) // 1. Zeile mit Feldnamen
...
cTXT += cFeld1+","+cFeld2+","+cFeld3+chr(13)+chr(10) // Feldinhalte
...
memowrite(cFile,cTxt)
3. Per Programm könnte man die Datei auch einlesen und entfernen lassen:

Code: Alles auswählen

cTXT := memoread("CSV-Text.txt")
cTXT := ltrim(cTXT) // alle Blanks vorne entfernen
if left(cTXT,2) = chr(13)+chr(10) // Zeilenschaltung vorhanden ?
   cTXT := substr(cTXT,3)
endif
memowrit("CSV-Text.txt",cTXT)
allerdings setzt memowrit() ein chr(26) Dateiende Zeichen.
Wenn das stört muss man mit low level Dateifunktionen nehmen.
Ich meine in der Wissensbasis mal Str2Disk() veröffentlicht zu haben, die das besser macht.
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Robert,
ich nehme mal an, es geht Dir darum, die Daten zu importieren und die erste Zeile enthält die Spaltenbeschriftungen.
Dann öffne die csv-Datei doch einfach per USE (vorher die entsprechende DBE einstellen) und mache ein SKIP - damit bist Du auf dem zweiten Satz und somit auf dem ersten "echten".

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Robert
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 36
Registriert: Mo, 13. Feb 2006 12:47

Beitrag von Robert »

Hallo,

danke euch erstmal für die schnelle Antwort.

Jede Zeile hat den selben Aufbau, u.a. bestehend aus der Aktion (z.B. ob ein Datensatz erstellt werden soll) gefolgt vom abwechselnden Auftreten FELD1,WERT1,FELD2,WERT2,...

Diese Daten sollen dann in die entsprechenden Felder der Datenbank eingetragen werden.

Meine Überlegung war jetzt, dass es beim Zugriff auf die Datenbank Probleme geben kann, wenn ein Datensatz nicht geschrieben werden konnte, oder durch Stromausfall plötzlich schluss mit dem einlesen ist.

Aus diesem Grund wollte ich bereits geschriebene Daten aus der Datei entfernen, damit sie beim erneuten Einlesen nicht doppelt vorhanden sind.

Ich werde das mit dem memoread/memowrite respektive Str2Disk in Betreacht ziehen.


Mir kam gerade noch eine andere Idee:

Ich könnte auch am Anfang jeder Zeile ein Zeichen mit T bzw. F vorsehen, welches markiert, ob die Zeile bereits erfolgreich verarbeitet wurde. Da die Position ja konstant ist, kann man ein F ja einfach mit T überschreiben, wenn alles geklappt hat und diese Zeilen dann beim einlesen überspringen.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Robert,

die gelesenen Zeilen in der Datei zu entfernen oder zu markieren ist ein erheblicher Zeitaufwand und nicht wirklich sicher. Ich lese hier TXT Dateien mit Millionen von Zeilen in wenigen Minuten ein. Die Gefahr dass gerade dann ein Stromausfall stattfindet ist nicht groß.
Bei allenen Änderungen der Einlesedatei würde sich aber ein Schreibfehler fatal auswirken.

Ich würde eher einen Zwischenschritt einlegen etwa

1. Ziel-DBF sperren und Kopie erstellen.
2. Daten aus TXT Datei einlesen
3. Nach erfolgreichem Einlesen ZIEL-DBF gegen Kopie austausche.

oder

Einlesen in eine DBF Steuerdatei, die ein Feld erledigt (1 Zeichen oder Datum etc.) enthält und von dort dann den kontrollierten Ablauf starten.
Ab 1000 Zeilen ist übrigens MemoLine() viel zu langsam.

oder

TXT Datei in Array einlesen und Array abarbeiten wobei dann die erledigte Zeile gespeichert wird.
Gruß
Hubert
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hallo Robert,

wie wäre es wenn du auf die Datenbank einen Index setzt und beim Import aus der csv-Datei einen Dbseek machst. Ist vorhanden, so wurde der Satz bereits importiert.
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Antworten