Clipper On Line • Ver Tópico - LENTIDAO PARA PESQUISAR DBF EM HARBOUR

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Projeto Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

 

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor Itamar M. Lins Jr. » 17 Fev 2020 18:11

Ola!
REQUEST HB_LANG_PT
REQUEST HB_CODEPAGE_PT850

Function Main()  //no PRG principal (inicial) tem que ter esta funcao MAIN
LOCAL xTem, cPesq, xTot, t1, t2, GetList := {}

SET(40,159)

SetMode( MaxRow() + 1, MaxCol() + 1 )  //tamanho da janela (linhas/colunas)

CLS
CLOSE ALL

*********** so pra deixar vazio !!
USE prod
ZAP
CLOSE

use produto new
IF ! FILE ("acess.ntx") .OR. !FILE("edup.ntx")
INDEX ON field->CODIGO TO acess
INDEX ON field->DESCRICAO TO edup
ENDIF
SET INDEX TO acess, edup

use prod new

DO WHILE .T.
cPESQ=SPACE(30)
@10,10 SAY "PESQUISA ..: " GET cPESQ PICTURE [@K!]
READ

IF LASTKEY()=27
   EXIT
ENDIF

T1=TIME()
xTOT=0
xTEM=0

SELECT PRODUTO
SET ORDER TO 2
GO TOP
DO WHILE !EOF()
   xTEM++
   IF ALLTRIM(cPESQ) $ PRODUTO->DESCRICAO   //procuro primeiro parte no nome
      xTOT++

      SELECT PROD
      DBAPPEND()
      REPLACE PROD->CODIGO WITH PRODUTO->CODIGO, PROD->DESCRICAO WITH PRODUTO->DESCRICAO,;
              PROD->PRECOVENDA WITH PRODUTO->PRECOVENDA, PROD->ESTOQUE WITH PRODUTO->ESTOQUE

   ENDIF
/*
*/
  SELECT PRODUTO
  SKIP
ENDDO
T2=TIME()

@15,10 SAY xTOT
@15,25 SAY xTEM

@18,10 SAY T1
@19,10 SAY T2
ENDDO

return nil

Captura de tela de 2020-02-17 18-07-21.png
No "celelon" veinho com @ say, depois do "Do While"
Linux wins!


Saudações,
Itamar M. Lins Jr.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6959
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 312 vezes
Mens.Curtidas: 508 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor JoséQuintas » 17 Fev 2020 18:20

Sem índice vai ser mais rápido, índice e OrdWildSeek() vai ser mais rápido porque não vai nem usar o o DBF.
Mas no momento, tudo tem a ver com ficar mostrando a cada registro em tela gráfica e não console igual no Clipper.

Talvez até no Clipper seja mais rápido sem mostrar processamento.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18158
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor JoséQuintas » 17 Fev 2020 18:36

test5.png
test5.png (10.18 KiB) Visualizado 3091 vezes


TODOS os meus testes foram com GTWVG.
O primeiro, mostrando andamento, demorou cerca de 3 segundos.

Neste último usei hb_DateTime(), só pra mostrar milésimos de segundo.
Praticamente um décimo de segundo, 0,109 segundos

Fonte original do Clipper, apenas comentados os @SAY intermediários neste último.
Reduziu de 3 segundos para 1/10 segundo.

Acabo de lembrar de outra coisa:
Como tem a ver com atualização de tela, placas gráficas mais lentas podem demorar muito mais.
E se tiver warsaw (segurança de banco) que se intromete até em atualização de tela... aí danou-se...

No final, acho que este tópico acabou levantando um assunto importantíssimo, principalmente pra quem ainda usa console, ou está começando a usar Harbour/XHarbour.
O mais comum é mesmo colocar algum indicativo de processamento, e precisa tomar cuidado com isso.
E não menos importante: GTWVG, GTWVW e GTWVT NÃO SÃO CONSOLE, nelas essa diferença fica mais visível ainda, porque é forçada a atualização do texto na tela gráfica.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18158
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor EduardoSPno » 17 Fev 2020 19:12

Quintas e Itamar, MOSTROS !!!!!

Puxa, coisa basica, eu coloquei o @say para poder ver o processamento, mas nunca pensei que ele ficava ATUALIZANDO A TELA, retirei conforme os mestres disseram e bala 1 no maximo 2 seg.

Vou testar em rede no cliente e volto aqui para finalizar ...

REQUEST HB_GT_WVT_DEFAULT
REQUEST HB_GT_WVT
esses caras aqui de cima tornan-se desnecessários??
se possivel, olhem o exemhar.prg ... por favor ...

Muito obrigado AMIGOS ...
EduardoSPno
Usuário Nível 2

