Como criar filtros rápidos em xBase/Clipper/Harbour

Foto de Anderson

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.

Total votes: 0