Seite 2 von 3
Verfasst: Mo, 29. Okt 2007 17:58
von Manfred
Naja,
wir haben halt einen großen Vorteil den Könnern hier gegenüber:
Wir können noch sehr viel dazulernen und haben noch einen ganz großen Ahaeffekt.
Verfasst: Mo, 29. Okt 2007 18:01
von Martin Altmann
Hallo Manfred,
hast Du in Deiner neuen Datei mal die Anzahl der ";" gezählt?
Es muß ein vielfaches der Zeilenanzahl sein - wenn nicht, klappt es natürlich nicht! Dann hast Du innerhalb eines Feldes ebenfalls ein ";" und dann knallt es!
Viele Grüße,
Martin
Verfasst: Mo, 29. Okt 2007 18:04
von Manfred
Hi Martin,
wie ein Vielfaches der Zeilenanzahl? Das ist es doch schon, wenn pro Zeile mehr als 1 Semikolon auftaucht.
meinst Du wenn innerhalb eines Feldes nochmal ein ";" auftaucht, also zum Beispiel test;test, das aber ein Feld sein soll?
Nun, das war mit das erste was ich geprüft hatte. Ist wirklich nur als Feldtrenner genutzt.
Verfasst: Mo, 29. Okt 2007 18:05
von Martin Altmann
Yup!
Dann ist ja gut...
Viele Grüße,
Martin
Verfasst: Mo, 29. Okt 2007 18:11
von AUGE_OHR
hi,
Manfred hat geschrieben:
PS: Stopp, ich habe es gefunden. Ich denke AtNum() ist mein Freund.
oder in pure Xbase++
Code: Alles auswählen
FUNCTION Countat( cFile, cExt )
LOCAL nRet := 0
LOCAL nPosi := 1
LOCAL nMax := LEN(cFile)
DO WHILE nPosi > 0
nPosi := AT(cExt,cFile,nPosi+1)
IF nPosi > 0
nRet++
ELSE
EXIT
ENDIF
ENDDO
RETURN nRet
Beispiel :
nPosi := Countat( UPPER(cFile),".AVI")
cSuch := STRTRAN( UPPER(cFile),".AVI" ,".AVS", nPosi )
das sollte auch mit ";" funktionieren.
gruss by OHR
Jimmy
Verfasst: Mo, 29. Okt 2007 18:15
von Manfred
Hi Jimmy,
das ist sicherlich wahr, aber dann kommen wir zu meinem Thema im anderen Thread, wie man sowas optimieren kann. Ich denke einmal die fertigen Funktionen sind auch schneller als es in reinem Xbase++ nachzubauen.
Verfasst: Mo, 29. Okt 2007 19:00
von Manfred
Hi,
hat irgendwer eine Ahnung, ob Charrepl() aus den Tools eine Größenbegenzung hat? Ich habe jetzt einfach einmal versucht die ";" gegen ein CHR(9) auszutauschen, von dem ich ja weiß, dass es klappt. Es wird immer nur ein leerer String zurückgeliefert. Wenn ich einen kurzen eigenen Satz bilde, dann klappt die Funktion.
Das hier klappt:
nText := Charrepl(";","hallo;das;ist;ein;test",CHR(9))
Naja, die Datei hat zur Zeit eine Größe von über 360MB.....
Verfasst: Mo, 29. Okt 2007 19:36
von AUGE_OHR
hi,
Manfred hat geschrieben:
das ist sicherlich wahr, aber dann kommen wir zu meinem Thema im anderen Thread, wie man sowas optimieren kann. Ich denke einmal die fertigen Funktionen sind auch schneller als es in reinem Xbase++ nachzubauen.
aber "die" Funktion gibt es nicht in den Xbtools ... sie zählt ja nur wie
oft ein Zeichen vorkommt.
gruss by OHR
Jimmy
Verfasst: Mo, 29. Okt 2007 19:41
von Manfred
Watt?
Du meinst jetzt auch Charrepl() ? Die macht genau das was ich haben will, naja zumindest bei kleinen Texten. Ich versuche gerade einmal zu prüfen, ob es wirklich eine Grenze gibt...
Verfasst: Mo, 29. Okt 2007 19:58
von AUGE_OHR
hi,
Manfred hat geschrieben:
Watt?
Du meinst jetzt auch Charrepl() ? Die macht genau das was ich haben will, naja zumindest bei kleinen Texten. Ich versuche gerade einmal zu prüfen, ob es wirklich eine Grenze gibt...
ich bezog mich auf die von mir gepostete Function Countat().
was Charrepl() kann man doch auch STRTRAN() nehmen?!
gruss by OHR
Jimmy
Verfasst: Mo, 29. Okt 2007 20:00
von Manfred
Stimmt, verdammt, habe ich die ganze Zeit übersehen. Das werde ich jetzt mal ausprobieren.
Verfasst: Mo, 29. Okt 2007 20:06
von Manfred
So,
also Charrepl() scheint irgendwie ne Macke zui haben bei sehr großen Dateien. Mit StrTran() geht es. Jetzt habe ich die ";" gegen CHR(9) ausgetauscht, aber dei Unterteilung in Field1-x klappt trotzdem nicht. Die DELDBE macht immer nur ein Spalte daraus. Also liegt das Problem woanders. Hm, also weiterbasteln.
Verfasst: Mo, 29. Okt 2007 20:41
von AUGE_OHR
hi,
Manfred hat geschrieben:
Die DELDBE macht immer nur ein Spalte daraus. Also liegt das Problem woanders.
Yup an deiner Reihenfolge ...
Code: Alles auswählen
DBESETDEFAULT("deldbe")
// Umschalten zu Multi-Field
DbeInfo( COMPONENT_DATA, DELDBE_MODE, DELDBE_MULTIFIELD )
// Semikolon als Trennzeichen zwischen den Spalten
DBEINFO(COMPONENT_DATA, DELDBE_FIELD_TOKEN,";")
// Kein Trennzeichen für Zeichenwerte
DBEINFO(COMPONENT_DATA, DELDBE_DELIMITER_TOKEN, Chr(0) )
DBEINFO(COMPONENT_DATA, DELDBE_MAX_BUFFERSIZE, 128*1024)
// Währungen werden mit Komma getrennt
DBEINFO(COMPONENT_DATA, DELDBE_DECIMAL_TOKEN, ",")
CLS
* Dbusearea(.T.,"DELDBE","SEMIKO.TXT",,.F.)
USE ("SEMIKO.TXT") VIA DELDBE
browse()
RETURN
so würde es ja gehen, aber : Das ";" ist ja üblicherweise bei CVS Dateien
in der ersten Zeile und wird als Feldname übernommen ... wenn er aber
kein ";" mehr findet wird es einen Makro Error geben ...
und es gibt wohl auch noch einen offenen BUG seit der v1.3x :
http://www.alaska-software.com/scripts/ ... PDRID=3629
Wenn du also wirklich Textdateien browsen willst geht das auch ohne
DELDBE wenn man die "Skipper" anpasst. Ich hab da sicherlich noch
was rumliegen ... muss mal suchen.
gruss by OHR
Jimmy
Verfasst: Mo, 29. Okt 2007 21:19
von AUGE_OHR
hi,
hier ist so ein Textbrowser mit "Skipper"
gruss by OHR
Jimmy
Code: Alles auswählen
/*****
*
* TBR28.PRG
* Browsing a text file - first approach
*
*/
#include "inkey.ch"
#include "fileio.ch"
#include "setcurs.ch"
#include "samples.ch"
#include "tbrowse.ch"
#define WHAT_IT_DOES "ESC - Quit"
#xtranslate BOFile() => (n == nFirstRec)
#xtranslate EOFile() => (n == nLastRec)
// Global stuff
STATIC cBuffer
STATIC n
STATIC nLastRec
STATIC nFirstRec
/*****
*
* Main Function
* WARNING: This program does not handle line overflow
*
*/
PROCEDURE MAIN(cFile)
TBR28(cFile)
RETURN
FUNCTION Tbr28( cFile )
LOCAL nHandle, oBrow, nKey, nMaxRow, nMaxCol
LOCAL oCol
// Open file
nHandle := FOPEN( cFile, FO_READ )
IF nHandle < 0
SCROLL()
QOUT( MSG_TBR28_ERR )
QUIT
ENDIF
// Screen (not handled by TBrowse
SETCURSOR(SC_NONE)
SETBLINK(.F.) // This way you have more colors
SETCOLOR(BR_TXT_BGND_CLR)
SCROLL()
nMaxRow := MAXROW()
nMaxCol := MAXCOLUMN
SCROLL()
// "Shadow"
SETCOLOR(BR_TXT_BLACK)
SCROLL( 3, 4, nMaxRow - 2, nMaxCol - 2)
SETCOLOR(BR_TXT_CLR_SPEC)
@ 0, 0 SAY PADC(BR_TXT_HEADER, nMaxCol + 1) COLOR BR_TXT_HEAD_CLR
@ nMaxRow, 0 SAY PADC(WHAT_IT_DOES, nMaxCol + 1) COLOR MSG_ROW_CLR
// Positioning
nLastRec := FindBottom(nHandle)
nFirstRec := n := FindTop(nHandle)
// STEP 1
oBrow := TBROWSEDB( 2, 2, nMaxRow - 3, nMaxCol - 4)
oBrow:skipBlock := {|x| SkipRec(x, nHandle)}
oBrow:goTopBlock := {|| n := FindTop(nHandle)}
oBrow:goBottomBlock := {|| n := FindBottom(nHandle)}
// STEP 2
cBuffer := SPACE(RECSIZE)
oCol := TBCOLUMNNEW( , {|| cBuffer} )
oCol:width := nMaxCol - 5
oBrow:addColumn(oCol)
WHILE .T.
// STEP 3
ForceStable(oBrow)
// STEP 4
nKey := INKEY(0)
IF !TBMoveCursor( nKey, oBrow )
IF nKey == K_ESC
EXIT
ENDIF
ENDIF
END
SCROLL()
RETURN (NIL)
/*****
*
* Main Skipper
*
*/
FUNCTION SkipRec( nRequest, nHandle )
LOCAL nActually := 0
IF (nRequest == 0)
ReadLine(nHandle, 0)
ELSEIF (nRequest > 0)
WHILE (nActually < nRequest) .AND. ;
(!EOFile())
ReadLine(nHandle, 1)
nActually++
END
ELSEIF (nRequest < 0)
WHILE (nActually > nRequest) .AND. ;
(!BOFile())
ReadLine(nHandle, -1)
nActually--
END
ENDIF
RETURN (nActually)
/*****
*
* Top of File
*
*/
FUNCTION FindTop(nHandle)
LOCAL cBuff := SPACE(RECSIZE)
LOCAL nAt
FSEEK(nHandle, 0, FS_SET)
FREAD(nHandle, @cBuff, RECSIZE)
nAt := AT(CR, cBuff)
RETURN (FSEEK(nHandle, nAt + 1, FS_SET))
/*****
*
* Bottom of File
*
*/
FUNCTION FindBottom(nHandle)
// Assume last byte is an LF
RETURN (FSEEK(nHandle, 0, FS_END))
/*****
*
* Reads a line of text
*
*/
FUNCTION ReadLine( nHandle, nRec )
LOCAL cBuff := SPACE( RECSIZE )
LOCAL nAt
IF (nRec == 0)
BackCRLF(nHandle, 1)
ELSEIF (nRec < 0)
BackCRLF(nHandle, 2)
ENDIF
FREAD(nHandle, @cBuff, RECSIZE)
nAt := AT(CR, cBuff)
FSEEK(nHandle, n, FS_SET)
cBuff := SPACE(RECSIZE)
FREAD(nHandle, @cBuff, nAt + 1)
n := FSEEK(nHandle, 0, FS_RELATIVE)
cBuffer := SUBSTR(cBuff, 1, RAT(CR, cBuff) - 1)
RETURN (NIL)
/*****
*
* Pointer at proper place
*
*/
FUNCTION BackCRLF(nHandle, nTimes)
LOCAL cBuff
LOCAL nCnt := 0
FSEEK(nHandle, -2, FS_RELATIVE)
WHILE (nCnt < nTimes)
cBuff := SPACE(1)
WHILE (cBuff != CR) .AND.;
(FSEEK(nHandle, 0, FS_RELATIVE) != 0)
FSEEK(nHandle, -1, FS_RELATIVE)
FREAD(nHandle, @cBuff, 1)
FSEEK(nHandle, -1, FS_RELATIVE)
END
nCnt++
END
IF (FSEEK(nHandle, 0, FS_RELATIVE) != 0)
n := FSEEK(nHandle, 2, FS_RELATIVE)
ELSE
n := FSEEK(nHandle, 0, FS_SET)
ENDIF
RETURN (NIL)
// EOF - TBR28.PRG //
Verfasst: Di, 30. Okt 2007 8:17
von Manfred
Hi
verflixt, das war nur ein Beispiel. Ich wollte Textdateien schon so behandeln wie eine DB, nämlich Skippen und dann die entsprechenden Spalten in eine normale dbf speichern.
Verfasst: Di, 30. Okt 2007 9:16
von Manfred
Hi,
was läuft denn hier schon wieder falsch?
Code: Alles auswählen
#include "deldbe.ch"
#include "Fileio.ch"
PROCEDURE main()
DBESETDEFAULT("deldbe")
DBEINFO(COMPONENT_DATA, DELDBE_FIELD_TOKEN,CHR(9))
DBEINFO(COMPONENT_DATA, DELDBE_DELIMITER_TOKEN, Chr(0) ) //
DBEINFO(COMPONENT_DATA, DELDBE_MAX_BUFFERSIZE, 128*1024)
DBEINFO(COMPONENT_DATA, DELDBE_DECIMAL_TOKEN, ",") // Währungen werden mit Komma getrennt
DbeInfo(COMPONENT_DATA, DBE_EXTENSION,"")
DBEINFO(COMPONENT_DATA, DELDBE_FIELD_TYPES, "NCCNNCNCCCCCNCCNNCCCCCC")
Dbusearea(.T.,"DELDBE","generic",,.F.)
RETURN
Es kommt bei Dbusearea, oder auch nur einfach USE die Fehlermeldung unzulässige Funktion. Wenn ich direkt nach Dbesetdefault("deldbe") abfrage, dann ist die Deldbe aktiv.
Verfasst: Di, 30. Okt 2007 9:21
von Martin Altmann
Hallo Manfred,
ich mache das - im Prinzip - so wie Du, nur nehme ich statt des dbUseAreas einfach:
Viele Grüße,
Martin
Verfasst: Di, 30. Okt 2007 9:23
von Martin Altmann
...wobei ich mich nur auf die drei DELDBE_DELIMITER_TOKEN, DELDBE_FIELD_TOKEN und DELDBE_FIELD_TYPES beschränke!
Viele Grüße,
Martin
Verfasst: Di, 30. Okt 2007 9:27
von Manfred
Hi Martin,
ich habe ja oben genanntes Problem. Ich habe gerade aus einem funktionierenden Programmteil den Part übernommen, in dem ich eine TExtdatei öffne und die Spaltentrennung klappt. Ich möchte jetzt Schritt für Schritt nachvollziehen, wo denn nun das Problem liegt. Irgendwo mache ich etwas falsch, oder anders als im funktionierenden Teil.
Verfasst: Di, 30. Okt 2007 9:27
von Martin Altmann
Hallo Manfred,
was willst Du mit DBE_EXTENSIONS erreichen?
Dein Kommentar zu DELDBE_DECIMAL_TOKEN ist irreführend! Natürlich werden nicht die Währungen mit "," getrennt, sondern Zahlen haben ein "," als Dezimaltrennzeichen (also 123,09 statt 123.09)!
Viele Grüße,
Martin
Verfasst: Di, 30. Okt 2007 9:29
von Manfred
Hi Martin,
damit erreiche ich, dass das Programm auch eine TExtdatei ohne .txt aufmacht. Ansonsten erwartet es text.txt und das ist in dem Fall nicht gut.
Verfasst: Di, 30. Okt 2007 9:33
von Martin Altmann
Hmm,
ich habe bei mir den Parameter nicht und er öffnet trotzdem eine Datei namens Daten.csv ohne Probleme.
Oder meinst Du, dass er eine Datei namens Daten öffnen soll - völlig ohne Extension?
Geht denn dann nicht einfach
Aber wenn das an sich funktioniert, dann ist ja gut...
Viele Grüße,
Martin
Verfasst: Di, 30. Okt 2007 9:34
von Manfred
richtig,
ich meinte OHNE Extension. Ich habe es nur so probiert und war mit dem Ergebnis dann zufrieden.
Verfasst: Di, 30. Okt 2007 10:51
von Manfred
Also,
das Problem ist gelöst. Allerdings frage ich mich jetzt ob da nicht evtl. ein dicker Hund im System begraben ist? Die Fehlermeldung "unzulässige Funktion" worauf läßt die denn schließen?
Falsch!!
Richtig ist "Die Datei ist nicht vorhanden"....
Das ich darauf nicht von selbst gekommen bin, tse tse tse.
Verfasst: Di, 30. Okt 2007 12:07
von Manfred
So Leute,
Charrepl() -> PDR 5998