CSV Dateien mit CR+LF innerhalb einer Zeile

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

Moderator: Moderatoren

Antworten
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

CSV Dateien mit CR+LF innerhalb einer Zeile

Beitrag von Koverhage »

Es gibt ja viele Lösungen eine Text oder CSV Datei einzulesen, aber bei allen habe
ich folgendes Problem:
Innerhalb einer Zeile gibt es Textfelder die manchmal ein CR+LF enthalten.
Der Vorschlag von Jimmy dies über Excel zu machen ist toll, scheitert aber daran
das manche kein Excel haben.
Mit Memoline, etc. bekomme ich nur Schrott.
Wie zu erkennen macht Excel das richtig, wie macht Excel das ?
Zählt Excel die Trennzeichen ?

Über Tipps würde ich mich freuen.
Dateianhänge
Musterzeile Excel
Musterzeile Excel
2015-04-29_115047.jpg (10.06 KiB) 4795 mal betrachtet
Gruß
Klaus
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: CSV Dateien mit CR+LF innerhalb einer Zeile

Beitrag von Tom »

Ich würde vermuten, dass der fragliche Text in Anführungszeichen steht. Oder dass er zwischen den Trennzeichen (Semikola) eindeutig ist. Das wird enden, wenn jemand auf die Idee gekommen ist, direkt im Text das Trennzeichen (";") zu verwenden. Auch Excel bekommt das dann nicht mehr hin:

KUNDENNR;INFO;SUMME
10292;Heiliger Habicht [CRLF] auf dem Zaun;1095,50
10293;Grüner Spatz;5,55
10294;Stockente;schönes Exemplar;705,77

"schönes Exemplar" dürfte auch Excel in der Spalte "SUMME" verorten. Wenn der jeweilige "Info"-Text in Anführungszeichen steht, funktioniert (in Excel) alles. Bei mir bricht Excel ohne Leerzeichen in der Zeile für Kundnnr. 10292 um (erzeugt also einen neuen Datensatz), bei Kundennr. 10294 landet "schönes Exemplar" erwartungsgemäß in der Spalte "SUMME".

Du wirst Dir vermutlich einen eigenen Parser bauen müssen. Also Trennzeichen zählen. Und, falls es Elemente wie bei Kundennr. 10294 gibt - und keine Anführungszeichen -, sogar Datentypen ermitteln.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: CSV Dateien mit CR+LF innerhalb einer Zeile

Beitrag von brandelh »

daran bin ich auch schon gescheitert. Schuld ist die schwammige Übersetzung was vorgeht.
Ich hatte das immer so verstanden, dass das Zeilenende zwingend vorgeht, Zeilenschaltungen hätte ich dort nie vermutet.
Tatsache ist aber (wenn man die Anleitung genau liest), dass alles zwischen zwei " " erlaubt ist. Wenn es denn ein " sein soll, dann muss man zwei "" schreiben ...

Wie man das alles noch einigermaßen performant einlesen soll ist mir schleierhaft ... in meinen Programmen habe ich immer CRLF entfernt, oder aber mit einem Platzhalter weitergegeben {CRLF} und diesen auf der anderen Seite wieder ausgepackt. Wobei das Rechteck in der Anzeige für mich nach einem weichen Zeilenumbruch aussieht.
Gruß
Hubert
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: CSV Dateien mit CR+LF innerhalb einer Zeile

Beitrag von Koverhage »

@Hubert,
Wobei das Rechteck in der Anzeige für mich nach einem weichen Zeilenumbruch aussieht.
Kann sein das Excel das ersetzt, in der CSV Datei steht ein CR und ein LF.

@Tom,

ja, der Text und auch CR und LF steht in Anführungszeichen.
Gruß
Klaus
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: CSV Dateien mit CR+LF innerhalb einer Zeile

Beitrag von Tom »

ja, der Text und auch CR und LF steht in Anführungszeichen.
Dann schmeiß es raus. Du kannst mit NumAt(), At() und StrTran() eine Funktion bauen, die CRLF zwischen zwei Anführungszeichen findet und entfernt. Ich bin allerdings so gut wie auf dem Weg nach Boise, so dass ich Dir keinen Code liefern kann.
Herzlich,
Tom
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: CSV Dateien mit CR+LF innerhalb einer Zeile

Beitrag von Koverhage »

Genau das waren meine Gedanken.

Ich lese Datei ja auf einmal ein, FREADSTR, MEMOLINE usw. betrachten die Zeile ja mit dem ersten CR+LF als beendet.

Der einzige Ansatz den ich sehe ist:
1. Datei komplett einlesen (mache ich bereits)
2. Dan mit AT() 1. " und n#chste " suchen
3. Wenn alle CR+LF dazwischen löschen.
Dann ganz normal mit Memoline arbeiten. Dürfte zwar ein wenig länger dauern, aber meines Erachtens der einzige Weg.
Gruß
Klaus
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: CSV Dateien mit CR+LF innerhalb einer Zeile

Beitrag von Koverhage »

Habe das jetzt so gelöst, ist ausreichend schnell, wobei ich die Steuerzeichen durch | ersetze.
Das hat folgenden Vorteil:
Beim Verarbeiten, d.h. den Text in ein Memofeld übertragen, kann ich den Zeilenumbruch wieder einfügen.

Ja man könnte es noch flexibler gestalten, mir reicht es erst mal so :D

Code: Alles auswählen

// -- Entferne Steuerzeicehn aus einem String der in Anfuehrungszeichen steht z.B. bei CSV Dateien
Function EntferneSteuerzeichen(cTmpBuffer)
Local nStartPos := 1, nAktPos := 0, nEndPos := 0, nFoundPos := 0, nReplacePos := 0
Local cSuchenach := chr(13)+chr(10)

do while .t.
   nAktPos := AT('"',cTmpBuffer, nStartPos)
   IF nAktPos = 0
      exit
   ENDIF
   IF nAktPos > 0
      nEndPos := AT('"',cTmpBuffer,nAktPos+1)
   ENDIF
   IF nEndPos > nAktPos
      nFoundPos := AT(cSuchenach,substr(cTmpBuffer,nAktPos,nEndPos-nAktPos))
      IF nFoundPos > 0
         nReplacePos := nAktPos
         nReplacePos += (nFoundPos-1)
         cTmpBuffer[nReplacePos] := "|"
         nReplacePos++
         cTmpBuffer[nReplacePos] := "|"
      ENDIF
   ELSE
      exit
   ENDIF
   nStartPos := nEndPos + 1
enddo
return cTmpBuffer
Gruß
Klaus
Antworten