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)