Página 1 de 2
Rede lenta em alguns filtros
Enviado: 16 Mai 2015 16:28
por Josmar dos Santos
Boa tarde..eu de novo..rs.rs.rs. Seguinte, eu tenho um arquivo de contas APAGAR.DBF. Na rede ele roda com exceções. Vou explicar: No cadastro ele pode ser aberto compartilhado que não da lentidão, mas na manutenção(Alteração, consulta e exclusão) ele fica muito lento quando duas ou mais pessoas estão utilizando o mesmo arquivo(Se um abrir o cadastro, a consulta fica lenta). Agora, interessante é: Na manutenção o usuário tem três opções de consulta..lacamento, código do cliente e nome. Isso que não entendo!! No opção de lançamento ele é lentíssimo para abrir o arquivo, já nas outras opções é bem mais rápido. Andei vendo alguma coisa aqui no fórum que o pessoal não gosta do setfilter. Pergunto a vocês, será que seria o meu caso, pois utilizo setfilter para fazer as minhas consultas. O que me deixa meio perdido é que a lógica de consulta é igual para todos. Por que alguns filtros são mais rápidos do que os outros já que utiliza o mesmo arquivo?
Obs-> Utilizo CDX já compilado em Harbour graças a Deus..rs.rs.rs
Josmar
Eis um exemplo:
Código: Selecionar todos
SET DELETED ON
M->MOSTRA_RESULTADO := .T.
MENSAGEM( "Aguarde abertura de arquivos" )
IF !ABREFOR()
ALERT("NAO CONSIGO ABRIR O CADASTRO")
RETURN .F.
ENDIF
IF !ABREIND()
ALERT("NAO CONSIGO ABRIR O CADASTRO")
RETURN .F.
ENDIF
IF !ABREPAG()
ALERT("NAO CONSIGO ABRIR O CADASTRO")
RETURN .F.
ENDIF
ORDSETFOCUS("APAGAR_6")
SET FILTER TO V3<>0
PRIVATE ME_MO, LANC, COD, RAZ, TIPO, NRO, NF, V1, VENC, HIST, HIST1, PGTO
PRIVATE V2, V3, DATA, OBS, EMISS, ASSINAT, SIT_PAG
COR( "MENU" )
@ LIN_MENU, 00
@ LIN_MENU,01 SAY "Manuten‡„o ³ Cod.Lan‡amento"
JANELA( 03, 02, 21, 77, "Cod.Lan‡amento" )
L_CON := L_SOM; C_CON := C_SOM
@ 05, 04 CLEAR TO 19, 75
@ 05, 04 SAY SUBS( TB_JANELA, 1, 1 ) +;
REPL( SUBS( TB_JANELA, 2, 1 ), 70 ) + SUBS( TB_JANELA, 3, 1 )
@ 06, 04 SAY SUBS( TB_JANELA, 12, 1 )
@ 06, 75 SAY SUBS( TB_JANELA, 4, 1 )
@ 07, 04 SAY SUBS( TB_JANELA, 11, 1 )
@ 07, 75 SAY SUBS( TB_JANELA, 5, 1 )
FOR CONTAR = 8 TO 18
@ CONTAR, 04 SAY SUBS( TB_JANELA, 10, 1 )
@ CONTAR, 75 SAY SUBS( TB_JANELA, 6, 1 )
NEXT
@ 19, 04 SAY SUBS( TB_JANELA, 9, 1 ) +;
REPL( SUBS( TB_JANELA, 8, 1 ), 70 ) + SUBS( TB_JANELA, 7, 1 )
// -> Define as rotinas a serem usadas pelo TBROWSE
ROTI_NAS := { { | X | CARREG14( X ) },;
{ | X | CARGE_14( X ) },;
{ || SALVAR14() } }
GRA_VAR := {}
// -> Define as colunas para o TBROWSE
OB_COLUN := {}
AADD( OB_COLUN, TBCOLUMNNEW( "LANC:", { || TRAN( APAGAR->LANC, "999999" ) } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "CODIGO:", { || TRAN( APAGAR->COD, "99999" ) } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "RAZAO:", { || APAGAR->RAZ } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "TIPO:", { || APAGAR->TIPO } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "NRO.DOC:", { || APAGAR->NRO } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "N.FISCAL:", { || APAGAR->NF } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "VALOR:", { || TRAN( APAGAR->V1, "@E 999999999.99" ) } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "VENC:", { || APAGAR->VENC } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "PAGTO:", { || APAGAR->PGTO } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "V.PAGO:", { || TRAN( APAGAR->V2, "@E 999999999.99" ) } ) )
AADD( OB_COLUN, TBCOLUMNNEW( "SALDO:", { || TRAN( APAGAR->V3, "@E 999999999.99" ) } ) )
// -> Mostra a tela BROWSE e sai retornando o controle ao programa
BRO_WSE( .T. )
M->LANC := SPACE( 6 )
ED_JAN := {}
AADD( ED_JAN, { "Digite o numero do lan‡amento.:", M->LANC, "999999", 6,;
{ | DADOS | M->LANC := DADOS } } )
WHILE .T.
IF EDIT_JAN( ED_JAN ) = .F.
EXIT
ENDIF
SEEK TRIM( M->LANC )
IF EOF()
BEEP()
MENSAGEM( "Dados n„o encontrados", 3 )
LOOP
ENDIF
MENSAGEM( "Posicione sobre o registro desejado e tecle <ENTER>" )
// -> Edita tela BROWSE
BRO_WSE()
ENDDO
SET DELETED ON
RESTSCREEN( LIN_MENU + 1, 00, MAXROW() - 1, MAXCOL(), TELA_PRI )
SET DELETED ON
SET FILTER TO
Rede lenta em alguns filtros
Enviado: 16 Mai 2015 20:35
por JoséQuintas
A demora não é pelo que mostra, e sim pelo que não mostra.
Quanto menos registros mostrar, mais demorado vai ser.
Se o filtro resultar em um único registro, vai processar o arquivo inteiro pra mostrar o browse.
Se o filtro resultar em várias páginas, vai processar apenas uma página pra mostrar o browse.
Rede lenta em alguns filtros
Enviado: 18 Mai 2015 13:47
por Josmar dos Santos
Boa tarde Quintas, desculpe a minha ignorância, mas não entendi a sua explicação. Te pergunto: vc quis dizer a quantidade de campos que aparecem no BROWSE ou seria quantidade de filtros. Por que eu não entendo! Como eu disse: no contas a pagar existe três opções de filtros de consulta: Lançamento, Vencimento e Nome. Com exceção do Lançamento, os outros são rápidos e todos eles possuem as mesmas quantidade de campos no BROWSE. Você sugeri alguma ideia?
Josmar
Rede lenta em alguns filtros
Enviado: 18 Mai 2015 14:11
por paiva
BOa tarde
acho que o que ele quis dizer é:
o prg vai lendo a base e selecionando os reg filtrados QUANDO atinge o limite de linhas do Browser da tela ELE exibe esta tela e continua trabalhando por traz.
então se o resultado final Não encher uma Pag ou CUSTAR a encher ele vai DEMORAR a exibir a 1 pagina
PAiva
EU uso MUito set filter + se vc CRIAR um dbf abrir a BASE ler ela toda selecionando e gravando o dbf e depois exibir
ficar N vezes + rapido COM certeza pode ter 10.000 reg ou mais fica INSTANTANEO
q coisa contact que te mostro pelo Team.
skyper paiva_sistemas
Rede lenta em alguns filtros
Enviado: 18 Mai 2015 15:46
por JoséQuintas
Pra efeito didático, imagine um programa que vai mostrar 10 registros na tela:
Código: Selecionar todos
nCont = 0
DO WHILE .NOT. Eof()
IF Filtro()
nCont = nCont + 1
IF nCont = 10
EXIT
ENDIF
ENDIF
SKIP
ENDDO
O programa vai ter que processar registros até a quantidade chegar a 10, e pular os que não interessam.
Supondo que o arquivo tem 6.000 registros.
Se o resultado do filtro tem 1 registro, vão ser pulados 5.999 até terminar.
Se o resultado do filtro tem 500 registros, vai sair quando chegar a 10, nem vai precisar ir até o fim, e portanto não vai processar 6.000 registros.
Isso equivale ao processamento usado pra preencher a sua tela do Browse.
Então depende de quantos registros precisa pular pra preencher a tela.
Mesmo que só mostre 10, vai ter que pular os outros que não interessam.
Então a velocidade depende de quantos está pulando (não mostrando).
"pular um registro" significa que tudo isso tá passando pela rede e levando tempo.
O demorado então não é pra mostrar, é pra pular o que não vai mostrar.
A saída pra deixar mais rápido seria usar índices e rotinas pra agilizar, pra não precisar pular tanto.
pediu um lançamento, agilizaria mais o arquivo em ordem de lançamento e fazer um SEEK pelo número de lançamento.
pediu uma data, agilizaria mais um índice por data, fazer o SEEK da data, e trabalhar só com a sequencia de data.
Rede lenta em alguns filtros
Enviado: 18 Mai 2015 16:19
por Kapiaba
Boa tarde, troque o VELHO SET FILTER, por ORDSCOPE() ou por INDICE TEMPORARIO NA MEMORIA, COMANDO: MEMORY ou TEMPORARY
Sesu filtros, voarão. Uso muito ocm xHarbour é praticmante, instantâneo.
Veja aqui, como acelerar o velho SET FILTER:
https://pctoledo.org/forum/viewto ... =2&t=16031
Abs
Rede lenta em alguns filtros
Enviado: 19 Mai 2015 17:37
por Josmar dos Santos
Andei pesquisando sobre esse comando ORDSCOPE(). Achei ele muito interessante, pelo que vi ele faz um filtro no número X até o número Y (Se há 10.000 registros, ele só pega aqueles que tiverem entre as duas variáveis). Ontem tirei esse comando SET FILTER TO V3<>0 do código e compilei o mesmo, a pesquisa melhorou em mais de 100%. Só que utilizo esse comando para separar valores em abertos no CONTAS A PAGAR, ou seja, se o valor V3<>0 ele fica em aberto nessa TBROWSE. Agora caso V3=0 ele vai para outra TBROWSE como já pago. Uso para separar as contas em abertos com ascontas já pagas. É evidente que tirando esse SET FILTER TO V3<>0, todos os valores com V3=0 voltaram novamente para esse TBROWSE, porém ficou bem mais rápido. Agora pergunto a vocês daria para usar esse comando ORDSCOPE() para fazer a mesma função que esse comando está fazendo? ou seja, separar os valores já pagos dos valores em aberto? Como ficaria a sintaxe do mesmo??
Caso não dê para fazer o que eu quero vou tirar esse comando, tudo bem que a TBROWSE fique com mais dados, mas pelo menos ficou mais rápido...
Josmar
Rede lenta em alguns filtros
Enviado: 19 Mai 2015 20:49
por Eolo
O que o ORDSCOPE() faz é simplesmente limitar a navegação a um determinado ESCOPO ou extensão (de dados contíguos), baseado no INDICE ativo.
Se esse campo V3 é numérico, está indexado e contém 0 ou 1:
ORDSCOPE(0,0) -> seta o TOP
ORDSCOPE(1,0) -> seta o BOTT
-> só vão ficar visíveis os registros com V3=0
GO TOP vai para o primeiro 0, GO BOTT vai pro último 0
ORDSCOPE(0,1) -> TOP
ORDSCOPE(1,1) -> BOTT
-> só vão ficar visíveis os registros com V3=1
GO TOP vai para o primeiro 1, GO BOTT vai pro último 1
ORDSCOPE(0,nil)
ORDSCOPE(1,nil)
-> faz mostrar novamente todos os registros, desativando o filtro
GO TOP vai para o primeiro 0, GO BOTT vai pro último 1
Outro exemplo, com um DBF indexado pelo campo NOME:
ORDSCOPE(0,”A”) -> TOP
ORDSCOPE(1,”C”) -> BOTT
-> só vão ficar visíveis os registros com NOMEs iniciados com A, B ou C
GO TOP vai para o primeiro A, GO BOTT vai para o último C.
Óbvio que os dados têm que ser sequenciais, não dá pra filtrar por exemplo os nomes iniciados com A e F (sem mostrar de B a E).
Como o Kapiaba mencionou, o ORDSCOPE() é instantâneo. Abandone de vez o SET FILTER.
Rede lenta em alguns filtros
Enviado: 20 Mai 2015 09:59
por paiva
BOM dia uma duvida....
e se o índice for composto ex: empresa+filial+pedido
999 99 NNNNNN
como ficaria ? ou não pode ?
para filtra todos os ITENS de um determinado pedido ?
ob
Paiva
Rede lenta em alguns filtros
Enviado: 20 Mai 2015 10:17
por Eolo
e se o índice for composto ex: empresa+filial+pedido
999 99 NNNNNN
como ficaria ? ou não pode ?
Pode, mas lembrando que quem manda é o índice.
Por exemplo,
ORDSCOPE(0,’999 15’)
ORDSCOPE(1,’999 15’)
vai mostrar só a Filial 15 da Empresa 999.
ORDSCOPE(0,’999 10’)
ORDSCOPE(1,’999 15’)
vai mostrar as filiais de 10 a 15 da empresa 999.
ORDSCOPE(0,’999’)
ORDSCOPE(1,’999’)
vai mostrar todas as filiais da empresa 999.
ORDSCOPE(0,’999 15 100000’)
ORDSCOPE(1,’999 15 200000’)
vai mostrar os pedidos de 100000 a 200000 da filial 15 da empresa 999.
Agora, se vc quiser isolar as filiais 15, mas de todas as empresas, tem que criar outro índice
filial+empresa+pedido
99 999 NNNNNN
ORDSCOPE(0,’15’)
ORDSCOPE(1,’15’)
vai mostrar as filiais 15, de todas as empresas
Rede lenta em alguns filtros
Enviado: 20 Mai 2015 10:46
por Eolo
Um outro exemplo, pra complicar:
Código: Selecionar todos
use vendas new excl
inde on strzero(codcliente,5)+descend(dtos(datavenda)) tag xpto to vendas
* clientes em ordem crescente, datavenda decrescente dentro de cada cliente
set inde to vendas
set orde to “xpto”
base= strzero(1234,5)+descend(dtos(ctod(“01/01/2015”)))
topo= strzero(1234,5)+descend(dtos(ctod(“31/01/2015”)))
ORDSCOPE(0,base)
ORDSCOPE(1,topo)
go top
* vendas para o cliente 1234, de 01 a 31/01/2015
Rede lenta em alguns filtros
Enviado: 20 Mai 2015 12:15
por Kapiaba
Boa tarde,
Código: Selecionar todos
/*
ORDSETFOCUS("APAGAR_6")
SET FILTER TO V3<>0 // SE V3 FOR UM FIELD...
*/
SELECT APAGAR
// simulando o SET FILTER com Indice na memoria,
INDEX ON V3 TAG 05 TO APAGARTEMP ;
FOR ( .NOT. EOF() ) .AND. APAGAR->V3 != 0 MEMORY // TEMPORARY
GO TOP
BROWSE()
Voce pode fazer quantos tipos de filtros quiser, basta saber os campos do banco
Rede lenta em alguns filtros
Enviado: 20 Mai 2015 13:11
por Eolo
Kapiaba,
1. vc faz FOR ( .NOT. EOF() ) .AND. APAGAR->V3 != 0
Precisa do !EOF()? Até onde eu sei, os registros fantasmas EOF e BOF não entram nos indices.
Não bastaria, no índice condicional, "FOR V3#0"?
2. eu não gosto de criar índices no run time. Se o DBF tem 200 registros, pode ficar imperceptível. Mas se são 500.000, a cada consulta vai ter um delay no processamento, um "Aguarde, indexando arquivo"...
3. Há casos em que eu crio TAGs com índices condicionais, como o FOR, mas eles ficam fazendo parte integrante da base de dados. Não são criados no run time. E, sim, funciona como no ORDSCOPE, fica bem rápido.
Rede lenta em alguns filtros
Enviado: 20 Mai 2015 13:53
por Kapiaba
Boa tarde,
1. vc faz FOR ( .NOT. EOF() ) .AND. APAGAR->V3 != 0
Precisa do !EOF()? Até onde eu sei, os registros fantasmas EOF e BOF não entram nos indices.
Não bastaria, no índice condicional, "FOR V3#0"?
Eu sempre fiz asssim e funciona legal com xHarbour, este foi o modo que eu aprendi, prefiro que o indice na memoria o .dbf vá a té o fim, nunca testei sem o .NOT. EOF(), mas, creio q vá funcionar também.
2. eu não gosto de criar índices no run time. Se o DBF tem 200 registros, pode ficar imperceptível. Mas se são 500.000, a cada consulta vai ter um delay no processamento, um "Aguarde, indexando arquivo"...
Quando se cria indice na memoria, pode ser bancos com mais que isso, que o usuário nem percebe, já que o mesmo, vai para uma memoria auxiliar.
3. Há casos em que eu crio TAGs com índices condicionais, como o FOR, mas eles ficam fazendo parte integrante da base de dados. Não são criados no run time. E, sim, funciona como no ORDSCOPE, fica bem rápido.
Desconheço esta informação, nada que se cria na memoria, vai para .CDX do seu .DBF, ao terminar o processo, tudo morre, e você chama o .CDX do banco original, creio que se fecha o temporário, com SET ORDER TO 0. abs.
Rede lenta em alguns filtros
Enviado: 20 Mai 2015 19:10
por Eolo
Eu sempre fiz asssim e funciona legal com xHarbour, este foi o modo que eu aprendi, prefiro que o indice na memoria o .dbf vá a té o fim, nunca testei sem o .NOT. EOF(), mas, creio q vá funcionar também.
Criar um índice na memória OU criar no HD não tem ligação nenhuma com usar ou não o EOF().
A indexação sempre vai até o EOF. Só para, eventualmente, antes de chegar no EOF, quando se usa a cláusula WHILE. Com ela, quando a condição X deixar se ser atendida, a indexação termina naquele registro, atingido ou não o EOF.
Desconheço esta informação, nada que se cria na memoria, vai para .CDX do seu .DBF, ao terminar o processo, tudo morre, e você chama o .CDX do banco original, creio que se fecha o temporário, com SET ORDER TO 0.
O que eu quis dizer foi que eu crio TAGs permanentes, dentro do CDX, com e sem a cláusula FOR. A cláusula FOR não é só pra índices temporários.
Por exemplo, meu NOMES.DBF recebe clientes, fornecedores e funcionários, tudo junto, porque há clientes que são fornecedores, funcionários que são clientes e por aí vai. Quando o José (cliente e fornecedor) muda de endereço, só preciso alterar um DBF.
Pra identificar, 3 campos, CLIE, FORN e FUNC, que recebem 0 ou 1. Na indexação:
use nomes
index on nome tag tudo to nomes // todos os nomes, sem FOR
index on nome tag clie for CLIE=1 to nomes // só clientes
index on nome tag forn for FORN=1 to nomes // só fornecedores
index on nome tag func for FUNC=1 to nomes // só funcionários
Se o José é cliente e fornecedor (CLIE=1, FORN=1, FUNC=0), ele vai aparecer nas TAGs CLIE e FORN. Se o João é só funcionário (CLIE=0, FORN=0, FUNC=1), só aparece na TAG FUNC.
Quando abro a Cadastro de Funcionários, é só usar o SET ORDE TO “FUNC”. Vêm só os funcionários. E, na inclusão de um novo nome, pra evitar duplicidade, SET ORDE TO "TUDO" e SEEK.