Seite 1 von 1

Erstellung von Indexfiles

Verfasst: So, 04. Nov 2012 7:36
von saul
Hallo,
ich habe meine Topdown Version auf neuesten Stand gebracht und habe angefangen damit zu arbeiten. Nun gibt es dort bei der Erstellung der Index Files ein Beispiel:

Code: Alles auswählen

    -- SAMPLE --
********************** Do this for each DBF
*******     dbf                  cdx        cFlag    lUseBar  nEvery     aTags
aDbf := {"cust.dbf","cust.cdx","customer",  .F.,      10,     { {"name","lname+fname"},;   // tag1  {Tag Name,Index Key}
             {"dob" ,"stod('dob')"} ;   // tag2
        } }
aadd(aFiles,aDbf)
Wenn ich das richtig verstanden habe, so wird hier eine Indexdatei cust.cdx erstellt aber mit 2 Tags bzw. 2 Indexkeys.
Geht das überhaupt in einer Indexdatei?
Falls ja, wie kann man diese im Programm ansprechen?

mfg
Wolfgang
Wolfgang

Re: Erstellung von Indexfiles

Verfasst: So, 04. Nov 2012 10:12
von Zupan Miran
Hello
All my program have CDX index like this
aDbf := {"&pot_baze"+"PARTNER.dbf","&pot_baze"+"PARTNER.CDX","PARTNER", .T., 10,;
{ {"sifra","sifpar"},{"davcna","davcna_st"},{"naziv","naziv"} } }
this is something like old clipper way:
USE PARTNER
INDEX ON sifpar TAG sifra TO PARTNER
INDEX ON davcna_st TAG davcna TO PARTNER
INDEX ON naziv TAG naziv TO PARTNER
So, in PARTNER.CDX you have 3 keys (sifra, davcna,naziv) (translate: partner number, VAT number, name)
In program, i open the dbf
IF !tdOpenDbf("&pot_baze"+"PARTNER.dbf","PARTNER","shared")
close all; RETURN nil
ELSE
SET INDEX TO "&pot_baze"+"PARTNER"
OrdSetFocus("naziv")
ENDIF

so, when I first browse the partner.dbf , data are sorting by name, or, when you control input get data
(VAT) you must swith to example OrdSetFocus("sifra")

FUNCTION Ctrl_Part(oGetX1,oGetX2,oOld,novi)
LOCAL lVrni:=.F.
LOCAL aFields
LOCAL nRows := 24 , nCols := 76

BEGIN SEQUENCE
SELECT PARTNER
OrdSetFocus("sifra")
dbgotop()
IF dbseek(val(oGetX1:editbuffer())) .and..not. substr(alltrim(oGetX1:editbuffer()),1,1)="?"
oGetX1:setData( alltrim(str(sifpar))+space(8-len(alltrim(str(sifpar)))) )
oGetX2:setData( partner->naziv )
xnaziv_par:=naziv
xDatum_val:=dat_valute
xRabat_art:=rabat_art
xRabat_Kup:=rabat
IF novi=.T.
a30:=rabat
ENDIF
lVrni:=.T.
BREAK
ELSE
//*** doloci kolone in oznaci partnerja na crni listi ***
bColor := { || iif(crna="D", {tdRED,nil},{nil,nil} )}
bColor2 := { || iif( km=0 , {tdRED,nil},{tdBLU,nil} )}
aFields := { {"sifpar" ,"ćifra" ,.F.,,,, 4,bColor },;
{"naziv" ,"Naziv kupca",.F.,,,,22,bColor },;
{"ulica" ,"Naslov" ,.F.,,,,13,bColor },;
{"naslov" ,"Kraj" ,.F.,,,,11,bColor },;
{"davcna_st","Davźna" ,.F.,,,, 8,bColor },;
{"Km" ,"Km" ,.F.,,,, 4,bColor2} }

//*** postavi se na pravo mesto ***
OrdSetFocus("naziv")
dbgotop()

