Exemplo de como criar filtros em banco de dados que funcionem rapidamente em Harbour/xHarbour
Vou apresentar alguns segmentos de códigos para tentar dar um panorama geral.
Vamos começar do início com as configurações iniciais:
*** SETs #INCLUDE "SET.CH" SET(_SET_MESSAGE, 23) SET(_SET_MCENTER, .F.) SET(_SET_EVENTMASK,159) // MOUSE NOS GETs SETMODE(43,80) SETMOUSE(.t.) SET SCOREBOARD OFF SET DATE BRITISH SET DELETED ON SET EPOCH TO YEAR(DATE())-50 // Bug do milênio SET MESSAGE TO 24 SET OPTIMIZE ON // compara valores armazenados no index ao invés do banco de dados SET TIME FORMAT TO "hh:mm" SET CONFIRM ON SET HARDCOMMIT OFF // É MELHOR DAR UM DBCOMMIT() NO FINAL DE CADA TAREFA SET WRAP ON
Para criar os bancos de dados com os índices DBFCDX e usar a acentuação de nosso idioma português:
*** DEFINIR TIPO DE BANCO DE DADOS: DBFCDX Nativo *** REQUEST DBFCDX REQUEST DBFFPT ANNOUNCE FPTCDX RDDSETDEFAULT("DBFCDX") RDDREGISTER( "DBFCDX", 1 ) // RDT_FULL SET AUTOPEN OFF *** DEFINIR IDIOMA PORTUGUÊS *** REQUEST HB_CODEPAGE_PT850 // PARA INDEXAR CAMPOS ACENTUADOS HB_SETCODEPAGE("PT850") // PARA INDEXAR CAMPOS ACENTUADOS
Depois do Clipper 5.2e eu passei a usar uma função para abrir os banco de dados sem problemas:
ABREDBF("ESTAGIO", "EST") EST->(ORDSETFOCUS("POSICAO")) ABREDBF("POSICAO", "POS") ABREDBF("PROCESSO", "PRO") ABREDBF("EMPRESAS", "EMP") ABREDBF("CADASTRO", "CRC") ABREDBF("UNIDADE", "UG")
Aqui vem o exemplo que mais uso, criar um índice temporário localmente com o filtro desejado. Eu uso a função RAN para criar um número aleatório (randômico) e não repetir os nomes de arquivos. Todavia, é sempre bom apagar esses arquivos temporários após o uso e, para não esquecer disso, já deixe o parâmetro "ADDITIVE TEMPORARY" para que ele se autodestrua após ser fechado.
SELECT PRO // FILTRA ABERTAS E FINALIZADAS NO EXERCÍCIO cRANDOM := ALLTRIM(STR(RAN(9999))) fINDEX := xTEMP+"TEMP" + cRANDOM INDEX ON MODALIDADE+ANO+STRZERO(NUMERO,3)+COMPL TAG TEMP TO (fINDEX) ; FOR ( DRESULTADO >= dINI .AND. DRESULTADO <= dFIM ) .OR. ; ( INICIO >= dINI .AND. INICIO <= dFIM ) ; ADDITIVE TEMPORARY PRO->(DBGOTOP()) // ATIVA FILTROS E RELAÇÕES MOVENDO O PONTEIRO DO REGISTRO PARA O INÍCIO
Espero que tenha como ter dado uma boa idéia geral de como fazer.
Já tem uma função para gerar números aleatórios na página de downloads, então só vou deixar aqui embaixo a função ABREDBF:
FUNCTION ABREDBF(cDBF, cALIAS, cINDEX) IF EMPTY(cINDEX) IF FILE(cDBF+INDEXEXT()) cINDEX := cDBF ENDIF ENDIF bORD := cALIAS + "->(INDEXORD())" bSETORD := cALIAS + "->(ORDSETFOCUS(1))" IF SELECT(cALIAS)=0 USE (cDBF) ALIAS (cALIAS) SHARED NEW IF !EMPTY(cINDEX) SET INDEX TO (cINDEX) ENDIF ELSEIF EVAL( { || &bORD } ) > 1 // CASO JA ESTEJA ABERTO, ASSEGURA QUE ESTÁ NA 1ª CHAVE DO INDICE EVAL( { || &bSETORD } ) ENDIF RETURN
USANDO SERVIDOR DE BANCO DE DADOS
Se você usar um servidor como o LETODBF lembre-se de que os DBFs vão rodar lá onde não enxergará as variáveis do programa, portanto há casos em que dará problema, por exemplo:
SELECT EMP cRANDOM1 := ALLTRIM(STR(RAN(9999))) fINDEX1 := xTEMP+"TEMP" + cRANDOM1 + INDEXEXT() INDEX ON CNPJ+ANO TAG TEMP TO (fINDEX1) ; FOR ANO=xANO ; ADDITIVE TEMPORARY
Na linha 5 acima a variável pública xANO não será enxergada pelo programa, pois não existe lá no lado do servidor, dando um erro de "váriável não existe".
Uma alternativa é utilizar as funções utilizadas no comando index que são OrdCondSet() + OrdCreate() diretamente.
LOCAL cKey, cFor ... cRANDOM1 := ALLTRIM(STR(RAN(9999))) fINDEX1 := xTEMP+"TEMP" + cRANDOM1 + INDEXEXT() cKey := "CNPJ+ANO" cFor := "ANO=" + STR(xANO,4,0) ordCondSet( cFor, &("{||"+ cFor +"}"), /*all*/, /*b_while*/, ; /*eval*/, /*every*/, RecNo(), /*next*/, /*rec*/, ; /*rest*/, /*descend*/, /*NIL*/, ; .T. /*add*/, /*cur*/, /*cust*/, /*noopt*/, ; /*c_while*/, .T. /*mem*/, /*filter*/, /*ex*/ ) ordCreate( fIndex1 /*bag*/, "TEMP" /*tag*/, cKey, &("{||"+ cKey +"}"), /*unique*/ )
Leia também: Como Agilizar o Tráfego da Rede no Clipper.
Comentários recentes