Amiguinho,
A SUBNTX trabalha em cima de um arquivo de indice, extraindo dele o conjunto de registro que voce selecionou, criando um arquivo de indice menor e ativando-o para uso.
Para usa-lo voce:
- Abre a tabela
- Seta os indices do arquivo
- Seleciona a ordem que voce deseja filtrar
- Usa SUBNTX para criar o filtro desejado
- Adiciona o novo indice aos ja abertos
- Usa browse ou dbEdit sobre o conjunto filtrado
Para ajuda-lo voce pode integrar algumas facilidades ao seu codigo:
Código: Selecionar todos
#command DELETE TAGS => F_Erase( "SUB*.NTX" )
#command ADD INDEX <SubIndex> => ordListAdd( <"SubIndex"> ) ;;
ordSetFocus( NDXCOUNT() )
#command RESET ORDER <order> => ordListReset( <order> )
Para o bom uso de SUBNTX voce de sempre eliminar os temporarios criados por ela.
ADD INDEX <SubIndex> vai adicionar o novo indices ao final dos indices da area aberta.
RESET ORDER <order> vai derrubar um indice da ordem e restabelece-la ao padrao.
As funcoes de apoio são:
Código: Selecionar todos
FUNCTION F_ERASE( ARQUIVOS )
CONTADOR := ADIR( ARQUIVOS )
IF CONTADOR != 0
DECLARE TXT_NOMES[ CONTADOR ]
ADIR( ARQUIVOS, TXT_NOMES )
FOR CONTADOR := 1 TO LEN( TXT_NOMES )
FERASE( TXT_NOMES[CONTADOR] )
NEXT
ENDIF
RETURN .T.
FUNCTION NDXCOUNT()
LOCAL counter
FOR counter = 1 TO 15
IF EMPTY(INDEXKEY(counter))
EXIT
ENDIF
NEXT
RETURN (counter-1)
FUNCTION ordList()
LOCAL counter
PUBLIC nomes_ndx := {}
FOR counter = 1 TO 15
IF EMPTY(INDEXKEY(counter))
EXIT
ENDIF
AADD(nomes_ndx,ORDNAME(counter))
NEXT
RETURN nomes_ndx
FUNCTION ordListReset( ord_number )
LOCAL counter, nomes_ndx := ordList()
if valtype(ord_number) = 'C'
ord_number := ordSetList( ord_number )
endif
ordListClear()
FOR counter = 1 TO len(nomes_ndx)
IF counter = ord_number
ELSE
ordListAdd(nomes_ndx[counter])
ENDIF
NEXT
RETURN .t.
FUNCTION ordSetList( O_R_DEM )
FOR counter = 1 TO 15
ordSFocus := counter
IF EMPTY(INDEXKEY(counter))
EXIT
ENDIF
IF UPPER(ALLTRIM(ORDNAME(counter))) = UPPER(ALLTRIM(O_R_DEM))
EXIT
ENDIF
NEXT
RETURN ordSFocus
O codigo exemplo:
Código: Selecionar todos
// Sample showing how to use SUBNTX with NTX indexes
#include "FiveWin.ch"
static oWnd, cTempo1, cTempo2, cName := "COMERC"
//----------------------------------------------------------------------------//
function Main()
DEFINE WINDOW oWnd FROM 1, 1 TO 20, 60 ;
TITLE "Sistema de Faturamento"
SET MESSAGE OF oWnd TO OemToAnsi( "5volution.com - (r) Jose Carlos da Rocha, 2004 - Brasil" )
ACTIVATE WINDOW oWnd ;
ON INIT ShowDlg()
return nil
//----------------------------------------------------------------------------//
function ShowDlg()
IF ! FILE("CLIENTES.DBF")
msgrun("CLIENTES.DBF nao encontrado!")
QUIT
ENDIF
USE CLIENTES
IF lastrec() < 75
EXPAND_DBF()
ENDIF
IF ! FILE("SUBDEMO.NTX")
//msgrun("WAIT. Creating file SUBDEMO.NTX...")
MsgMeter( { |oMeter,oText,oDlg,lEnd| ;
MakeIndex( oMeter, oText, oDlg, @lEnd, "CLIENTES->NOME+CLIENTES->ESTADO", "SUBDEMO.NTX", "" ) },;
"Creating index SUBDEMO.NTX..." )
ENDIF
msgwait("Primeiro. Mostro todo database...")
browse()
msgwait("Agora. Usando um simples SEEK...")
set index to SUBDEMO
go top
seek "5VOLUTION"
browse()
msgwait("Agora. Usando um simples SET FILTER...")
go top
seek "5vol"
msgwait("Observacao. Quando mover o cursor alem do browse o cursor se perde por muito tempo...")
msgwait("((provavelmente mais de um minuto)")
cTempo1 := time()
set filter to CLIENTES->NOME = "5VOLUTION"
go top
cTempo2 := time()
MsgAlert("Tempo de Operacao: "+tempo( cTempo1,cTempo2 )+" segundo(s)" )
browse()
set filter to
msgwait("E AGORA. Usando SUBNTX...")
nString := 1
do while .t. //cName <> "exit"
if MsgGet( "Digite uma frase:",; // Title
"Nome:",; // Label
@cName ) // A variable by reference
set index to
cTempo1 := time()
//
num = subntx( "SUBDEMO.NTX", "_SUB.NTX", cName )
//
cTempo2 := time()
if ! FILE("_SUB.NTX")
msgwait("Nenhum filtro foi gerador...")
else
set index to _sub
//MsgAlert("Tempo de Operacao: "+tempo( cTempo1,cTempo2 )+" segundo(s)" )
browse()
endif
nString := nString + 1
do case
case nString = 2
cName := "SA"
case nString = 3
cName := "JOS"
case nString = 4
cName := "W"
case nString = 5
cName := "BE"
case nString = 6
cName := "PANI"
otherwise
msgwait("Eu gosto disto. Obrigado...")
quit // exit
endcase
set index to
erase _sub.ntx
else
exit
endif
enddo
close databases
return nil
//----------------------------------------------------------------------------//
function EXPAND_DBF
msgrun("STAND BY while expanding CLIENTES.DBF...")
ERASE SUBDEMO.NTX
COPY TO _SUBTMP
FOR i = 1 to 49
APPEND FROM _SUBTMP
NEXT
ERASE _SUBTMP.DBF
REPLACE ALL REC WITH RECNO()
return nil
//----------------------------------------------------------------------------//
function tempo( inicio, final )
return str(val(strtran(substr(final,4,5),":",""))-val(strtran(substr(inicio,4,5),":","")),6)
//----------------------------------------------------------------------------//
function MakeIndex( oMeter, oText, oDlg, lEnd, cChave, cIndex, cFor )
FIELD Last
oMeter:nTotal = RecCount()
IF EMPTY( cFor )
INDEX ON &(cChave) TO &(cIndex) ;
EVAL ( oMeter:Set( RecNo() ), SysRefresh(), ! lEnd )
ELSE
INDEX ON &(cChave) TO &(cIndex) FOR &(cFor) ;
EVAL ( oMeter:Set( RecNo() ), SysRefresh(), ! lEnd )
ENDIF
return nil