//*** iskanje ***
izberi:=tdIsearch(nRows,nCols,aFields,20,"Vnesi Kupca","@!",,"Seznam PARTNERJEV (izberi z ENTER)",,,,,,,,tdBROW2_PP,,oStari,,.T.,,.F.,.T.,,,,,,,1)
IF izberi=.F. //*** xbeK_ESC
lVrni:=.F.
ELSE //*** xbeK_ENTER
oGetX1:setData( alltrim(str(sifpar))+space(8-len(alltrim(str(sifpar)))) )
oGetX2:setData( partner->naziv )
xnaziv_par:=naziv
xDatum_val:=dat_valute
xRabat_art:=rabat_art
xRabat_Kup:=rabat
IF novi=.T.
a30:=rabat
ENDIF
lVrni:=.T.
ENDIF

//*** close
SetAppWindow(oOld)
SetAppFocus(oOld)
ENDIF

END SEQUENCE

SELECT RACUNI
RETURN lVrni

I hope this help
Miran Zupan
Slovenia

Re: Erstellung von Indexfiles

Verfasst: So, 04. Nov 2012 15:25
von georg
Hallo, Wolfgang -


seit FoxPro (oder SixDriver, was weiss ich, mein Gedächtnis setzt da aus) gibt es CDX-Dateien, die es ermöglichen, innerhalb der CDX-Datei (wohlgemerkt, nicht INDEX-Datei) individuelle Indices zu erstellen, die als "Tags" bezeichnet werden.

Also etwa

Code: Alles auswählen

INDEX ON Feld TAG "A1" TO MyIndex
INDEX ON Feld2 TAG "EinAnderesSuchKriterium" TO MyIndex
Um festzulegen, welcher der Tags verwendet werden soll, gibt es dann z.B. den Fehler

Code: Alles auswählen

ordSetFocus("EinAnderesSuchKriterium")
Der Vorteil unter DOS war, dass man lediglich einen File-Handle benötigte, aber trotzdem mehr als einen Index für eine Datei öffnen konnte.

Du kannst in der Dokumentation mal unter ord... nachsehen, da sind die meisten dazugehörigen Funktionen aufgeführt.

Re: Erstellung von Indexfiles

Verfasst: Mo, 05. Nov 2012 9:53
von AUGE_OHR
hi,

noch eine kleine Ergänzung zur CDX
TAG Name 10 Zeichen
also bitte NICHT "EinAnderesSuchKriterium"

nun ist CDX nur die "ORDER" Komponente und bei FOX hast du bei der "DATA" Komponente ja verschiedene Möglichkeiten.
abhängig davon welche DATA Komponente du verwendest ist die Indexkey() Länge bei CDX evtl. auf 120/240*** beschränkt.
***PDR 2940, 4846

Re: Erstellung von Indexfiles

Verfasst: Mo, 05. Nov 2012 9:58
von georg
Hallo, Jimmy -


danke für die Ergänzung. Ich verwende normalerweise zweistellige Tags (A1, A2, etc.) und wollte nur zeigen, dass auch längere Namen möglich sind.

Re: Erstellung von Indexfiles

Verfasst: Mo, 05. Nov 2012 10:53
von brandelh
georg hat geschrieben:Der Vorteil unter DOS war, dass man lediglich einen File-Handle benötigte, aber trotzdem mehr als einen Index für eine Datei öffnen konnte.
Die Anzahl der File-Handles ist jetzt zwar kein Thema mehr, aber wenn man nur eine CDX Datei je DBF braucht, kann man den gleichen Namen verwenden !
Eine Anwendung braucht also nur noch die Indexdatei mit dem Dateinamen der DBF (ohne ".DBF") zu öffnen und man spart sich interne Listen welche Indexdateien nun dazu gehören.
Handbuch hat geschrieben:Eine wichtige Eigenschaft des CDX Dateiformats ist, daß die Sortierfolge für Zeichen in der CDX Datei gespeichert wird, wenn eine Zeichenvergleichstabelle ausgewählt ist (siehe SET COLLATION). Dadurch wird die Sortierung von Zeichenketten zu dem Zeitpunkt festgelegt, zu dem ein Index erzeugt wird.
Handbuch hat geschrieben:Weiterhin ist anzumerken, daß Indizes für Zeichenausdrücke bei der CDXDBE unabhängig von Groß- und Kleinschreibung werden,
sobald eine Zeichenvergleichstabelle aktiv ist. Dieses Verhalten ist wiederum kompatibel mit Visual FoxPro.
Und Textindexfelder werden komprimiert abgespeichert, das spart nicht nur Plattenplatz, sondern auch Bandbreite im Netzwerk.
Hier ein Beispiel mit Ergebnis:

