Página 2 de 3
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 17 Fev 2020 18:11
por Itamar M. Lins Jr.
Ola!
Código: Selecionar todos
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

- No "celelon" veinho com @ say, depois do "Do While"
Linux wins!
Saudações,
Itamar M. Lins Jr.
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 17 Fev 2020 18:20
por JoséQuintas
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.
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 17 Fev 2020 18:36
por JoséQuintas

- test5.png (10.18 KiB) Exibido 4374 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.
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 17 Fev 2020 19:12
por EduardoSPno
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 ...
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 17 Fev 2020 19:13
por EduardoSPno
corrigindo, MONSTROS !!!!!
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 18 Fev 2020 00:50
por JoséQuintas
Pra usar GTWVG, basicamente é isto:
e compilar usando hbmk2 projeto.hbp gtwvg.hbc
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 18 Fev 2020 08:19
por JoséQuintas
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.
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 18 Fev 2020 20:03
por EduardoSPno
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 !!
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 18 Fev 2020 20:50
por Itamar M. Lins Jr.
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.
https://pctoledo.org/forum/viewto ... osnetregok
Código: Selecionar todos
//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.
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 18 Fev 2020 21:48
por EduardoSPno
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
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 19 Fev 2020 08:04
por JoséQuintas
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.
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 19 Fev 2020 08:22
por EduardoSPno
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??
Código: Selecionar todos
// 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
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 19 Fev 2020 10:42
por Kapiaba
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
Código: Selecionar todos
// 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.
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 19 Fev 2020 10:46
por Kapiaba
Eduardo:
Se nao entender espanhol, use o tradutor do google, ou pergunte aos demais.
Código: Selecionar todos
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.
LENTIDAO PARA PESQUISAR DBF EM HARBOUR
Enviado: 19 Fev 2020 10:52
por Kapiaba
Eduardo, veja esse exemplo para abertura de bancos de dados. Se gostar, adapte para o seu gosto pessoal.
Código: Selecionar todos
// ------------------------------------------------------------------------
// 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.