Usuário Nível 2
 
Mensagens: 59
Data de registro: 03 Mai 2012 16:23
Cidade/Estado: Sao Paulo/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor EduardoSPno » 17 Fev 2020 19:13

corrigindo, MONSTROS !!!!!
EduardoSPno
Usuário Nível 2

Usuário Nível 2
 
Mensagens: 59
Data de registro: 03 Mai 2012 16:23
Cidade/Estado: Sao Paulo/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor JoséQuintas » 18 Fev 2020 00:50

Pra usar GTWVG, basicamente é isto:

PROCEDURE HB_GTSYS()

   REQUEST HB_GT_WVG_DEFAULT

   RETURN


e compilar usando hbmk2 projeto.hbp gtwvg.hbc
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18158
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor JoséQuintas » 18 Fev 2020 08:19

Só reforçando o anterior da GTWVG:

HB_GTSYS é executado ao carregar o EXE, e assume uma GT - uma LIB pra tela.

Depois, como primeira coisa no programa:

SetMode(25,80)
CLS

A partir daí o aplicativo tem tela/janela.
Se não tiver janela, não vai ter nem aonde mostrar mensagem de erro, por isso é importante forçar a criação da janela.

Depois disso só vai acrescentar alguma coisa diferente se quiser recurso adicional, e se o recurso adicional exigir alguma coisa.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18158
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor EduardoSPno » 18 Fev 2020 20:03

Amigos Quintas e Itamar, mais uma pra ver no que eu estou errando, a pesquisa quando eh no proprio computador esta 10, rapidinho, graças a dica do @say, mas quando faço a pesquisa de um outro micro pela rede, ai q mora o problema.

Explicando:
Se no servidor, nao estou usando o BD, o terminal roda rapidinho
Se no servidor estou usando o BD, o terminal fica bem lento

Estou postando os fontes e no PRG o exemplo, acho que tem algo errado na rotina do REDE.PRG, peço muito a ajuda de vc´s pra resolver esse problema

Desde já, muito grato !!
Anexos
FILTRO.rar
FONTES E BD
(1.81 MiB) Baixado 135 vezes
EduardoSPno
Usuário Nível 2

Usuário Nível 2
 
Mensagens: 59
Data de registro: 03 Mai 2012 16:23
Cidade/Estado: Sao Paulo/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor Itamar M. Lins Jr. » 18 Fev 2020 20:50

Ola!
E usando o clipper fica como ?
Vc está copiando o DBF com 22 mil itens na rede do servidor para estação e vice versa.
Tem uns ajustes já postados aqui outras vezes para fazer no registro do windows.
http://www.pctoledo.com.br/forum/viewtopic.php?f=4&t=11325&hilit=win_osnetregok
//Paliativo, tem que rodar com direitos de admin
IF !win_osnetregok()
  IF !win_osnetregok(.t.,.t.)
     alert("O registro não foi ajustado.")
  ENDIF
ENDIF


Porém vc deve começar a estudar como instalar e o usar o LetoDBf e os recursos ordwildeek..., index temporary...
Com o LetoDbf vc usa arquitetura cliente/servidor igual ao ADS.
Procure no forum, tem muitos tópicos, na seção de Banco de Dados.

Saudações,
Itamar M. Lins Jr.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6959
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 312 vezes
Mens.Curtidas: 508 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor EduardoSPno » 18 Fev 2020 21:48

Ola Itamar!!

