relatórios... como aumentar a performace???

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

Moderador: Moderadores

Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

relatórios... como aumentar a performace???

Mensagem 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)

fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem 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. :)
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Mensagem 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
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem 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.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
ederxc
Usuário Nível 4
Usuário Nível 4
Mensagens: 619
Registrado em: 15 Set 2006 08:40
Localização: Pedreira -SP-

Mensagem 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 ...

:%
C:\Xharbour\Xdev\Fw\VSX
Avatar do usuário
gvc
Colaborador
Colaborador
Mensagens: 1270
Registrado em: 23 Ago 2005 10:57

Mensagem 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.
"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Mensagem 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.

:P

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
Editado pela última vez por janio em 12 Fev 2008 10:30, em um total de 1 vez.
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem 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.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem 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. :)
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
ederxc
Usuário Nível 4
Usuário Nível 4
Mensagens: 619
Registrado em: 15 Set 2006 08:40
Localização: Pedreira -SP-

Mensagem por ederxc »

... É com PDF não rola , fiz um teste aqui com 40000 e demorou um bocado
C:\Xharbour\Xdev\Fw\VSX
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Mensagem 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 !
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Mensagem por janio »

Talvez se fosse gerando um DBF em vez de TXT seria mais fácil controlar esse 'povoamento' com tbrowse...

Jânio
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
edmarfrazao
Usuário Nível 3
Usuário Nível 3
Mensagens: 185
Registrado em: 06 Dez 2005 11:16

Mensagem por edmarfrazao »

se desejar visualizar direto o txt na tela tenho uma rotina

que não importa nada simplemente visualiza o txt usando readln
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Mensagem 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 !!! :))
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
Luciano Bonfim
Usuário Nível 3
Usuário Nível 3
Mensagens: 414
Registrado em: 23 Ago 2007 09:34
Localização: Rio de Janeiro / São Paulo
Contato:

Mensagem 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
Muito Obrigado,

Luciano Bonfim de Azevedo
www.bonfim.com.br
luciano@bonfim.com.br
www.linkedin.com/in/lucianobonfim
Skype : lucianobonfim
Responder