É possível ??

Delphi

03/01/2006

Pessoal, to me batendo a um bom tempo com geradores de relatórios.
RDPrint, VDOPrint, Rave...

O negócio é que tenho extrema necessidade de impressão rápida nas
matriciais. Vou começar a explorar o Fortes agora, mas de antemão
gostaria de saber se é possível fazer um lance aqui que tenho muito
nos meus relatórios:

Um pesquisa mestre-detalhe assim:

Valor - Detalhes

5,00 - 1500 3000 5000 1254 1252 1251
..........6235 8457 5214 9874 6252 1251
..........1252 5874

6,20 - 3500 3000 5000 1254 1252 1251
..........6235 8457 5214 9874 6252 1251
..........1252 5874

( esses pontinhos são a margem )


Tive grande dificuldade para( e não consegui ) fazer isso no Rave, e
acabei desistindo pela lerdeza nas matriciais.
O RDPrint que comprei trabalha beleza, só que para gerar 30 páginas
disso ai passa quase 40 segundos !! E não é a lógica, porque no Rave
o mesmo código passa 5 segundos para gerar 60 ! E no VDOPrint é
mandado automáticamente ( tudo bem não tem visualização ). è que ele gera tudo primeiro para depois mandar para impressora, mesmo desativando o preview.

A pergunta no Fortes é :
Tem como jogar o Mestre no lado e na mesma linha dos
detalhes, que iniciam com uma margem.
Se poderem me ajudar beleza, serei um novo adpto do Fortes.

Vcs conhecem algum outro Gerador que funciona para matriciais ( com Preview ) blz ??

Obrigado.
Laelson Correia


Laelsonc

Laelsonc

Curtidas 0

Respostas

Joni Nunes

Joni Nunes

03/01/2006

Caro colega, utilizo RDPrint para impressão de relatórios que geram mais 600 páginas sendo que esses relatórios possuem várias variações pois são relatórios contábeis, projeções, extrato de movimentos e não tenho problemas com performance. Dos componentes que eu e a equipe que trabalho pesquisamos (Fortes, Rave, RDPrint e outros) escolhemos o RDPrint.

Não querendo por um dúvida sua capacidade, mas sim como aprendizado e curiosidade, disponibilize o seu código para eu e outros colegas de profissão dar uma olhada e ver se podemos colaborar de uma forma mais efetiva.

Abraço.

Joni Nunes
Analista de Sistemas
jonifoz@yahoo.com.br


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

OK, obrigado por se disponibilizar a ajudar.

Coloco o código ai embaixo e gostaria que analizasse(m).
Coloquei ai só o ´1° Relatório´, Mas vai até o ´10° Relatório´ só mudando os parâmentros iniciais, são todos iguais.

Obs.: Para gerar a visualização desse relatório tah demorando 42 segundos, e sem a visualização o mesmo. Como vcs poderam ver, ele é mestre-detalhe como o exemplo na mensagem acima.

Uso dois loops, um para pegar o mestre e outro para gerar o detalhe na mesma linha e em colunas diferentes.



// Inicio...
with impressao do
begin
abrir; // inicializa o arquivo de impressao...
if setup then // abre tela para escolha da impressora e modelo...
begin


//-----------------------------------------------------------------------------
conta := 0;
cabecalho := ´´;
Linha := 1;
Limite_Linha := 62;


//******************************************************//
// 1° RELATÓRIO
//*****************************************************//
n_premio := ´1´;
n_tipo := ´M´;
cabecalho := ´----------- 1° Prêmio -----------´;

with MD.DESCARGA_MESTRE do
begin
Close;
SQL.Clear;
SQL.Add(´select desc_descarga from desc_temp where desc_id=´´+desc_id+´´ and desc_jogopremio=´´+n_premio+´°´ and desc_jogotipo=´´+n_tipo+´´ group by desc_descarga order by desc_descarga Desc;´);
Open;
end;

//Se tiver registros continue
if MD.DESCARGA_MESTRE.RecordCount > 0 then begin

if (Linha < 59) and (Linha > 5) then begin
end;

if Linha < Limite_Linha then begin
inc(Linha); inc(Linha);
impc(Linha,40, cabecalho, [Expandido,Negrito]); //AQUI É O CABEÇALHO
inc(Linha); inc(Linha);
end;

