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. :lol:

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:

Code: Alles auswählen

use ( iquellpfad + ausdatei ) via ("DELDBE")
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

Code: Alles auswählen

use ( "Daten." ) via ("DELDBE")
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