Page 1 of 1
check on a archive from a array- resolved
Posted: Mon Jul 15, 2019 8:49 pm
by Silvio.Falconi
I have to check in an archive to see if there are records that need to be deleted because they are not needed.
To check which elements are not necessary I have to compare if two items of an array (adata) previously loaded are the same in the archive.
If in the archive a record has the contents of two fields that are not equal to the items of aData must be deleted.
I made this test but it not found that I wish
Code: Select all
Function Trova_tariffe_inutili(cDir,adata)
Local oTariffe
Local n
Local cIdElemento
Local cSettore
Local lyes:= .f.
Local atemp:={}
xbrowser aData
For n= 1 to Len(adata)
cIdElemento:= aData [n][2]
cSettore := aData [n][4]
oTariffe:=TDatabase():Open( , cDir+"TARIFFE", "DBFCDX", .T. )
oTariffe:SetOrder( 1 )
oTariffe:GoTop()
Do while .not. oTariffe:eof()
IF oTariffe:Tasettore==cSettore .and. oTariffe:TaElemento=cIdElemento
else
aadd(atemp,{oTariffe:TaElemento,oTariffe:Tasettore} )
Endif
oTariffe:skip()
Enddo
oTariffe:close()
cSettore:=""
next
xbrowser atemp
return nil
on aData I have these items
on archive Tariffe.dbf I have these records
so the procedure must search only the two records
because tasettore = "I" and tasettore ="F" on adata not exit
How I can resolve it ?
Re: check on a archive from a array
Posted: Wed Jul 17, 2019 2:52 pm
by ukoenig
Silvio,
If in the archive a record has the contents of two fields
that are not equal to the items of aData must be deleted.
my test to filter data from a array
Just to know if the speed needs to be increased :
how many records You have to test and what is the length of the array to be checked
regards
Uwe
Re: check on a archive from a array
Posted: Wed Jul 17, 2019 4:30 pm
by Silvio.Falconi
Uwe,
I cannot Know it
on archive can be also 2000 rows
on aData array generally there are now 24 rows but it depend from some factors
I need it ...I can explain you
when creating a beach I can insert elements that are for hire, for these elements the price list must be made for each price list which are generally 3 and can vary according to the sectors from A to H
elements x price lists x sectors
the next are those who create the beach can remove an element or a sector: for example, this year you find an umbrella in the H sector but next year you will find a beach umbrella in sector G and not more H
so the idea was to find in the tariff archive the price list that is no longer necessary because precisely the rates for the H sector umbrella are no longer needed
Re: check on a archive from a array
Posted: Wed Jul 17, 2019 6:49 pm
by ukoenig
Silvio,
how often You have to run this test.
I'm just thinking about. to include a meter-control in case of a longer running time.
regards
Uwe
Re: check on a archive from a array
Posted: Thu Jul 18, 2019 11:08 am
by Silvio.Falconi
No because the final user can run this procedure at init of each season.
i must know wich record to erase because then on report of price list the record deleted must no printed
Re: check on a archive from a array
Posted: Thu Jul 18, 2019 3:28 pm
by ukoenig
Silvio,
I tested a solution for better speed ( short and very fast )
It only scans the array-data and not the maybe possible 2000 records from the dbf
Code: Select all
FUNCTION SELECT_DATA(oCust1, aData)
LOCAL n := 1
// CreateIndex( cFile, cTag, cKey, lUnique, lDescend, lMemory )
oCust1:CreateIndex( "CUSTOMER", "TMP", "LAST + FIRST", , , .T. ) // index in memory
FOR n := 1 TO LEN(aData) // scan and select data from array
// filter on array-data
oCust1:ORDSCOPE(0, NIL ) // reset
oCust1:ORDSCOPE(1, NIL ) // reset
oCust1:ORDSCOPE(0, aData[n][1] + aData[n][2] ) // set top scope from array
oCust1:ORDSCOPE(1, aData[n][1] + aData[n][2] ) // set bottom scope from array
oCust1:GoTop()
DO WHILE oCust1:EOF() = .F.
oCust1:DELETE() // delete filter-data
oCust1:Skip()
ENDDO
n++
NEXT
oCust1:ORDSCOPE(0, NIL ) // reset
oCust1:ORDSCOPE(1, NIL ) // reset
regards
Uwe
Re: check on a archive from a array
Posted: Thu Jul 18, 2019 4:26 pm
by Silvio.Falconi
ukoenig wrote:Silvio,
I tested a solution for better speed ( short and very fast )
It only scans the array-data and not the maybe possible 2000 records from the dbf
Code: Select all
FUNCTION SELECT_DATA(oCust1, aData)
LOCAL n := 1
// CreateIndex( cFile, cTag, cKey, lUnique, lDescend, lMemory )
oCust1:CreateIndex( "CUSTOMER", "TMP", "LAST + FIRST", , , .T. ) // index in memory
FOR n := 1 TO LEN(aData) // scan and select data from array
// filter on array-data
oCust1:ORDSCOPE(0, NIL ) // reset
oCust1:ORDSCOPE(1, NIL ) // reset
oCust1:ORDSCOPE(0, aData[n][1] + aData[n][2] ) // set top scope from array
oCust1:ORDSCOPE(1, aData[n][1] + aData[n][2] ) // set bottom scope from array
oCust1:GoTop()
DO WHILE oCust1:EOF() = .F.
oCust1:DELETE() // delete filter-data
oCust1:Skip()
ENDDO
n++
NEXT
oCust1:ORDSCOPE(0, NIL ) // reset
oCust1:ORDSCOPE(1, NIL ) // reset
regards
Uwe
Uwe,
I tried
I have Tariffe.dbf indexed with UPPER(TAELEMENTO)+TASETTORE
cId:=adata[n][2] // taelemento
cSector:=adata[n][4] // tasettore
I made
Code: Select all
oTariffe:=TDatabase():Open( , cDir+"TARIFFE", "DBFCDX", .T. )
oTariffe:SetOrder( 1 ) // UPPER(TAELEMENTO)+TASETTORE
oTariffe:GoToP()
for n:= 1 to len(adata)
cId:=adata[n][2]
cSector:=adata[n][4]
oTariffe:ORDSCOPE(0, NIL ) // reset
oTariffe:ORDSCOPE(1, NIL ) // reset
oTariffe:ORDSCOPE(0, aData[n][2] + aData[n][4] ) // set top scope from array
oTariffe:ORDSCOPE(1, aData[n][2] + aData[n][4] )
oTariffe:GoTop()
DO WHILE oTariffe:EOF() = .F.
oTariffe:DELETE() // delete filter-data
oTariffe:Skip()
ENDDO
n++
NEXT
IT delete all as you can see here
while it must delete only the records have F and I on 7th column
to not delete all record I thinked to insert a LOGIC field TACANCEL and chabge this as
DO WHILE oTariffe:EOF() = .F.
// oTariffe:DELETE() // delete filter-data
oTariffe:tacancel:=.t.
oTariffe:save()
oTariffe:commit()
oTariffe:Skip()
ENDDO
Re: check on a archive from a array- resolved
Posted: Thu Jul 18, 2019 4:54 pm
by Silvio.Falconi
Perhaps Now I resolved
Code: Select all
oTariffe:=TDatabase():Open( , cDir+"TARIFFE", "DBFCDX", .T. )
oTariffe:SetOrder( 1 ) // UPPER(TAELEMENTO)+TASETTORE
oTariffe:GoToP()
for n:= 1 to len(adata)
cId:=adata[n][2]
cSector:=adata[n][4]
oTariffe:ORDSCOPE(0, NIL ) // reset
oTariffe:ORDSCOPE(1, NIL ) // reset
oTariffe:ORDSCOPE(0, aData[n][2] + aData[n][4] ) // set top scope from array
oTariffe:ORDSCOPE(1, aData[n][2] + aData[n][4] )
oTariffe:GoTop()
DO WHILE oTariffe:EOF() = .F.
// oTariffe:DELETE() // delete filter-data
oTariffe:tacancel:=.t.
oTariffe:save()
oTariffe:commit()
oTariffe:Skip()
ENDDO
n++
NEXT
Now I haveonly two the records with tacancel :=.t.
I must make an array with this filter and show it
then if the fina user confirm I can delete only the records having tacancel:= .t.
oTariffe:ORDSCOPE(0, NIL ) // reset
oTariffe:ORDSCOPE(1, NIL ) // reset
oTariffe:GoToP()
atemp:=oTariffe:FW_DbfToArray( cFieldList, { || oTariffe:TACANCEL=.t. } )
xbrowser atemp
Finally,
thanks to Uwe, I have an array with the records must be deleted !!!!