Otto,
I load an entire dbf into an Array using this function
...
LOCAL aClifor := {}
...
aClifor := load_dbf( "clifor" )
....
....
FUNCTION LOAD_DBF( cFile )
LOCAL aRecord := {}
LOCAL aFile := {}
LOCAL nFld
LOCAL nIni
SET DELETED OFF
SELECT 0
USE &cFile
GO TOP
nIni := SECONDS()
DO WHILE !EOF()
aRecord := {}
AADD( aRecord , IIF( DELETED() , "D", " " ) )
FOR nFld := 1 TO FCount()
// here if I remove condition I think I can include numeric
IF fieldtype( nFld ) = "C" .OR. fieldtype( nFld ) = "M"also
AADD( aRecord , UPPER(fieldget( nFld )) )
ENDIF
NEXT i
AADD( aFile , aRecord )
SKIP
ENDDO
SET DELETED ON
RETURN aFile
If I have to search in array call this function
sea_array( ALLTRIM("clifor"), aClifor, UPPER( field->words ) , field->progr )
at this point of the program I use cdx files created by function sea_array
// INDEX ON recno() TAG RICERCA CUSTOM TO &cCdxFile
SET INDEX TO &cIndSearch
SET ORDER TO TAG RICERCA
FUNCTION SEA_ARRAY( cFile , aFile, cCerca, cProgr )
LOCAL nPosLast
LOCAL nPos
LOCAL nFound
LOCAL iCerca
LOCAL nPos2
LOCAL nRecord
LOCAL n1 := SECONDS()
LOCAL aCerca := HB_ATokens( alltrim( cCerca ) , " " )
LOCAL aFound := {}
LOCAL nHandle
LOCAL cCdxFile := "search\" + cProgr
nPosLast := 0
DO WHILE .T.
nPos := ASCAN( aFile , { | aItem | ASCAN( aItem, { | cItem | aCerca[1] $ cItem } ) > 0 } , nPosLast + 1 )
IF nPos > 0
nFound := 1
FOR iCerca := 2 TO LEN( aCerca )
nPos2 := ASCAN( aFile[ nPos ] , { | cItem | aCerca[ iCerca ] $ cItem } )
IF nPos2 > 0
nFound ++
ENDIF
NEXT iCerca
IF nFound = LEN( aCerca )
IF aFile[ nPos , U_DELETE ] <> "D"
AADD( aFound , nPos )
ENDIF
ENDIF
nPosLast := nPos
ELSE
EXIT
ENDIF
ENDDO
ferase( cCdxFile + ".cdx" )
IF LEN( aFound ) > 0
SELECT &cFile
INDEX ON recno() TAG RICERCA CUSTOM TO &cCdxFile
FOR EACH nRecord In aFound
GOTO nRecord
OrdKeyAdd()
NEXT
SET INDEX TO
ELSE
nhandle := fcreate( cCdxFile + ".cdx" )
fclose( nHandle )
ENDIF
RETURN NIL
This is a client/server application
Server side I load into an array the content of dbf table at startup
At the end of this initial operation this app in polling mode wait for requests from clients.
A client makes a request to server that:
- perform search
- create index
the client when index is created use this index.
When a clients modifies a record of table (loaded into array) I update array in this way **
agg_rec( "clifor", aClifor, nRecno )
FUNCTION AGG_REC( cFile, aFile, nRecord )
LOCAL cDelete
LOCAL aRec := {}
LOCAL nFld, nNew
LOCAL nNuovi
LOCAL aNew := {}
LOCAL nStart := LEN( aFile )
LOCAL i
// se ci sono nuovi record prima crea i nuovi elementi dell'array vuoti
IF nRecord > LEN( aFile )
nNuovi := nRecord - LEN( aFile )
FOR nNew := 1 TO nNuovi
aRec := {}
FOR nFld := 1 TO FCount()
IF fieldtype( nFld ) = "C" .OR. fieldtype( nFld ) = "M"
AADD( aRec , "" )
ENDIF
NEXT i
AADD( aFile , aRec )
AADD( aNew , nStart + nNew )
NEXT nNew
ELSE
AADD( aNew , nRecord )
ENDIF
SELECT &cFile
FOR nNew := 1 TO LEN( aNew )
i := aNew[ nNew ]
GOTO aNew[ nNew ]
aFile[ i , U_DELETE ] := cDelete
aFile[ i , U_DELETE ] := " "
aRec := {}
AADD( aRec , IIF( DELETED() , "D", " " ) )
FOR nFld := 1 TO FCount()
IF fieldtype( nFld ) = "C" .OR. fieldtype( nFld ) = "M"
AADD( aRec , UPPER( fieldget( nFld ) ) )
ENDIF
NEXT i
FOR nFld := 1 TO LEN( aFile[ i ] )
IF aFile[ i , nFld ] <> aRec[ nFld ]
aFile[ i , nFld ] := aRec[ nFld ]
ENDIF
NEXT nFld
NEXT nNew
RETURN NIL
** I use another historical program that in real time update from main database (set of dbf tables). After each replace I write into a log file dbftable and record
Another server app read this registrations and replies anyu change in the secondary database
(You do not know how many times they saved my ass)
info@marcoboschi.it