Code: Alles auswählen

#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
#include "Inkey.ch"
#include "DBFDBE.CH"
#include "NTXDBE.CH"
#include "FOXDBE.CH"
#include "CDXDBE.CH"

PROCEDURE dbeSys()
  SET COLLATION TO GERMAN
  SET DATE TO GERMAN
  SET EPOCH TO year(date())-80
  SET CHARSET TO OEM
  IF ! DbeLoad( "DBFDBE", .t.)
     Alert( "DBFDBE: MSG_DBE_NOT_LOADED" , {"OK"} )
  ENDIF
  IF ! DbeLoad( "NTXDBE", .t.)
     Alert( "NTXDBE: MSG_DBE_NOT_LOADED" , {"OK"} )
  ENDIF
  IF ! DbeBuild( "DBFNTX","DBFDBE","NTXDBE"  )
     Alert( "DBFNTX: MSG_DBE_NOT_CREATED" , {"OK"} )
  ENDIF
  IF ! DbeLoad( "FOXDBE", .t.)
     Alert( "FOXDBE: MSG_DBE_NOT_LOADED" , {"OK"} )
  ENDIF
  IF ! DbeLoad( "CDXDBE", .t.)
     Alert( "CDXDBE: MSG_DBE_NOT_LOADED" , {"OK"} )
  ENDIF
  IF ! DbeBuild( "FOXCDX","FOXDBE","CDXDBE"  )
     Alert( "FOXCDX: MSG_DBE_NOT_CREATED" , {"OK"} )
  ENDIF
  IF ! DbeBuild( "DBFCDX","DBFDBE","CDXDBE"  )
     Alert( "DBFCDX: MSG_DBE_NOT_CREATED" , {"OK"} )
  ENDIF
  DbeInfo( COMPONENT_DATA,  FOXDBE_MEMOBLOCKSIZE , 80 )
  DbeInfo( COMPONENT_ORDER, DBE_LOCKMODE         , LOCKING_EXTENDED )
  DbeSetDefault("DBFNTX")
RETURN

proc main
   field text, id
   cls
   ? "Aktive DBE: ",DbeSetDefault()
   CreateALL()
   DbeSetDefault("DBFCDX")
   ? "Aktive DBE: ",DbeSetDefault()
   CreateALL()
   DbeSetDefault("FOXCDX")
   ? "Aktive DBE: ",DbeSetDefault()
   CreateALL()
   ? "Fertig"
   ?
   wait

return

procedure CreateALL()
   field text, id
   local x, cFN
   cFN := "A_Test_"+DbeSetDefault()
   ? "CreateALL(), Start ",time(),"  ", DbeSetDefault()
   dbcreate(cFN, {{"ID","N",10,0},{"Text","c",100,0}})
   use (cFN) exclusive
   for x := 1 to 1000
      append blank
      replace ID with x
      replace text with "Satz "+str(x,5,0)
   next
   ? "CreateALL(), Index ",time()
   index on text tag "Text" to (cFN)
   ? "CreateALL(), Ende  ",time()
   set index to (cFN)
   if dbseek("satz") // Kleinbuchstaben suchen
      ? "'satz' wurde gefunden in '"+rtrim(text)+"' Recno():",recno()
   else
      ? "'satz' wurde nicht gefunden. CASE sensitive ! "
   endif
   use
return
Ein Feldname TEXT ist natürlich unglücklich, da TEXT auch ein Befehl ist.
Diese Beispiel funktioniert aber dennoch !
Hier das Ergebnis:

Code: Alles auswählen