Usando o clipper de boa, sem problemas, isso que achei estranho, mas não faço a copia do dbf para outro terminal, como coloquei no exemplo eu faço o mapeamento e puxo como SET DEFAULT TO Z:\TESTE (onde z: eh o hd do servidor e TESTE a pasta onde estão os dbf´s

Vc teria algum exemplo mais simples sobre o LetoDbf (pelo que vi ele se adapta legal ao Harbour

Muito obg
EduardoSPno
Usuário Nível 2

Usuário Nível 2
 
Mensagens: 59
Data de registro: 03 Mai 2012 16:23
Cidade/Estado: Sao Paulo/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor JoséQuintas » 19 Fev 2020 08:04

EduardoSPno escreveu:Explicando:
Se no servidor, nao estou usando o BD, o terminal roda rapidinho
Se no servidor estou usando o BD, o terminal fica bem lento


- É normal em rede ficar mais lento, mas não porque tá rodando no servidor, exceto Clipper
- Usuários já relataram que NTX fica muito mais lento em rede do que CDX.

Se está se referindo a usar um programa Clipper no servidor, recomendo compilar esse programa Clipper usando OSLIB, e colocando na primeira linha do fonte OL_AutoYield(.T.)

Verifique se quando seu programa está carregado no servidor, se ele está ocupando muito tempo de CPU.
Isso era normal no Clipper, porque o Clipper roubava 100% de CPU, e não sobrava tempo pro Windows trabalhar.
No Harbour, ele tem tratamentos melhores pra isso, mas em certas situações precisa ajuda do programador..

O teste simples pra decidir se o problema é NTX, é testar fazer a pesquisa sem índice nenhum.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18158
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor EduardoSPno » 19 Fev 2020 08:22

Amigo Kapiaba, gostaria de saber a respeito do seu POST, me perdoe por não entender, mas essas opções aceleram a busca no BD??

O RDDSYS e DBFNTX??

// CABECALHO(s)
ANNOUNCE RDDSYS
REQUEST DBFNTX

FUNCTION FILTRO()
CLS
CLOSE ALL
//********** so pra deixar vazio !!
USE PROD EXCLUSIVE NEW
ZAP
CLOSE

RDDSETDEFAULT("DBFNTX")

IF ABREARQ( "PRODUTO", "PRODUTO", .F. , 10 )
IF .NOT. FILE ( "ACESS.NTX" ) .OR. .NOT. FILE( "EDUP.NTX" )
INDEX ON CODIGO    TO ACESS
INDEX ON DESCRICAO TO EDUP
ENDIF
SET INDEX TO ACESS, EDUP
ELSE
ALERT( "N„o foi poss¡vel abrir o arquivo de Produtos" )
ENDIF
EduardoSPno
Usuário Nível 2

Usuário Nível 2
 
Mensagens: 59
Data de registro: 03 Mai 2012 16:23
Cidade/Estado: Sao Paulo/SP
Curtiu: 0 vez
Mens.Curtidas: 1 vez

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor Kapiaba » 19 Fev 2020 10:42

Bom dia Eduardo, na verdade, os indices *.NTX, são do velho CLIPPER SUMMER 87, portanto LENTOS., Altamente recomendado,
que você comece a usar, indices .CDX, super rápidos e de uso muito simples. Dúvidas, pergunte a vontade.
Eu prefiro mostrar via programa/módulo fica mais didático. você também pode consultar em: www.fivewin.com.br

// Esta em: C:\FWH..\SAMPLES\EDUARDO.PRG - 19/02/2020 - kapiabafwh@gmail.com

// CABECALHO(s)

ANNOUNCE RDDSYS

REQUEST DBFCDX, DBFFPT // USO DE MEMO

FUNCTION Main()  // MENU PRINCIPAL - CONFIGURACAO PERFEITA PARA XHARBOUR/CDX.

   /*
   // VARIAVEIS DO SISTEMA.
   LOCAL
   GLOBAL... VIDE EXEMPLOS DO XHARBOUR.
   MEMVAR
   PRIVATE
   PUBLIC
   */

   RDDSETDEFAULT("DBFCDX")

   SET CENTURY ON
   SET DATE BRITISH
   SET TIME FORMAT TO "HH:MM:SS"
   SET EPOCH TO YEAR( DATE() ) - 30
   SET SOFTSEEK OFF
   SET WRAP ON
   SETCANCEL( .F. )
   SET CONFIRM OFF
   SET DELETED ON
   SET ESCAPE OFF
   SET EXACT ON
   SET EXCLUSIVE OFF
   SET MULTIPLE OFF

   HB_LANGSELECT( 'PT' )     // Default language is now Portuguese
   HB_SETCODEPAGE( "PT850" )

   // SEU MENU DE DISPAROS PARA OS MODULOS AUXILIARES...

RETURN NIL
//-> IDENTADO POR: HBFORMAT.EXE DO XHARBOUR. C:\XHARBOUR\BIN\HBFORMAT.EXE
FUNCTION Filtro()  // chamado do MENU PRINCIPAL

   FIELD CODIGO, DESCRICAO

   CLS
   CLOSE ALL

   //********** so pra deixar vazio !!
   USE PROD EXCLUSIVE NEW  // SHARED -> EM REDE.
   ZAP
   CLOSE

   // CRIE UM MODULO, SOMENTE PARA INDEXACAO DE TODOS OS BANCOS.
   // EVITE INDEXAR NO PROPRIO MODULO DE TRABALHO. EX.: REINDEXA.PRG
   IF ABREARQ( "PRODUTO", "PRODUTO", .F. , 10 ) // COMPARTILHADO E .T.??

   // REVEJA ESSA ROTINA ABREARQ.PRG, TEM FORMAS MAIS MODERNAS DE ABERTURA.

      // USANDO *.CDX
      IF .NOT. FILE ( "PRODUTO.CDX" ) // MESMO NOME DO .DBF, FACILITA A VIDA.

         /* INDICE NTX, MUITO VELHO E LENTO. -> CLIPPER SUMMER 87
         INDEX ON CODIGO    TO ACESS
         INDEX ON DESCRICAO TO EDUP
         */

         // CLIPER 5.2D OU CLIPPER 5.3 SE NAO ME FALHA A MEMORIA.
         INDEX ON CODIGO    TAG 01 TO PRODUTO FOR .NOT. DELETED() EVERY 10
         INDEX ON DESCRICAO TAG 02 TO PRODUTO FOR .NOT. DELETED() EVERY 10

         // INDEX ON PRECO TAG 03 TO PRODUTO FOR !DELETED() EVERY 10
         // VOCE PODE CRIAR EM UM UNICO *.CDX, ATE 50 TAGS E CHAMA-LAS EM
         // TEMPO REAL EM QUALQUER MODULO DO SEU SISTEMA.

      ENDIF

      // SET INDEX TO ACESS, EDUP  // NTX - LENTO E VELHO DO SUMMER 87.

      SET ORDER TO 01 // POR CODIGO. CDX MUITO RAPIDO.

      // SET ORDER TO 02 // POR NOME/DESCRICAO, ETC.

   ELSE

      ALERT( "N„o foi poss¡vel abrir o arquivo de Produtos" )

   ENDIF

   /* // DESNECESSARIO PARA INDICES *.CDX, TODOS NO MESMO .CDX.
   IF ABREARQ( "PROD", "PROD", .F. , 10 )

   ELSE

      ALERT( "N„o foi poss¡vel abrir o arquivo de Produtos" )

   ENDIF
   */

   DO WHILE .T.

      cPESQ = SPACE( 30 )
      @10, 10 SAY "PESQUISA ..: " GET cPESQ PICTURE [@K!]
      READ

      IF LASTKEY() = 27
         EXIT
      ENDIF

      T1 = TIME()

      xTOT = 0
      xTEM = 0

      SELECT PRODUTO
      SET ORDER TO 2  // POR DESCRICAO
      GO TOP

      DO WHILE !EOF()

         xTEM++

         IF ALLTRIM( cPESQ ) $ PRODUTO->DESCRICAO   //procuro primeiro parte no nome

            // xTOT++  // incrementa o total

            // SELECT PROD // COM CDX, NAO NECESSITA, POIS JA ESTA ABERTO.
                           // VOCE PODE TROCAR A TAG, EM TEMPO REAL.

            DBAPPEND()

            RLOCK()  // EM REDE, TRAVE O REGISTRO.

            REPLACE CODIGO     WITH PRODUTO->CODIGO,     ;
                    DESCRICAO  WITH PRODUTO->DESCRICAO,  ;
                    PRECOVENDA WITH PRODUTO->PRECOVENDA, ;
                    ESTOQUE    WITH PRODUTO->ESTOQUE

            COMMIT  // USE SEMPRE, POIS O WINDOWS "SEGURA" O REPLACE.

            xTOT++  // incrementa o total nao deveria ser aqui?

         ENDIF

         @15, 10 SAY xTOT
         @15, 25 SAY xTEM

         // SELECT PRODUTO  // COM CDX, NAO NECESSITA, POIS JA ESTA ABERTO.
                            // VOCE PODE TROCAR A TAG, EM TEMPO REAL.

         SKIP

      ENDDO

      UNLOCK  // DESTRAVE O REGISTRO AO TERMINO.

      T2 = TIME()

      @18, 10 SAY T1
      @19, 10 SAY T2

   ENDDO

RETURN NIL

// FIM DO PROGRAMA - Modificado por: kapibafwh@gmail.com


Abs.
Kapiaba
Colaborador

Colaborador
 
Mensagens: 1766
Data de registro: 07 Dez 2012 15:14
Cidade/Estado: São Paulo
Curtiu: 311 vezes
Mens.Curtidas: 119 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor Kapiaba » 19 Fev 2020 10:46

Eduardo:
Se nao entender espanhol, use o tradutor do google, ou pergunte aos demais.

 INDEX 
Crea un fichero índice
------------------------------------------------------------------------------
Sintaxis

     INDEX ON <expClave> [TAG <cNombreOrden>] [TO <cNombreContOrden>]
        [FOR <lCondición>] [ALL]
        [WHILE <lCondición>] [NEXT <nNúmero>]
        [RECORD <nRegistro>] [REST]
        [EVAL <bBloque>] [EVERY <nIntervalo>]
        [UNIQUE] [ASCENDING|DESCENDING]
        [USECURRENT] [ADDITIVE]
        [CUSTOM] [NOOPTIMIZE]

     Nota: Aunque las cláusulas TAG y TO son opcionales, se debe
     especificar al menos una de ellas.

Argumentos

     <expClave> es una expresión que devuelve el valor clave que se debe
     guardar en el índice por cada registro del área de trabajo actual.
     <expClave> puede ser de tipo carácter, fecha, lógico o numérico. La
     longitud máxima de una expresión clave de índice depende del
     controlador.

     TAG <cNombreOrden> es el nombre del orden que se va a crear.
     <cNombreOrden> puede ser cualquier expresión que se evalúe como una
     cadena constante de caracteres.

     TO <cNombreContOrden> es el nombre de un fichero en disco que
     contiene uno o más órdenes. El RDD activo determina la capacidad de un
     contenedor de órdenes. El controlador por defecto, DBFNTX, sólo admite
     contenedores con un único orden, mientras que otros RDD soportan
     contenedores de múltiples órdenes (p.e. los controladores DBFCDX y
     DBFMDX). La vía o la extensión del nombre del fichero es opcional. Si
     no se incluye extensión, CA-Clipper utiliza la extensión por defecto
     del RDD actual.

     Aunque las cláusulas TAG y TO son opcionales, se debe especificar al
     menos una de ellas.

     FOR <lCondición> especifica el conjunto condicional de registros
     sobre el que se va a crear el orden. Sólo se incluyen en el orden
     resultante los registros que cumplan la condición. Cuando se utilizan
     los controladores DBFNTX y DBFNDX, la expresión <lCondición> no puede
     superar los 250 caracteres. El valor máximo de estas expresiones
     depende del RDD. La condición FOR se almacena como parte del contenedor
     de órdenes y se utiliza al actualizar o volver a crear el índice con el
     mandato REINDEX. Los valores duplicados de una clave no se añaden al
     contenedor de órdenes.

     La utilización de la cláusula FOR en controladores que no la admitan
     produce un error.

     La cláusula FOR proporciona el único ámbito en el que se reflejan
     automáticamente todos los cambios que se producen en la base de datos.
     Las demás condiciones de ámbito crean órdenes que no reflejan las
     actualizaciones de las bases de datos.

     ALL especifica todos los órdenes del área de trabajo actual o de la
     especificada. ALL es el ámbito por defecto de INDEX.

     WHILE <lCondición> especifica otra condición que deben cumplir
     todos los registros para ser procesados. Cuando se encuentra un
     registro que no cumple la condición, el mandato INDEX termina. Si se
     especifica una cláusula WHILE, los datos se procesan en el orden de
     control. La condición WHILE es temporal (es decir, no se guarda en el
     fichero y no se utiliza para actualizar o volver a crear índices con
     REINDEX). La cláusula WHILE crea órdenes temporales que no son
     actualizados.

     La utilización de la cláusula WHILE en controladores que no la admitan
     produce un error.

     La cláusula WHILE es más rápida y eficaz que la cláusula FOR. WHILE
     sólo procesa datos para los que la condición <lCondición> toma el valor
     verdadero (.T.) desde la posición actual. Sin embargo, la cláusula FOR
     procesa todos los datos de la fuente de datos.

     NEXT <nNúmero> especifica la porción de la base de datos que se va
     a procesar. Si se especifica NEXT, se procesan <nNúmero> de identidades
     de la base de datos en el orden de control. El ámbito es temporal (es
     decir, no se guarda en el orden ni se utiliza para actualizar o volver
     a crear índices con REINDEX).

     RECORD <nRegistro> especifica el registro que se va a procesar.

     REST especifica el proceso de todos los registros desde la posición
     actual del puntero de registro al final del fichero (EOF).

     EVAL <bBloque> evalúa un bloque de código cada cierto intervalo
     <nIntervalo>, donde <nIntervalo> es el valor especificado en la
     cláusula EVERY. El valor por defecto es 1. Esta cláusula ofrece una
     forma flexible de supervisar el progreso de la operación de indexación
     mediante una barra de estado o de progreso. El valor devuelto por
     <bBloque> debe ser de tipo de datos lógico. La indexación se detiene si
     <bBloque> devuelve el valor falso (.F.).

     EVERY <nIntervalo> es una cláusula que contiene una expresión
     numérica que modifica la frecuencia con la que se evalúa el <bBloque>
     de la cláusula EVAL. Cuando se utiliza la cláusula EVAL, la opción
     EVERY ofrece una mejora en el funcionamiento, al permitir evaluar la
     condición cada n registros en vez de en todos los registros. La palabra
     clave EVERY se ignora si no se especifica una condición EVAL.

     UNIQUE especifica que el valor clave de cada registro insertado en
     el orden es único. Los valores duplicados de claves no se añaden al
     orden.

     ASCENDING especifica que las claves de índice y sus datos asociados
     se clasifican en orden ascendente. Si no se especifica ASCENDING o
     DESCENDING, se supone ASCENDING. Aunque no se almacena como parte
     explícita del fichero, ASCENDING es un atributo implícito del fichero
     para el mandato REINDEX.

     La utilización de la condición ASCENDING en controladores que no la
     admitan produce un error. Las palabras clave siguientes se han
     incorporado a CA-Clipper 5.3.

     DESCENDING especifica que las claves del índice y sus datos
     asociados se clasifican en orden descendente. Utilizar esta palabra
     clave tiene el mismo efecto que especificar la función DESCEND() dentro
     de <expClave>, pero evita la disminución de velocidad durante las
     actualizaciones de índices. Si crea un índice DESCENDING, no necesitará
     utilizar la función DESCEND() durante un SEEK. DESCENDING es un
     atributo del fichero que se almacena para que pueda utilizarlo
     REINDEX.

     La utilización de la condición DESCENDING en controladores que no la
     admitan produce un error.

     USECURRENT especifica que sólo se incluirán en el orden los
     registros del orden de control comprendidos en el intervalo establecido
     por ORDSETSCOPE(). Se utiliza cuando se ha creado previamente un orden
     condicional y se quiere reordenar los registros que cumplan una
     condición, y/o para limitar el número de registros del orden a aquellos
     que cumplan una condición. Si no se especifica, se incluyen en el orden
     todos los registros de la base de datos.

     ADDITIVE especifica que no se deben cerrar los órdenes abiertos. Si
     no se especifica, todos los órdenes abiertos se cierran antes de crear
     el nuevo. Observe, no obstante, que el fichero índice de producción
     nunca se cierra.

     CUSTOM especifica que se creará un orden personalizado vacío en
     aquellos RDD que lo admitan. Del mantenimiento del orden personalizado
     se debe encargar el desarrollador e inicialmente está vacío. El sistema
     no añade ni borra claves de forma automática. Para realizar estas
     tareas deben utilizarse las funciones ORDKEYADD() y ORDKEYDEL(). Esta
     cláusula es muy adecuada para generar listas de valores posibles de
     registros y otras aplicaciones personalizadas.

     NOOPTIMIZE especifica que no se optimizará la condición FOR. Si no
     se especifica, la condición FOR se optimiza en aquellos RDD que lo
     admitan.

Descripción

     El mandato INDEX añade un conjunto de pares de clave ordenados por
     <expClave> a un fichero especificado por <cNombreContOrden>, utilizando
     la base de datos abierta en el área de trabajo actual.

     En RDD que admitan índices de producción o estructurales (p. e. DBFCDX,
     DBFMDX), al especificar un tag pero no un contenedor de órdenes, se
     crea el tag y se añade al contenedor de órdenes. Si no existe ningún
     Ã­ndice de producción o estructural, se creará uno para añadirle el
     tag.

     Al utilizar un RDD que admita contenedores con varios órdenes, se debe
     establecer explícitamente el orden de control deseado utilizando SET
     ORDER (o ORDSETFOCUS()). Si no se especifica un orden de control, el
     fichero de datos se procesará en el orden natural.

     Si <cNombreContOrden> no existe, se crea de acuerdo a los criterios del
     RDD del área de trabajo actual o de la especificada.

     Si <cNombreContOrden> existe y el RDD determina que los contenedores de
     Ã³rdenes sólo admiten un orden, se vacía <cNombreContOrden> y se añade
     el nuevo orden tanto al contenedor de órdenes como a la lista de
     Ã³rdenes del área de trabajo actual o de la especificada.

     Si <cNombreContOrden> existe y el RDD determina que los contenedores de
     Ã³rdenes pueden tener varios tags, se crea <cNombreOrden>, si todavía no
     existe; de lo contrario, se cambia <cNombreOrden> en <cNombreContOrden>
     y se añade a la lista de órdenes del área de trabajo actual o de la
     especificada.

     Las cláusulas ASCENDING o DESCENDING especifican la ordenación de los
     pares de clave. Si no se especifica ninguna de ellas, se toma ASCENDING
     por defecto.

     Si se especifica la cláusula UNIQUE, el orden resultante sólo contendrá
     registros con clave única. Algunos RDD sólo permiten una referencia a
     un valor clave, obviando todas las demás. Otros, al intentar añadir una
     clave repetida, producen un error recuperable en ejecución.

     La cláusula EVAL permite especificar un bloque de código que se evalúa
     cada vez que se inserta un registro en el orden. La cláusula EVERY
     permite modificar la frecuencia con la que se llama a <bBloque>. En
     lugar de evaluar la condición para cada registro que se inserta en el
     orden, se evalúa cada <nIntervalo> de registros que se incorporan al
     orden.

     El mandato INDEX contiene algunas cláusulas que permiten crear órdenes
     condicionales y parciales. Algunos órdenes se mantienen durante toda la
     vida de la aplicación, otros se consideran "temporales".

     La cláusula FOR proporciona el único orden cuyo ámbito es permanente y
     se mantiene a lo largo de toda la vida de la aplicación. La cadena de
     caracteres que se le pasa a la condición FOR se almacena dentro del
     orden para utilizarla, más tarde, en su mantenimiento. Aunque los
     Ã³rdenes creados con esta cláusula sólo acceden a una parte de la base
     de datos, existen mientras la base de datos esté activa. La cláusula
     FOR permite crear órdenes con ámbito permanente.

     Las cláusulas WHILE, NEXT, REST y RECORD procesan datos a partir de la
     posición actual del cursor de la base de datos en el área de trabajo
     por defecto o en la especificada. Si se declaran estas cláusulas, la
     lista de órdenes permanece abierta y se utiliza el orden activo para
     organizar la base de datos mientras se está creando. Estas cláusulas le
     permiten crear órdenes temporales (sin ámbito permanente) que contienen
     registros para los que <lCondición> toma el valor verdadero (.T.).

Notas

     Soporte de los RDD:  Algunos RDD no soportan totalmente todos los
     aspectos del mandato INDEX. Si desea obtener información acerca de un
     RDD, consulte el capítulo "Arquitectura de los Controladores de Base de
     Datos Sustituibles" en la Guía de Controladores.

Ejemplos

     Â¦ Este ejemplo crea un orden sencillo (índice) basado en el
        campo Cantidad:

        USE Cliente NEW
        INDEX ON Cliente->Cantidad TO CliCant

     Â¦ Este ejemplo crea un orden condicional (índice) basado en una
        cláusula FOR. El índice contendrá sólo aquellos registros cuyo campo
        FechaExp contenga una fecha posterior o igual al 1 de enero de
        1995:

        USE Factura NEW
        INDEX ON Factura->FechaExp       ;
           TO FactFech       ;
           FOR (Factura->FechaExp >= CTOD("01/01/95"))

     Â¦ Este ejemplo crea un orden en un contenedor con varios órdenes
        (es decir, un tag en un índice que puede soportar varios tags en un
        fichero de índice):

        USE Cliente NEW
        INDEX ON Cliente->Cantidad TAG CliCant TO Cliente

     Â¦ El ejemplo siguiente crea un orden que llama a la rutina
        MiFuncion durante su creación:

        #define INCREMENTO 10
        USE Cliente NEW
        INDEX ON cliente->Cuenta TO CliCuent EVAL;
              {MIFUNCION() } EVERY INCREMENTO

        FUNCTION MIFUNCION()

           STATIC nRegProces := 0

           nRegProces += INCREMENTO
           ? ( nRegProces/LASTREC() ) * 100

           RETURN (.T.)

Ficheros    La biblioteca asociada es CLIPPER.LIB

To download this example - click here.

See Also:
   CLOSE
   DBCREATEIND()
   DBORDERINFO()
   DBREINDEX()


abs.
Kapiaba
Colaborador

Colaborador
 
Mensagens: 1766
Data de registro: 07 Dez 2012 15:14
Cidade/Estado: São Paulo
Curtiu: 311 vezes
Mens.Curtidas: 119 vezes

LENTIDAO PARA PESQUISAR DBF EM HARBOUR

Mensagempor Kapiaba » 19 Fev 2020 10:52

Eduardo, veja esse exemplo para abertura de bancos de dados. Se gostar, adapte para o seu gosto pessoal.

// ------------------------------------------------------------------------
// Programa ..: REDE.PRG
//
// Descri‡Æo..: Fun‡äes de usuario (UDF) para Rede.
//
// Autor .....: Aulaware - A. Canudas
//
// Fun‡äes      Comentarios
// ------------ -----------------------------------------------------------
// NetUse       Abre Uma Tabela em Rede.
// NetCloseAll  Fecha Uma Tabela em Rede.
// NetFileLock  Bloqueia uma tabela aberta e compartilhada.
// NetRecLock   Bloqueio de registros em Rede.
//
// Datas        Comentarios
// ------------ -----------------------------------------------------------
// Maio, 2000
// ------------------------------------------------------------------------

#Include "Vendas.Ch"

// ------------------------------------------------------------------------
// Fun‡Æo.....: NetUse
// Descri‡Æo..: Abre um Arquivo DBF, em modo EXCLUSIVE (.F.), ou SHARED (.T.)
// Par metros : cDbf      -> Nome da Base de Dados
//              lShared   -> SHARED (.T.), EXCLUSIVE (.F.)
// Devolve ..: .T.       -> Si se ha podido abrir.
//             .F.       -> Si no se ha podido abrir.
// ------------------------------------------------------------------------

FUNCTION NetUse( cDbf, lShared )

   LOCAL cAlias := cFileName( cDbf )
   LOCAL bAlias := cFileName( cDbf )

   // CONTROLE DE PARAMETROS DE ENTRADA =====================
   If cDbf = NIL .OR. !File( cDbf + ".DBF" )
      MsgStop( "NOME DO ARQUIVO INCORRETO" + CRLF + CRLF + ;
               "NÃO ACHEI BANCO DE DADOS." + CRLF + CRLF + ;
               cDbf + ".DBF", "ERRO FATAL!!" )
      RETURN( .F. )
   ENDIF

   IIf( lShared = NIL, lShared := .F., lShared )
   // ======================================================

   IF lShared = .T.
      USE ( cDbf ) ALIAS ( cAlias := GetNewAlias( cAlias ) ) ;
      VIA "DBFCDX" SHARED NEW
   ELSE
      USE ( cDbf ) ALIAS ( cAlias ) VIA "DBFCDX" EXCLUSIVE NEW
   ENDIF

   IF !NetErr()
      RETURN( .T. )
   ENDIF

   // Se nÆo podemos abrir, solicita repeti‡Æo
   MsgStop( "IMPOSSIVEL ABRIR BANCO DE DADOS: " + cAlias + CRLF + ;
            OemToAnsi( "BLOQUEADO POR OUTRO USUµRIO." ), ;
            "ERRO FATAL DE REDE! FECHAR BANCO DE DADOS." )

RETURN( .F. )

// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
// Funci¢n ...: NetCloseAll
// Descripci¢n: Libera todos los ficheros, vuelca posibles datos de memoria
//              a disco duro, y cierra todos los ficheros.
// Par metros : Ninguno.
// Devolve ..: NIL
// ------------------------------------------------------------------------
FUNCTION NetCloseAll()

   DbUnLockAll()
   DbCommitAll()
   DbCloseAll()

RETURN NIL
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
// Funci¢n ...: NetFileLock
// Descripci¢n: Bloquea un fichero DBF.
// Par metros : Ninguno.
// Devolve ..: .T. -> Si se ha podido bloquear.
//              .F. -> Si no se ha podido bloquear.
// ------------------------------------------------------------------------
FUNCTION NetFileLock()

   IF fLock()
      RETURN( .T. )
   ENDIF

   MsgStop( "BANCO DE DADOS " + Alias() + " BLOQUEADO Por Outro Usuario.", ;
            "ERROR DE REDE" )

RETURN( .F. )
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
// Funci¢n ...: NetRecLock
// Descripci¢n: Bloquea un registro de fichero DBF, abierta en modo SHARED.
// Par metros : oDbf -> Objeto DATABASE.
// Devolve ..: .T.  -> Si se ha podido bloquear.
//              .F.  -> Si no se ha podido bloquear.
// ------------------------------------------------------------------------
FUNCTION NetRecLock( oDbf )

   IF oDbf:RecLock()
      RETURN( .T. )
   ENDIF

   MsgStop( "REGISTRO BLOQUEADO." + CRLF + ;
            "Outro Usuario o Esta Usando.", "ERRO DE REDE" )

RETURN( .F. )
// ------------------------------------------------------------------------

/*
// verificamos que no ocurra error si otros usuario están ocupando la Tabela

If MiTabela->( neterr() )
   ? "Imposible Agregar Registro en este momento"
    Return Nil
Else
    // si no ocurrió error, la Tabela está libre para agregarle un registro
    // en blanco, Porem queda bloqueado así que...
    MiTabela->( LastRec( DbUnLock() ) )
    // Con LastRec() nos aseguramos que sea el último registro físico
    // Agora se Podem reemplazar valores
    replace miTabela->campo1 with xvalor1
    replace miTabela->campo2 with ...etc, etc
Endif

if ( !NETERR() )
    Ferase("MiTabela.cdx")
    INDEX ON MiTabela->nombre1 TAG nom1
    INDEX ON ...etc, etc
else
    ? "Lo Siento.... Imposible Reindexar Agora"
endif
*/


Abs.
Kapiaba
Colaborador

Colaborador
 
Mensagens: 1766
Data de registro: 07 Dez 2012 15:14
Cidade/Estado: São Paulo
Curtiu: 311 vezes
Mens.Curtidas: 119 vezes

Anterior Próximo



Retornar para Harbour

Quem está online

Usuários vendo este fórum: Google [Bot] e 14 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro