Página 1 de 3
relatórios... como aumentar a performace???
Enviado: 11 Fev 2008 11:02
por janio
Colegas,
O procedimento que tenho adotado para exibir relatórios no
VIDEO é o seguinte: mando a impressão para um TXT.... depois importo esse TXT para um DBF e através do Tbrowse o visualizo na tela.
Ou seja, o relatório é mostrado na tela
somente ser gerado todo o TXT (lido registro a registro) e depois importado para um DBF.
Em um teste simples com um banco de dados com
40.000 registros, esse procedimento durou cerca de
37 segundos.
Se em vez de mandar a impressão para um TXT, eu exibir esses dados através de um
DbEdit ou
Tbrowse, os mesmos
40.000 registros são mostrados instantaneamente.
Por que?? Acredito que seja pelo fato de com o TXT o relatório só é mostrado após a leitura de
TODOS os dados.
Já com o Dbedit ou Tbrowse esse dados vãos sendo lidos a medida que vão sendo mostrados na tela.
A pergunta é:
1-) Esse procedimento está correto??
2-) Não há como ir gerando esse TXT à medida que for sendo mostrado o relatório na tela (como acontece com o tbrowse) ??
Para TXT:
Código: Selecionar todos
SET PRINT ON
SET PRINTER TO arquivo.txt
SET DEVICE TO PRINTER
SET CONSOLE OFF
SetPrc(0,0)
xSOMA := 0
cCONTA := 0
vDATAi := Ctod("01/01/2007")
vDATAf := Ctod("31/12/2007")
SELECT PEDIDO
DBSETORDER(8)
GOTO TOP
ORDSCOPE( 0, DTOS(vDATAi) )
ORDSCOPE( 1, DTOS(vDATAf) )
GOTO TOP
SET RELATION TO CODCLI INTO CLIENTE, TO CODVED INTO VENDEDOR
DO WHILE !EOF()
vTOTAL_PED = ( PEDIDO->TOTPED - PEDIDO->VLRDES )
@ PROW() + 01,00 SAY PEDIDO->PEDIDO PICT "@E 999,999"
@ PROW() ,08 SAY STRZERO(PEDIDO->CODCLI,4)
@ PROW() ,13 SAY CLIENTE->NOMCLI PICT "@!S22"
@ PROW() ,37 SAY VENDEDOR->NOMRDZ PICT "@!"
@ PROW() ,51 SAY STRZERO(PEDIDO->QTDPAR,02)
@ PROW() ,59 SAY PEDIDO->VENPRI
@ PROW() ,70 SAY vTOTAL_PED PICT "@E 99,999.99"
xSOMA = xSOMA + vTOTAL_PED
cCONTA = cCONTA + 1
DBSKIP()
ENDDO
ORDSCOPE( 0, NIL )
ORDSCOPE( 1, NIL )
@ PROW() + 03,00 SAY PADC("****** FIM DO RELATORIO ******",79)
SET CONSOLE ON
SET PRINTER OFF
SET PRINTER TO
SET DEVICE TO SCREEN
Para Dbedit ou Tbrowse:
Código: Selecionar todos
vDATAi := Ctod("01/01/2007")
vDATAf := Ctod("31/12/2007")
SELECT PEDIDO
DBSETORDER(8)
GOTO TOP
ORDSCOPE( 0, DTOS(vDATAi) )
ORDSCOPE( 1, DTOS(vDATAf) )
GOTO TOP
SET RELATION TO CODCLI INTO CLIENTE, TO CODVED INTO VENDEDOR
DbEdit(1,1,23,79)
Enviado: 11 Fev 2008 11:13
por Maligno
Você está trabalhando em mono-tarefa, com o agravante de ainda ter que exportar o texto para DBF, o que não é nada prático. A solução que vejo é usar um visualizador de TXT, abandonando o DBF intermediário. Só isso já vai ajudar bastante. Mas o que vai deixar realmente bom é você criar uma thread secundária, que permita a visualização do TXT
enquanto ele estiver sendo povoado. Claro que isso requer uma lógica bem mais compelxa, com controle de semáforos, inclusive. Mas deve ficar o "cão chupando manga" de rápido.

Enviado: 11 Fev 2008 11:40
por janio
Maligno escreveu:Mas o que vai deixar realmente bom é você criar uma thread secundária, que permita a visualização do TXT
enquanto ele estiver sendo povoado. Claro que isso requer uma lógica bem mais compelxa, com controle de semáforos, inclusive. Mas deve ficar o "cão chupando manga" de rápido.

Maligno,
É exatamente isso que imagino. O problema é a montagem dessa
maledita rotina.... rsrsrsrs
Já vi duas situações:
1- Um sistema (não em clipper/xharbour) que o relatório
é mostrado instantaneamente, embora tenha/terá milhões de registros. Com um detalhe: O txt só vai sendo 'povoado' à medida que vai-se avançando no relatório. Isso evita que fique havendo um processamento 'por trás'.
2- Também já vi outro (não sei se em Delphi) que mostra logo a primeira página na tela, mas enquanto isso fica processando o restante do relatório, amarrando o processador. Não achei esse método legal.
Jânio
Enviado: 11 Fev 2008 11:58
por Maligno
janio escreveu:É exatamente isso que imagino. O problema é a montagem dessa maledita rotina.... rsrsrsrs
Rapadura é doce mas não é mole não.

))
O xHarbour tem uma série de funções para tratamente de threads. Você vai ter que estudar e fazer seu próprio sistema ou encontrar algo pronto. É capaz que exista. Procurou por alguma coisa assim?
Já vi duas situações:
1- Um sistema (não em clipper/xharbour) que o relatório é mostrado instantaneamente, embora tenha/terá milhões de registros. Com um detalhe: O txt só vai sendo 'povoado' à medida que vai-se avançando no relatório. Isso evita que fique havendo um processamento 'por trás'.
Deve ficar muito bom mesmo. Mas acho que você não vai encontrar algo pronto que faça isso, pois é um sistema bem "amarrado", apesar de não ser tão complicado de fazer.
2- Também já vi outro (não sei se em Delphi) que mostra logo a primeira página na tela, mas enquanto isso fica processando o restante do relatório, amarrando o processador. Não achei esse método legal.
Muito bom também. Leve em conta que a grande maioria dos relatórios não é tão grande. O processador será liberado mais ou menos rápido. Ademais, assim como no caso anterior, você pode controlar até onde o usuário poderá navegar, com o uso de semáforos.
Enviado: 11 Fev 2008 12:25
por ederxc
Buenas ...
Ja tentou usar uma impressora PDF ? Fica bem pratico ... Ae só nãoi sei dizer se abrira rapido com essa quantidade de resgistros ...
:%
Enviado: 11 Fev 2008 12:28
por gvc
Eu gravo o relatório e abro o mesmo usando o README.
É um prequeno programa da borland (muito antigo tempo do turbo pascal 1.xx).
Ele é pequeno e rápido.
Só tem o problema de ter que "esperar" o relatório terminar. Mas para o usuário ficou muito melhor do que antes, que ele tinha que imprimir para consultar.
No Clipper, vc pode abrir um arquivo até 64k. Não sei se ainda tem esse limite no xHarbour.
Usar uma impressora PDF não deve deixar mais rápido.
O arquivo deve ser criado, fechado e depois aberto pelo read. A abertura do read já é bem lenta. Muito mais que a abertura do TXT.
Isso pelo que eu ví em trabalhos aqui. Se der para abrir enquanto grava, ótimo mesmo.
Enviado: 11 Fev 2008 12:44
por janio
gvc escreveu:Só tem o problema de ter que "esperar" o relatório terminar
Esse 'pequenino problema' que vc fala é o responsável pela lentidão dos relatórios e minha maior dor de cabeça atual.
37 segundos para exibir um relatório com 40.000 registros não dá de matar ninguém de raiva. Sem falar que não é a toda hora que pede-se um relatório com tantos registros.
Mas...
Mas...
Se sei que é possível ter algo
INSTANTANEO, por que eu me conformaria em esperar 37 segundos???
Como disse no início e que foi bem compreendido pelo Maligno, preciso que vá GERANDO enquanto vai EXIBINDO. É possível isso por que já vi programa funcionando assim. É de dar água na boca. É uma bala! Só tem o problema de elaborar tal rotina que o Maligno falou. Essa eu entrego os pontos. Nem que eu morra doido consigo elaborar uma rotina dessas. buaaaaaaa... buaaaaaa
:'( :'( :'( :'( :'(
Jânio
Enviado: 11 Fev 2008 12:54
por Maligno
O XHarbour não tem esse limite de 64KB. Mas o problema vai continuar do mesmo jeito, seja em PDF ou qualquer outro meio que utilize um processamento seqüêncial. A única forma de fazer realmente rápido é tendo duas tarefas distintas. A primeira gerando o relatório em arquivo e a segunda mostrando esse arquivo pro usuário. Ou, conforme o Janio citou, montando um esquema coeso em que o relatório é gerado conforme for preciso visualizá-lo. No primeiro caso, o visualizador opera em função do gerador. No segundo caso o gerador processa por demanda, em função das necessidades do visualizador. Uma estrutura bem diferente.
Enviado: 11 Fev 2008 13:00
por Maligno
janio escreveu:Mas...
Mas...
Se sei que é possível ter algo INSTANTANEO, por que eu me conformaria em esperar 37 segundos???
Ô, ganância.

)))
Mas eu sou obrigado a concordar. Pra quê fazer arroz-com-feijão se dá fazer coisa muito melhor.
Só tem o problema de elaborar tal rotina que o Maligno falou. Essa eu entrego os pontos. Nem que eu morra doido consigo elaborar uma rotina dessas. buaaaaaaa... buaaaaaa
Você
acha que não consegue. Mas se você se dedicar e queimar as pestanas, consegue sim. Mas primeiro, você precisa se convencer disso.

Enviado: 11 Fev 2008 14:12
por ederxc
... É com PDF não rola , fiz um teste aqui com 40000 e demorou um bocado
Enviado: 11 Fev 2008 20:46
por alaminojunior
Tenho certeza, que com as funções de Multi-Threading ou BackGround, do xHarbour, como o Maligno já citou, vc consegue tal façanha.
Estude um pouco mais a respeito, faça alguns testes. Não está com jeito de bicho de sete cabeças não !
Enviado: 12 Fev 2008 09:33
por janio
Talvez se fosse gerando um DBF em vez de TXT seria mais fácil controlar esse 'povoamento' com tbrowse...
Jânio
Enviado: 12 Fev 2008 10:03
por edmarfrazao
se desejar visualizar direto o txt na tela tenho uma rotina
que não importa nada simplemente visualiza o txt usando readln
Enviado: 12 Fev 2008 10:08
por alaminojunior
Então rapaiz, acho que usando DBF em vez de TXT, dá para: a cada n milisec´s, fazer com que mais dados sejam transferidos. Isso com a StartThread() e outras funções pertinentes.
Ando meio sem tempo por aqui, mas à medida que for sobrando um tempinho, vou testando.
Note que as aplicações com esta lógica podem ser várias hein !?
Se cuida aí Bill Gates !!!

)
Enviado: 12 Fev 2008 12:37
por Luciano Bonfim
Caro Jânio,
Aproveitando seu código, gostaria de tirar uma dúvida. vi que vc usa ordscope, eu nunca usei essa funçäo e vejo todo mundo usando. em relatórios parecidos com o seu eu uso a sequinte lógica e acho que deve ser mais demorada do que usando o ordscope
Código: Selecionar todos
vDATAi := Ctod("01/01/2007")
vDATAf := Ctod("31/12/2007")
use PEDIDO
index on data to i1
seek vDatai
SET RELATION TO CODCLI INTO CLIENTE, TO CODVED INTO VENDEDOR
DO WHILE !EOF() .and. data<=vdataf
vTOTAL_PED = ( PEDIDO->TOTPED - PEDIDO->VLRDES )
@ PROW() + 01,00 SAY PEDIDO->PEDIDO PICT "@E 999,999"
@ PROW() ,08 SAY STRZERO(PEDIDO->CODCLI,4)
@ PROW() ,13 SAY CLIENTE->NOMCLI PICT "@!S22"
@ PROW() ,37 SAY VENDEDOR->NOMRDZ PICT "@!"
@ PROW() ,51 SAY STRZERO(PEDIDO->QTDPAR,02)
@ PROW() ,59 SAY PEDIDO->VENPRI
@ PROW() ,70 SAY vTOTAL_PED PICT "@E 99,999.99"
xSOMA = xSOMA + vTOTAL_PED
cCONTA = cCONTA + 1
DBSKIP()
ENDDO
a minha perguta é: usando esse dbscope que eu acredito que deve ser algum tipo de filtro realizado dentro do índice, fica mais rápido comparando cm o exemplo que eu postei?
Muito Obrigado