//LOOP MAIS IMPORTANTE - M1

while not MD.DESCARGA_MESTRE.Eof do begin

//Consulta os jogos com esse valor ( detalhes )
with MD.DESCARGA_DETALHE do
begin
Close;
SQL.Clear;
SQL.Add(´select desc_temp_jogo,desc_descarga from desc_temp where desc_id=´´+desc_id+´´ and desc_jogopremio=´´+n_premio+´°´ and desc_jogotipo=´´+n_tipo+´´ and desc_descarga=´´+TrocaVirgPPto(MD.DESCARGA_MESTRE.FieldByName(´desc_descarga´).AsString)+´´;´);
Open;
end;

if Linha > Limite_Linha then begin
novapagina; // Rodapé e Cabeçalho
end;

//Aqui eu imprimo o Valor -
imp(Linha,01, FormatFloat(´#,,0.00´,StrToFloat(MD.DESCARGA_MESTRE.FieldByName(´desc_descarga´).AsString))+´ - ´);

Inicio := 10; //Começar desse valor
Col := 9; // Numero de colunas
F := 1; //Incrementador
Total := MD.DESCARGA_DETALHE.RecordCount;

while not MD.DESCARGA_DETALHE.Eof do begin

if (F < Total) and (F < Col) then begin
imp(Linha,Inicio, MD.DESCARGA_DETALHE.FieldByName(´desc_temp_jogo´).AsString);
F := F + 1;
Inicio := Inicio + 8;
end else begin
imp(Linha,Inicio, MD.DESCARGA_DETALHE.FieldByName(´desc_temp_jogo´).AsString);
Inicio := 10;
F := 1;
Total := Total - Col;
inc(Linha);

if Linha > Limite_Linha then begin
novapagina; // Rodapé e Cabeçalho
end;


end;

MD.DESCARGA_DETALHE.next;
//FINALIZA OS JOGOS
end;

imp(Linha,01,´--------------------------------------------------------------------------------´);
inc(Linha);

MD.DESCARGA_MESTRE.next;
//FINALIZA VALOR
end;

cabecalho := ´´;
end; //Fim do If



//******************************************************//
// 2 ° RELATÓRIO
//*****************************************************//
...

Vai até o 10°.


//****************************************//
//
//****************************************//




fechar; // Finaliza e inicia impressao ou preview
end else
showmessage(´|--------------------------- Relatório Cancelado ---------------------------|´);
end;


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

Alguma sugestão ?


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

Alguem poderia olhar o meu código por favor ? Só pra dar uma opinião se esta certo.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

03/01/2006

colega, creio que o seu problema de lentidão se dê por conta da abertura e fechamento dos datasets dentro da montagem do relatório. meus relatórios são praticamente instantâneos, mas eu preparo as informações antes de iniciar a impressão do relatório.


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

OK. Valeu pela dica, mas o problema é mais embaixo. Malhei o RDPrint e me redimo... rsrs.

Fiz uns testes sem o relatório e vejo que a demora é mesmo na qry do detalhe. É lá o problema de lentidão.

Daria pra alguem me dizer se existe outra maneira de fazer este Mestre-Detalhe com uma performance melhor ? Tipo os do datasource.
Uso o Zeos com Mysql.

Só pra lembrar ai como é:

5,00 - 1500 2511 2652 6587 9512
.............5487 1254 6874 1357

9,50 - 1500 2511 2652 6587 9512
.............5487 1254 6874 1357


....

Por favor, nem que seja pra dizer que tah tudo errado..rsr


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

03/01/2006

eu faria isso numa única query.


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

Cara, agradeço mesmo pela ajuda, mas não sei como fazer esse consulta Mestre-Detalhe numa mesma qry. Dá pra vc me dar um exemplo ?


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

03/01/2006

tente assim. dessa forma não é necessária uma tabela detalhe e nem utilizar recursos com recordcount e outras variáveis:

with MD.DESCARGA_MESTRE do
begin
  Close;
  SQL.Text := ´select ´+
              ´  desc_descarga, desc_temp_jogo ´+
              ´from ´+
              ´  desc_temp ´+
              ´where ´+
              ´  desc_id = ´+QuotedStr(desc_id)+
              ´  and desc_jogopremio = ´+QuotedStr(n_premio)+
              ´  and desc_jogotipo = ´+QuotedStr(n_tipo)+
              ´order by ´+
              ´  desc_descarga desc ´;
  Open;
end;

// ******************************* //
// * Se tiver registros continue * //
// ******************************* //
// não utilize recordcount se você não precisa saber
// exatamente o número de registros. se a necessidade
// é apenas saber se a tabela está vazia, utilize
// .isempty ou .eof
if not MD.DESCARGA_MESTRE.IsEmpty then
begin
  if (Linha < 59) and (Linha > 5) then
  begin
  end;

  if Linha < Limite_Linha then
  begin
    inc(Linha); inc(Linha);
    impc(Linha,40, cabecalho, [Expandido,Negrito]); //AQUI É O CABEÇALHO
    inc(Linha); inc(Linha);
  end;

  // variável para controlar a mudança de registro ´mestre´
  sMestre := ´@.x´;
  Col := 9; // Numero de colunas
  //Inicio := 10; //Começar desse valor (desnecessario)

  //LOOP MAIS IMPORTANTE - M1
  while not MD.DESCARGA_MESTRE.Eof do
  begin
    if Linha > Limite_Linha then
    begin
      novapagina; // Rodapé e Cabeçalho
      sMestre := ´@.x´; // assim repete o "desc_descarga" na nova página
    end;

    //Aqui eu imprimo o Valor de "desc_descarga"
    if MD.DESCARGA_MESTRE.FieldByName(´desc_descarga´).AsString <> sMestre then
    begin
      sMestre := MD.DESCARGA_MESTRE.FieldByName(´desc_descarga´).AsString;
      imp(Linha,01,FormatFloat(´#,,0.00´,StrToFloat(sMestre))+´ - ´);
      F := 1; //Incrementador
    end;

//    Total := MD.DESCARGA_DETALHE.RecordCount; // variavel desnecessaria
//    além de desnecessária, tornava o sistema mais lento...

    imp(Linha,10 + (8 * (F - 1)), MD.DESCARGA_MESTRE.FieldByName(´desc_temp_jogo´).AsString);

    Inc(F);

    if F >= Col then
    begin
      inc(Linha);
      F := 1;
    end;

    MD.DESCARGA_MESTRE.next;

    if MD.DESCARGA_MESTRE.FieldByName(´desc_descarga´).AsString <> sMestre then
    begin
      imp(Linha,01,´--------------------------------------------------------------------------------´);
      inc(Linha);
    end;
    //FINALIZA VALOR
  end;

  cabecalho := ´´;
end; //Fim do If


obs.: não testei esse código.


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

Cara, to fazendo os primeiros testes aqui e tah show de bola !!!
Até agora to tonto..rsrsrs

Valeus, assim que terminar te falo ok.


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

Cara, como disse tah muito show.
Você fez tudo !! Muito obrigado.

Só não to, a princípio, conseguindo controlar a distância entre as colunas porque so tras oito, quando mudo para nove ela sai da página. E em algumas linhas ela salta duas vezes.

[b:e75a630d88]Mas muito obrigado rapaz.[/b:e75a630d88]

:D Laelson Correia


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

03/01/2006

para o numero de colunas correto, altere o trecho de código:
    if F >= Col then 
    begin 
      inc(Linha); 
      F := 1; 
    end;


para:
    if F > Col then 
    begin 
      inc(Linha); 
      F := 1; 
    end;


uma coisa: o salto de linhas pode ser comprometido dependendo do número de colunas da sua página.
se seu formulário for de 80 colunas, numa impressora de 80 colunas, poderá haver um ´estouro´ na largura dependendo das informações impressas e isso gera um salto de linha automático. mas é um problema fácil de avaliar e resolver.

outra coisa: o tempo para a geração do relatório melhorou?


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

Sim, o tempo melhorou. Como vc disse, ficou quase instantâneo !!
Vou só terminar, porque são dez ´joguinhos´ desse código, dentro do mesmo relátório, mudando apenas os parâmentros, daí avalio o final. Mas creio que melhor do que isso vai ser mesmo difícil. Sinceramente ainda to tentando entender como funciona essa lógica, aquele lance com a variável ´sMestre := ´@.x´;´ não entendi até agora..rsrs. :roll:

Mas isso é para com o tempo. É bom saber que existe jeito pra tudo na programação. Bom saber que existe pessoas dispostas a ajudar.

Eu ja havia alterado o lance das colunas, mas mesmo assim continua. Vou olhar com mais cuidado o que pode ser, daí te aviso.

Eu vou mecher nele hoje a tarde porque tenho compromissos pela manhã.
Obrigado.

Laelson Correia


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

03/01/2006

só mais uma coisa: você não precisa ter dez joguinhos desse código se a única diferença estiver nos parâmetros passados para a query; faça tudo dentro de um laço for..next e tenha somente um ´conjunto´ do código:

// "i" é uma variável do tipo shortint
for i := 1 to 10 do
begin
  // esse "case" poderia ser substituido por um array...
  case i of
    1: begin
         cabecalho := ´cabecalho para jogo 1´
         desc_id := ´valor 1´;
         n_premio := ´valor 1´;
         n_tipo := ´valor 1´;
       end;
    2: begin
         cabecalho := ´cabecalho para jogo 2´
         desc_id := ´valor 2´;
         n_premio := ´valor 2´;
         n_tipo := ´valor 2´;
       end;
    3: begin
         cabecalho := ´cabecalho para jogo 3´
         desc_id := ´valor 3´;
         n_premio := ´valor 3´;
         n_tipo := ´valor 3´;
       end;
    4: begin
         cabecalho := ´cabecalho para jogo 4´
         desc_id := ´valor 4´;
         n_premio := ´valor 4´;
         n_tipo := ´valor 4´;
       end;
    5: begin
         cabecalho := ´cabecalho para jogo 5´
         desc_id := ´valor 5´;
         n_premio := ´valor 5´;
         n_tipo := ´valor 5´;
       end;
    6: begin
         cabecalho := ´cabecalho para jogo 6´
         desc_id := ´valor 6´;
         n_premio := ´valor 6´;
         n_tipo := ´valor 6´;
       end;
    7: begin
         cabecalho := ´cabecalho para jogo 7´
         desc_id := ´valor 7´;
         n_premio := ´valor 7´;
         n_tipo := ´valor 7´;
       end;
    8: begin
         cabecalho := ´cabecalho para jogo 8´
         desc_id := ´valor 8´;
         n_premio := ´valor 8´;
         n_tipo := ´valor 8´;
       end;
    9: begin
         cabecalho := ´cabecalho para jogo 9´
         desc_id := ´valor 9´;
         n_premio := ´valor 9´;
         n_tipo := ´valor 9´;
       end;
    else
       begin
         cabecalho := ´cabecalho para jogo 10´
         desc_id := ´valor 10´;
         n_premio := ´valor 10´;
         n_tipo := ´valor 10´;
       end;
  end;

  with MD.DESCARGA_MESTRE do
  begin
    Close;
    SQL.Text := ´select ´+
                ´  desc_descarga, desc_temp_jogo ´+
                ´from ´+
                ´  desc_temp ´+
                ´where ´+
                ´  desc_id = ´+QuotedStr(desc_id)+
                ´  and desc_jogopremio = ´+QuotedStr(n_premio)+
                ´  and desc_jogotipo = ´+QuotedStr(n_tipo)+
                ´order by ´+
                ´  desc_descarga desc ´;
    Open;
  end;

  // ******************************* //
  // * Se tiver registros continue * //
  // ******************************* //
  // não utilize recordcount se você não precisa saber
  // exatamente o número de registros. se a necessidade
  // é apenas saber se a tabela está vazia, utilize
  // .isempty ou .eof
  if not MD.DESCARGA_MESTRE.IsEmpty then
  begin
    if (Linha < 59) and (Linha > 5) then
    begin
    end;

    if Linha < Limite_Linha then
    begin
      inc(Linha); inc(Linha);
      impc(Linha,40, cabecalho, [Expandido,Negrito]); //AQUI É O CABEÇALHO
      inc(Linha); inc(Linha);
    end;

    // variável para controlar a mudança de registro ´mestre´
    sMestre := ´@.x´;
    Col := 9; // Numero de colunas
    //Inicio := 10; //Começar desse valor (desnecessario)

    //LOOP MAIS IMPORTANTE - M1
    while not MD.DESCARGA_MESTRE.Eof do
    begin
      if Linha > Limite_Linha then
      begin
        novapagina; // Rodapé e Cabeçalho
        sMestre := ´@.x´; // assim repete o "desc_descarga" na nova página
      end;

      //Aqui eu imprimo o Valor de "desc_descarga"
      if MD.DESCARGA_MESTRE.FieldByName(´desc_descarga´).AsString <> sMestre then
      begin
        sMestre := MD.DESCARGA_MESTRE.FieldByName(´desc_descarga´).AsString;
        imp(Linha,01,FormatFloat(´#,,0.00´,StrToFloat(sMestre))+´ - ´);
        F := 1; //Incrementador
      end;

  //    Total := MD.DESCARGA_DETALHE.RecordCount; // variavel desnecessaria
  //    além de desnecessária, tornava o sistema mais lento...

      imp(Linha,10 + (7 * (F - 1)), MD.DESCARGA_MESTRE.FieldByName(´desc_temp_jogo´).AsString);

      Inc(F);

      if F > Col then
      begin
        inc(Linha);
        F := 1;
      end;

      MD.DESCARGA_MESTRE.next;

      if MD.DESCARGA_MESTRE.FieldByName(´desc_descarga´).AsString <> sMestre then
      begin
        imp(Linha,01,´--------------------------------------------------------------------------------´);
        inc(Linha);
      end;
      //FINALIZA VALOR
    end;

  end; // fim do if
end; // fim do for



GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

Simplesmente demais. Tudo certo, tudo ok.

Valeu amigo. Quaannndooo vc poder comentar esse código, acho que vai ajudar muita gente assim como eu.

Do mais, obrigado mesmo.


GOSTEI 0
Gigatel

Gigatel

03/01/2006

akela código atrás é usando em um componete ? ou é akeles métodos de descargas diretas... eu tenho problema tbm de lentidão com impressoras matricias e funciona perfeito com impressoras jato de tinta tbm ? tem como dá uma pequena explicada ? flw....


GOSTEI 0
Martins

Martins

03/01/2006

Simplesmente demais. Tudo certo, tudo ok. Valeu amigo. Quaannndooo vc poder comentar esse código, acho que vai ajudar muita gente assim como eu. Do mais, obrigado mesmo.


Pelo que li, o código do Emerson.en, tá até bem comentado, eu tomou cuidade deixar documentado, e como ele mesmo disse, aquele case poderia se substituído por um vetor, tipo...

array [1..10] of tipodevariavel


GOSTEI 0
Laelsonc

Laelsonc

03/01/2006

Desculpe. Não era comentar, e sim explicar.

Mas pra mim tah ok. Eu debulhei ele pra entender.
Mas a capacidade dos outros não pode ser avaliada pela nossa né.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

03/01/2006

akela código atrás é usando em um componete ? ou é akeles métodos de descargas diretas... eu tenho problema tbm de lentidão com impressoras matricias e funciona perfeito com impressoras jato de tinta tbm ? tem como dá uma pequena explicada ? flw....


sim, amigo. aquele exemplo é para com o RDPrint (por conta de algumas funções utilizadas). mas nada impede essa lógica seja aplicada em qualquer outro.


GOSTEI 0
Gigatel

Gigatel

03/01/2006

[quote:c2d39c8df2=´Gigatel´]akela código atrás é usando em um componete ? ou é akeles métodos de descargas diretas... eu tenho problema tbm de lentidão com impressoras matricias e funciona perfeito com impressoras jato de tinta tbm ? tem como dá uma pequena explicada ? flw....


sim, amigo. aquele exemplo é para com o RDPrint (por conta de algumas funções utilizadas). mas nada impede essa lógica seja aplicada em qualquer outro.[/quote:c2d39c8df2]


Certo... más no quesito rapidez é mesmo para o RDPrint mesmo....num dá para fazer nada no Qreport? num dá para que faça imprimir mais rápido ? flw..


GOSTEI 0
POSTAR