Textdatei in DBF übertragen
Moderator: Moderatoren
Textdatei in DBF übertragen
Hallo,
wieder ein Problem.
Ich habe eine Textdatei in der die Spalten mit TAB getrennt sind. Es gib in manchen Zeilen 2 Spalten, dann mal 4 Spalten, usw.
Wie kann ich die Daten am besten in eine DBF übertragen?
Habe jetzt eine Datenbank mit 4 Spalten angelegt. Das Problem ist aber, wenn ich z. B. aus der Textdatei die 4. Spalte einer Zeile in die DBF übertragen möchte, obwohl in der Textdatei nur 3 Spalten in der Zeile sind, dass mir das Programm crasht.
Irgendeine Lösung?
wieder ein Problem.
Ich habe eine Textdatei in der die Spalten mit TAB getrennt sind. Es gib in manchen Zeilen 2 Spalten, dann mal 4 Spalten, usw.
Wie kann ich die Daten am besten in eine DBF übertragen?
Habe jetzt eine Datenbank mit 4 Spalten angelegt. Das Problem ist aber, wenn ich z. B. aus der Textdatei die 4. Spalte einer Zeile in die DBF übertragen möchte, obwohl in der Textdatei nur 3 Spalten in der Zeile sind, dass mir das Programm crasht.
Irgendeine Lösung?
- Jan
- Marvin
- Beiträge: 14641
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 87 Mal
- Kontaktdaten:
Ist schon klar.
Aber es gibt ja eine Struktur: Wert1 TAB Wert2 TAB Wert3 TAB Wert4 CRLF
Die solle für jede Zeile gleich sein. Oder habe ich da etwas falsch verstanden?
Wenn also irgendwo steht TAB TAB dann weiß Du, daß da eigentlich ein Wert zwischengehört. Genauso, wenn da ein TAB CRLF auftaucht.
Und da schreibst Du dann eben einen von Dir zu bestimmenden Wert in Deine dbf. Ob das jetzt 0 oder NULL oder "" ist, das mußt Du wissen.
Jan
Aber es gibt ja eine Struktur: Wert1 TAB Wert2 TAB Wert3 TAB Wert4 CRLF
Die solle für jede Zeile gleich sein. Oder habe ich da etwas falsch verstanden?
Wenn also irgendwo steht TAB TAB dann weiß Du, daß da eigentlich ein Wert zwischengehört. Genauso, wenn da ein TAB CRLF auftaucht.
Und da schreibst Du dann eben einen von Dir zu bestimmenden Wert in Deine dbf. Ob das jetzt 0 oder NULL oder "" ist, das mußt Du wissen.
Jan
- Jan
- Marvin
- Beiträge: 14641
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 87 Mal
- Kontaktdaten:
OK. Verstanden. Aber das Prinzip ist gleich. Du musste einen Zähler einbauen, der vor jedem Zeilenvorschub (also vermutlich CRLF) die Werte zählt. Und sind das weniger als 4 müssen die ergänzt werden.
Also z.B. eine Schleife für jede Zeile, die bei jedem Wert 1 hochzählt.
Aber ohne Deinen Code zu kennen ist es schwierig zu sagen wie das genau auszusehen hat.
Jan
Also z.B. eine Schleife für jede Zeile, die bei jedem Wert 1 hochzählt.
Aber ohne Deinen Code zu kennen ist es schwierig zu sagen wie das genau auszusehen hat.
Jan
Hi Jan,
da verstehe ich leider gerade nur Bahnhof.
Ich bekomme eine Textdatei. Im Aufbau her wie ich im letzten Beitrag geschrieben habe.
Diese öffne ich mit der DELDBE.
Jetzt erstelle ich eine neue Datenbank und möchte die Daten übertragen. Hier der Quellcode:
[/code]
da verstehe ich leider gerade nur Bahnhof.
Ich bekomme eine Textdatei. Im Aufbau her wie ich im letzten Beitrag geschrieben habe.
Diese öffne ich mit der DELDBE.
Jetzt erstelle ich eine neue Datenbank und möchte die Daten übertragen. Hier der Quellcode:
Code: Alles auswählen
aStruct := {;
{"FIELD1", "N", 1, 0},;
{"FIELD2", "C", 100, 0},;
{"FIELD3", "C", 8, 2},;
{"FIELD4", "C", 8, 2} ;
}
DbCreate("DATENBANK.DBF", aStruct, "DBFNTX")
USE DATENBANK.dbf ALIAS DATENBANK VIA DBFNTX NEW EXCLUSIVE
FOR i := 1 TO TEXTDATEI->(RecCount())
DATENBANK->(DbAppend())
REPLACE FIELD1 WITH TEXTDATEI->FIELD1,;
FIELD2 WITH TEXTDATEI->FIELD2,;
FIELD2 WITH TEXTDATEI->FIELD3,;
FIELD4 WITH TEXTDATEI->FIELD4
TEXTDATEI->(DbSkip())
NEXT
- Jan
- Marvin
- Beiträge: 14641
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 87 Mal
- Kontaktdaten:
OK, jetzt verstehe ich besser. ich dachte, Du hättest die Textdatei irgendwie in einen String eingelesen.
Ich muß gestehen, daß ich mich mit Datenbanktreibern für Textdateien nicht auskenne. ich weiß also nicht, wie da die Werte belegt sind wenn in der Textdatei der Wert nicht existiert.
Versuch doch mal, ob das so geht:
Vielleicht hilft das ja.
Jan
Ich muß gestehen, daß ich mich mit Datenbanktreibern für Textdateien nicht auskenne. ich weiß also nicht, wie da die Werte belegt sind wenn in der Textdatei der Wert nicht existiert.
Versuch doch mal, ob das so geht:
Code: Alles auswählen
REPLACE FIELD1 WITH IIF(TEXTDATEI->FIELD1 = NULL, 0, TEXTDATEI->FIELD1,;
FIELD2 WITH IIF(TEXTDATEI->FIELD2 = NULL, "", TEXTDATEI->FIELD2,;
FIELD3 WITH IIF(TEXTDATEI->FIELD3 = NULL, "", TEXTDATEI->FIELD3,;
FIELD4 WITH IIF(TEXTDATEI->FIELD4 = NULL, "", TEXTDATEI->FIELD4
Jan
- Manfred
- Foren-Administrator
- Beiträge: 21165
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 206 Mal
- Danksagung erhalten: 67 Mal
Hallo JanR
mache es doch ganz einfach... Ich würde mir im Debugger anschauen, was denn passiert, wenn Du auf eine Field zugreifst, was nichts hat. Das ist m.E. die einfachste Methode um zu sehen, wodrauf Du dann prüfen mußt.
mache es doch ganz einfach... Ich würde mir im Debugger anschauen, was denn passiert, wenn Du auf eine Field zugreifst, was nichts hat. Das ist m.E. die einfachste Methode um zu sehen, wodrauf Du dann prüfen mußt.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
- brandelh
- Foren-Moderator
- Beiträge: 15689
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 65 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo Jan,
wenn man TXT Daten einlesen muß, sollte man die DELDBE nicht nutzen !
Diese setzt meines Wissens genau gleichen Satzaufbau und Satzlänge voraus.
Wenn alles Text ist, kann man append mit SDF nutzen, aber die TAB sind da eher ungeeignet.
Xbase geht - im Gegensatz zu Clipper - immer von tatsächlich gleichlangen Sätzen aus (angeblich eine Definition von SDF ...).
Ich mache es immer so:
cTxt := memoread(cDatei) // kein Problem auch bei 300 MB !
MEMOLINE() ist bie kleinen Dateien schön, aber bei tausenden von Zeilen muss man sich selbst kümmern. Immer nächsten suchen mit at() CRLF und die Einzelteile rausholen. Achtung nicht den String verändern (Sätze ausschneiden und kürzen), da das bei großen sehr langsam ist.
einfach den Anfang und das Ende merken und darin dann nach den Feldern suchen.
Ich habe jetzt kein Beispiel, aber es gab mal sowas über schnelle Stringbearbeitung etc...
wenn man TXT Daten einlesen muß, sollte man die DELDBE nicht nutzen !
Diese setzt meines Wissens genau gleichen Satzaufbau und Satzlänge voraus.
Wenn alles Text ist, kann man append mit SDF nutzen, aber die TAB sind da eher ungeeignet.
Xbase geht - im Gegensatz zu Clipper - immer von tatsächlich gleichlangen Sätzen aus (angeblich eine Definition von SDF ...).
Ich mache es immer so:
cTxt := memoread(cDatei) // kein Problem auch bei 300 MB !
MEMOLINE() ist bie kleinen Dateien schön, aber bei tausenden von Zeilen muss man sich selbst kümmern. Immer nächsten suchen mit at() CRLF und die Einzelteile rausholen. Achtung nicht den String verändern (Sätze ausschneiden und kürzen), da das bei großen sehr langsam ist.
einfach den Anfang und das Ende merken und darin dann nach den Feldern suchen.
Ich habe jetzt kein Beispiel, aber es gab mal sowas über schnelle Stringbearbeitung etc...
Gruß
Hubert
Hubert
- Jan
- Marvin
- Beiträge: 14641
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 87 Mal
- Kontaktdaten:
Der Vorschlag von Hubert war das, wo ich von ausgegangen war, zu Beginn der Diskussion. Da kann man dann nämlich die Tabs bis zum CRLF mitzählen und dann korrigierend eingreifen.
Ich habe das Zerteilen mal in einem älteren Programm eingebaut - habe ich aber zu Hause auf dem Rechner liegen. Ich schau nachher mal rein und würde das dann hier posten.
Jan
Ich habe das Zerteilen mal in einem älteren Programm eingebaut - habe ich aber zu Hause auf dem Rechner liegen. Ich schau nachher mal rein und würde das dann hier posten.
Jan
- Wolfgang Ciriack
- Der Entwickler von "Deep Thought"
- Beiträge: 2932
- Registriert: Sa, 24. Sep 2005 9:37
- Wohnort: Berlin
- Hat sich bedankt: 13 Mal
- Danksagung erhalten: 34 Mal
- Kontaktdaten:
Hallo Jan,
ich benutze zum Zerlegen von Textdateien immer die XbTools-Funktionen (weiss natürlich nicht ob du die Tools hast).
Damit geht das relativ einfach (Quick and dirty Beispiel):
ich benutze zum Zerlegen von Textdateien immer die XbTools-Funktionen (weiss natürlich nicht ob du die Tools hast).
Damit geht das relativ einfach (Quick and dirty Beispiel):
Code: Alles auswählen
trzch:=";"
offset:=0
laenge:=filesize(impdatei)
do while offset+10<laenge
* Zeilen nicht länger als 600 Zch.
tmp:=filestr(impdatei,600,offset)
* Trennzeichen ist CRLF
satztrenn:=at(chr(10),tmp)
offset+=satztrenn
satz:=substr(tmp,1,satztrenn-1)
** satz ist mein Datensatz
i:=0
** benötige nur bestimmte
tokeninit(@satz,trzch,1)
do while !tokenend()
vari:=tokennext(satz)
if !empty(vari)
do case
case i=0
v1:=vari
case i=2
v2:=val(vari)
.....
......
endcase
endif
i++
enddo
if v2<>0
append ....
replace ....
endif
enddo
Viele Grüße
Wolfgang
Wolfgang
- Jan
- Marvin
- Beiträge: 14641
- Registriert: Fr, 23. Sep 2005 18:23
- Wohnort: 49328 Melle
- Hat sich bedankt: 21 Mal
- Danksagung erhalten: 87 Mal
- Kontaktdaten:
Jan,
nicht verzagen, Forum fragen.... Da wird Sie geholfen. Wir kriegen das schon mit alle Mann (wieso eigentlich keine Frauen?) zusammen irgendwie hin.
Trotzdem eine schlechte Nachricht: Ich habe da alte Projekt anscheinend in einem Anfall von Wahnvorstellungen gelöscht. Mist! Aber gib mir ein wenig Zeit, ich versuche mal, ob ich das noch rekonstruieren kann. Und ich bin mir sehr sicher, daß ich das ohne Tools gemacht habe.
Apropos Tools: Hast Du keine Subscription? Da wären die dann automatisch mit bei. Muß ja nicht gleich die ultrateure sein, die kleine reicht ja auch schon...
Jan
nicht verzagen, Forum fragen.... Da wird Sie geholfen. Wir kriegen das schon mit alle Mann (wieso eigentlich keine Frauen?) zusammen irgendwie hin.
Trotzdem eine schlechte Nachricht: Ich habe da alte Projekt anscheinend in einem Anfall von Wahnvorstellungen gelöscht. Mist! Aber gib mir ein wenig Zeit, ich versuche mal, ob ich das noch rekonstruieren kann. Und ich bin mir sehr sicher, daß ich das ohne Tools gemacht habe.
Apropos Tools: Hast Du keine Subscription? Da wären die dann automatisch mit bei. Muß ja nicht gleich die ultrateure sein, die kleine reicht ja auch schon...
Jan
- AUGE_OHR
- Marvin
- Beiträge: 12903
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 44 Mal
hi,
auch eine Lösung :
in DoMyTAB kannst du nun die Zeile "zerpflücken"
gruss by OHR
Jimmy
p.s. sind in dem Textfile "Umlaute" ?
ich mache es zwar immer über FOPEN, aber für MEMOREAD gibtsJanR hat geschrieben: die XbTools habe ich leider nicht. Gibt es da keine andere Lösung? Bin langsam am verzweifeln
auch eine Lösung :
Code: Alles auswählen
LOCAL cText := MemoRead( cSysFilename )
LOCAL nMaxLines := MlCount( cText, 80 )
LOCAL cLine, n
FOR n:=1 TO nMaxLines
cLine := Trim( MemoLine( cText, 80, n ) )
DoMyTAB(cLine)
NEXT
gruss by OHR
Jimmy
p.s. sind in dem Textfile "Umlaute" ?
- brandelh
- Foren-Moderator
- Beiträge: 15689
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 65 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hallo JanR,
es kommt ganz auf die Anzahl der Zeilen der Importdatei an und auf die Zeit, die es dauern darf. Die Lösung von JIMMY ist die Standard Clipper-Lösung. Das Problem ist die Verarbeitungszeit, die bei ein paar tausend Zeilen noch gut ist, danach aber explodiert. Memoline merkt sich die aktuelle Zeile nicht !
Wenn du also was schnelleres für große Dateien brauchst, dann muß man selbst die Satzgrenzen ermitteln (so aus dem Gedächtnis, also eventuell Tippfehler enthalten ) :
Diese Methode ist sehr schnell, da der Hauptstring im Speicher nicht mehr bewegt wird. Ich nutze diese Art bei Dateien mit 300 MB und vielen Millionen von Zeilen, es ist wirklich flexibel und flott. Der Arbeitsspeicher des Rechners sollte allerdings das doppelte an Arbeitsspeicher haben wie die Datei groß ist (250 MB Datei -> 512 MB Rechner, ich habe 2 GB )
Der AT Befehl hat erst ab 1.82 den 3. Parameter ...
Ich habe da noch eine Funktion, die die Datei auf Festplatte Zeilenweise einließt, ich meine die ist auch auf den Alaska Seiten ...
es kommt ganz auf die Anzahl der Zeilen der Importdatei an und auf die Zeit, die es dauern darf. Die Lösung von JIMMY ist die Standard Clipper-Lösung. Das Problem ist die Verarbeitungszeit, die bei ein paar tausend Zeilen noch gut ist, danach aber explodiert. Memoline merkt sich die aktuelle Zeile nicht !
Wenn du also was schnelleres für große Dateien brauchst, dann muß man selbst die Satzgrenzen ermitteln (so aus dem Gedächtnis, also eventuell Tippfehler enthalten ) :
Code: Alles auswählen
#define CRLF chr(13)+chr(10)
cTXT := MemoRead(...) // diesen TEXT nicht mehr ändern !
nZeile := 1
nZeiVon := 1
nZeiBis := 0
nTab := 0
do while .t. // aktuelle nZeiVon ist schon bekannt
// geht erst ab 1.82:
// At( <cSubString>, <cString>, [<nStartPos>] ) --> nPosition
nZeiBis := At( CRLF, cTXT, nZeiVon ) // 1. Zeichen von CRLF !
if nZeiBis > 0
cZeile := substr(cTXT,nZeiVon,nZeiBis-nZeiVon)
else
cZeile := substr(cTXT,nZeiVon) // nun den Rest der Datei
nZeiBis := len(cZeile) //Abbruchbedingung
endif
// mit cZeile kann man spielen, da kurz...
do while .t.
nTab := at(chr(9),cZeile)
if nTab > 0
uFeld := left(cZeile,nTab-1)
cZeile := substr(cZeile,nTab+1)
else // alle Felder ausgelesen
uFeld := cZeile
cZeile := ""
endif
... tu was damit
if empty(cZeile)
exit
endif
enddo
// Datensatz ist verarbeitet
nZeiVon := nZeiBis+2 // CR + LF = 2 Zeichen
if nZeiVon > len(cTXT)
exit
endif
enddo
Der AT Befehl hat erst ab 1.82 den 3. Parameter ...
Ich habe da noch eine Funktion, die die Datei auf Festplatte Zeilenweise einließt, ich meine die ist auch auf den Alaska Seiten ...
Gruß
Hubert
Hubert
- brandelh
- Foren-Moderator
- Beiträge: 15689
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 65 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Hi,
hier ist die Datei mit der man Textdateien direkt zeilenweise auslesen kann (das Original stammt noch von Clipper wie ich gerade im Header lesen kann):
hier ist die Datei mit der man Textdateien direkt zeilenweise auslesen kann (das Original stammt noch von Clipper wie ich gerade im Header lesen kann):
Code: Alles auswählen
* Funktionen zur Behandlung von ASCII Textdateien
* Anpassung von Original CL5 Beispielen: FILEIO.PRG
*
* Im Gegensatz zu Original Funktion, wird bei einem String
* nie CHR(26) zurückgegeben -> Markiert ein Dateiende
* und CR+LF wird am Ende des Strings abgeschnitten.
*
#ifdef TEST
cls
nDateiHandle := TxtDatOpen( "manuRech.lst" )
? 'TxtDatOpen( "AutoRech.lst" )', nDateiHandle
?
?
nZeile := 0
cZeile := ""
do while .t.
cZeile := TxtDatRead( nDateiHandle,1,100 )
if len(cZeile)=0
exit
endif
?? cZeile
if chr(26) $ cZeile
?? "CHR(26)"
endif
if chr(13) $ cZeile
?? "CR"
endif
if chr(10) $ cZeile
?? "LF"
endif
nZeile++
enddo
? "ENDE"
#endif
#include "FileIO.ch"
#include "common.ch"
*
* Funktionen zur Bearbeitung von ASCII Textdateien
*
*--------------------------------------------------------------
function TxtDatOpen( cDatName, nModus )
return fopen( cDatName, nModus )
*--------------------------------------------------------------
function TxtDatCreate( cDatName, nModus )
return fcreate( cDatName, nModus )
*--------------------------------------------------------------
function TxtDatClose( nHandle )
return fclose( nHandle )
*--------------------------------------------------------------
function TxtDatGoTop( nHandle ) // gibt aktuelle Position zurück
RETURN ( FSEEK( nHandle, 0 ) )
*--------------------------------------------------------------
function TxtDatGoBottom( nHandle ) // gibt aktuelle Position zurück
RETURN ( FSEEK( nHandle, 0, FS_END ) )
*--------------------------------------------------------------
function TxtDatPos( nHandle )
RETURN ( FSEEK( nHandle, 0, FS_RELATIVE ) )
*--------------------------------------------------------------
function TxtDatWrite( nHandle, cTxt, nAnz )
nAnz := fWrite(nHandle, cTxt, nAnz)
RETURN nAnz
*--------------------------------------------------------------
function TxtDatSize( nHandle )
LOCAL nCurrent
LOCAL nLength
nCurrent := TxtDatPos( nHandle ) // Aktuelle Position sichern
nLength := TxtDatGoBottom( nHandle ) // Länge ermitteln
FSEEK( nHandle, nCurrent ) // Dateizeiger zurücksetzen
RETURN nLength
*--------------------------------------------------------------
function TxtDatEOF( nHandle )
LOCAL nCurrent, lEOF
nCurrent := TxtDatPos( nHandle ) // Aktuelle Position sichern
lEOF := (nCurrent = TxtDatGoBottom( nHandle ))
// EOF = .t. wenn
// Aktuelle Position gleich
// Dateiende ist !
FSEEK( nHandle, nCurrent ) // Dateizeiger zurücksetzen
RETURN lEOF
*--------------------------------------------------------------
/***
*
* TxtDatRead( <nHandle>, [<nLines>], [<nLineLength>], [<cDelim>] ) --> cLines
*
* Liest eine oder mehrere Zeilen aus einer Textdatei
*
* HINWEIS:
* In die Zeilenlänge gehen die Begrenzer mit ein, so daß die maximale
* Länge einer gelesenen Zeile (nLineLength - LEN( cDelim )) ist.
*
* Vorgaben: nLines=1, nLineLength=80, cDelim=CRLF
*
* Fehlerprüfung muß über FERROR() erfolgen.
*
* FReadLn() gibt eine leere Zeichenkette ("") zurück, wenn EOF
* erreicht wird.
*
*/
function TxtDatRead( nHandle, nLines, nLineLength, cDelim )
LOCAL nCurPos // Aktuelle Position in Datei
LOCAL nFileSize // Dateigröße
LOCAL nChrsToRead // Anzahl der zu lesenden Zeichen
LOCAL nChrsRead // Anzahl der aktuell gelesenen Zeichen
LOCAL cBuffer // Lese-Puffer
LOCAL cLines // Rückgabe - Anzahl der gelesenen Zeilen
LOCAL nCount // Zähler der gelesenen Zeilen
LOCAL nEOLPos // Position von EOL (End Of Line) in cBuffer
DEFAULT nLines TO 1
DEFAULT nLineLength TO 80
DEFAULT cDelim TO ( CHR(13) + CHR(10) )
nCurPos := TxtDatPos( nHandle )
nFileSize := TxtDatSize( nHandle )
// Sicherstellen, daß kein Lesezugriff hinter EOF erfolgt
nChrsToRead := MIN( nLineLength, nFileSize - nCurPos )
cLines := ''
nCount := 1
DO WHILE (( nCount <= nLines ) .AND. ( nChrsToRead != 0 ))
cBuffer := SPACE( nChrsToRead )
nChrsRead := FREAD( nHandle, @cBuffer, nChrsToRead )
// Fehlerbedingung prüfen
IF !(nChrsRead == nChrsToRead)
// Fehler!
// Um konzeptionell mit den low-level Dateifunktionen
// kompatibel zu bleiben, wird der Benutzer gezwungen
// FERROR() auszuwerten (wurde durch FREAD() gesetzt),
// um den Fehler zu bemerken.
//
nChrsToRead := 0
ENDIF
nEOLPos := AT( cDelim, cBuffer )
// Puffer und aktuelle Dateiposition aktualisieren
IF ( nEOLPos == 0 )
cLines += LEFT( cBuffer, nChrsRead )
nCurPos += nChrsRead
ELSE
cLines += LEFT( cBuffer, ( nEOLPos + LEN( cDelim ) ) - 1 )
nCurPos += ( nEOLPos + LEN( cDelim ) ) - 1
FSEEK( nHandle, nCurPos, FS_SET )
ENDIF
// CHR(26) = EOF Char in Textdateien beachten !
if chr(26) $ cLines // Achtung CHR(26) in String enthalten.
cLines := LEFT( cLines, at( chr(26),cLines )-1 ) // Kürzen vor Chr(26)
TxtDatGoBottom( nHandle ) // Datei auf EOF setzen
exit // Schleife verlassen
endif
// Sicherstellen, daß kein Lesezugriff hinter EOF erfolgt
IF (( nFileSize - nCurPos ) < nLineLength )
nChrsToRead := ( nFileSize - nCurPos )
ENDIF
nCount++
ENDDO
if right( cLines , 2 ) = CHR(13) + CHR(10)
cLines := left( cLines , len(cLines)-2 )
endif
RETURN ( cLines )
[quote][/quote]
Gruß
Hubert
Hubert