Aktive DBE:  DBFNTX
CreateALL(), Start  11:27:21    DBFNTX
CreateALL(), Index  11:27:21
CreateALL(), Ende   11:27:21
'satz' wurde nicht gefunden. CASE sensitive !
Aktive DBE:  DBFCDX
CreateALL(), Start  11:27:21    DBFCDX
CreateALL(), Index  11:27:21
CreateALL(), Ende   11:27:21
'satz' wurde gefunden in 'Satz     1' Recno():               1
Aktive DBE:  FOXCDX
CreateALL(), Start  11:27:21    FOXCDX
CreateALL(), Index  11:27:21
CreateALL(), Ende   11:27:21
'satz' wurde gefunden in 'Satz     1' Recno():               1
Fertig
...
05.11.2012  11:27           111.099 A_Test_DBFNTX.DBF
05.11.2012  11:27           111.099 A_Test_DBFCDX.DBF
05.11.2012  11:27           111.361 A_Test_FOXCDX.DBF

05.11.2012  11:27           132.096 A_Test_DBFNTX.NTX
05.11.2012  11:27            14.336 A_Test_DBFCDX.CDX
05.11.2012  11:27            14.336 A_Test_FOXCDX.CDX
wenn man übrigens den TAG in dieser Zeile weg läßt:
index on text tag "Text" to (cFN)
gibt es einen runtime error:

Code: Alles auswählen

------------------------------------------------------------------------------
FEHLERPROTOKOLL von "D:\TEST\t.exe" Datum: 05.11.2012 11:24:46

Xbase++ Version     : Xbase++ (R) Version 1.90.355
Betriebssystem      : Windows XP 05.01 Build 02600 Service Pack 3
------------------------------------------------------------------------------
oError:args         :
          -> VALTYPE: C VALUE: A_Test_FOXCDX.CDX
          -> VALTYPE: C VALUE: text
          -> VALTYPE: B VALUE: {|| text}
          -> VALTYPE: U VALUE: NIL
oError:canDefault   : J
oError:canRetry     : J
oError:canSubstitute: N
oError:cargo        : NIL
oError:description  : D
oError:filename     : 
oError:genCode      :       8999
oError:operation    : DbCreateIndex
oError:osCode       :          0
oError:severity     :          2
oError:subCode      :          0
oError:subSystem    : BASE
oError:thread       :          1
oError:tries        :          1
------------------------------------------------------------------------------
CALLSTACK:
------------------------------------------------------------------------------
Aufgerufen von CREATEALL(83)
Aufgerufen von MAIN(63)
Es kann sein, dass dies am Feldnamen "TEXT" liegt.

Re: Erstellung von Indexfiles

Verfasst: Mo, 05. Nov 2012 11:02
von Jan
Für mich sind die Vorteile der cdx-Indizee:
  • Seitdem ich die verwende habe ich keine Probleme mit korrupten Indizee mehr. Bei ntx-indizee ständig.
  • Der Index heißt bei mir immer so wie die dbf, das macht es enorm übersichtlich.
  • Wenn ich irgendwo einen Index hinzufüge, dann muß ich mit ntx-Indizee darauf achten, die neu hinzugekommenen auch an allen anderen Öffnungspunkten im gleichen oder anderen Programmen mit Zugriff auf diese dbf hinzuzufügen. Bei cdx-Indizee nicht, denn die eine Datei öffne ich ohnehin, und der neu hinzugekommene wird automatisch mit geöffnet.
Jan

Re: Erstellung von Indexfiles

Verfasst: Mo, 05. Nov 2012 12:10
von Wolfgang Ciriack
Wobei ich vor langer Zeit, als ich von ntx auf cdx umgestellt habe, im Alaska Forum den Hinweis gelesen habe, man sollte aus Gründen der Stabilität nur 5 Tags pro Indexdatei verwenden, bei mehr, sollte man lieber mehrere Indexdateien verwenden.

Re: Erstellung von Indexfiles

Verfasst: Mo, 05. Nov 2012 12:20
von Manfred
aha, lese ich jetzt zum 1.Mal. Interessant.

Re: Erstellung von Indexfiles

Verfasst: Mo, 05. Nov 2012 13:26
von brandelh
ob das noch gilt ?

Re: Erstellung von Indexfiles

Verfasst: Mi, 07. Nov 2012 11:57
von Markus Walter
Als ich verwende teilweise mehr als 20... und kann nicht sagen, dass mit CDXen mit mehr als 5 tags mehr Probleme hätte, als mit CDXen mit weniger als 5...