zReport – Criação de relatórios em 10 minutos em AdvPL

Rotina que monta um relatório TReport através de uma cláusula SQL.


Tela de dados, especificando as colunas

Tela de dados, especificando as colunas

Link da Postagem: Criação de relatórios em 10 minutos em AdvPL

Logs de Atualização:

VersãoDataObservaçãoDownload
1.017/12/2016Criação do projetoClique Aqui
Dan_Atilio
Analista e desenvolvedor de sistemas. Técnico em Informática pelo CTI da Unesp. Graduado em Banco de Dados pela Fatec Bauru. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor do projeto Terminal de Informação, onde são postados tutoriais e notícias envolvendo o mundo da tecnologia.

39 Responses

  1. WAGNER FERREIRA disse:

    Como faço na query para colocar um grupo de pergunta já criado?

    Tenho que filtrar uma data porém não estou conseguindo fazer

    • Dan_Atilio disse:

      Boa noite Wagner, tudo bem?
      Primeiramente, prepare a consulta SQL, por exemplo:

      SELECT * 
      FROM SB1010 
      WHERE B1_COD >= ' ' AND B1_COD <= 'ZZZ'
      

      Ao gerar o código, ele terá as linhas que você pode editar, então edite a linha conforme os parâmetros que você tem, por exemplo.

      cQryAux += " WHERE B1_COD >= ' ' AND B1_COD <= 'ZZZ' "     + STR_PULA
      

      Após isso, altere conforme os parâmetros que você tem.

      cQryAux += " WHERE B1_COD >= '"+MV_PAR01+"' AND B1_COD <= '"+MV_PAR02+"' "     + STR_PULA
      

      Caso queira, no fonte já é criado a variável cPerg, ai você pode colocar uma pergunta que você já tem criada na SX1.

      Private cPerg := "SUA_PERGUNTA"
      

      Espero ter ajudado.
      Abraços.

      • marcello disse:

        Boa tarde, estou com duvida na ferramenta, se puder esclarecer melhor agradeço.
        Fiz uma consulta SQL usando seu exemplo e usei o grupo de parâmetro MTR080 (já existente do protheus)
        SELECT *
        FROM SB1010
        WHERE B1_COD >= ‘ ‘ AND B1_COD <= 'ZZZ'

        Compilei e fui na rotina pra gerar o relatório, ele carregou os parâmetros corretamente. Informei no parâmetro produto De 000008, Produto Até 000008 pois só quero esse produto, mas quando exporto para Excel aparece todos os produtos, ou seja, não obedeceu o parâmetro.

        Estou fazendo alguma coisa errada?

        • Dan_Atilio disse:

          Bom dia Marcello, tudo bem?
          Após gerar o fonte, vc vai ter que alterar o seu filtro, por exemplo, o fonte gerado vai ter esse trecho:

          cQuery += " WHERE B1_COD >= ' ' AND B1_COD <= 'ZZZ' "
          

          Ai você terá que editar e colocar os seus parâmetros (verifique qual MV_PAR é o produto de/até):

          cQuery += " WHERE B1_COD >= '"+MV_PAR01+"' AND B1_COD <= '"+MV_PAR02+"' "
          

          Abraços.

  2. marcello disse:

    Boa tarde, Dan_Atilio
    Obrigado pelo retorno.
    Então mesmo colocando o grupo de perguntas na rotina, depois editar o fonte e colocar os parâmetros pra cada pergunta, por exemplo se tiver pergunta do parâmetro de data emissão, devo fazer a mesma coisa por exemplo no D1_EMISSAO colocando o parâmetro no fonte assim com no B1_COD, correto?

    • Dan_Atilio disse:

      Bom dia Marcello, tudo bem?
      Sim, você deve colocar, lembrando que se o parâmetro não for do tipo Caracter, você tem que usar funções de conversão para concatenar com a string, por exemplo, dToS para parâmetros de data.
      Abraços.

  3. marcello disse:

    Tudo certo, fiz o teste e funcionou. muito obrigado!!

  4. WAGNER FERREIRA disse:

    Bom dia Dan,

    Teria alguma forma de eu criar um relatório com duas sessoes?

    Quando coloco dois selects o programa tá juntando tudo.

    Muito obrigado pela sua atenção.

    • Dan_Atilio disse:

      Boa noite Wagner, tudo bem?
      Existe forma sim, porém nesse aplicativo, ele gera apenas de uma seção. O que você pode fazer, é gerar dois relatórios e ir comparando e adicionar a outra seção a seu relatório.
      Irei anotar, para uma possível atualização, eu adicionar duas seções no aplicativo.
      Abraços.

  5. WAGNER FERREIRA disse:

    Olá Dan,
    Olha eu apurrinhando aqui de novo. rsrsrs

    Estou pesquisando como faço para tirar a d.ref, hora e emissão do relatório.

    Quando gero no excel ele vem no inicio com essas informações, mas nao consigo tirar.

    Me da um help.
    Mais uma vez muiiiiito obrigado e parabens pelo site, está cada dia melhor.

    • Dan_Atilio disse:

      Grande Wagner, tudo bem?
      Rapaz, primeiramente muito obrigado pelo contato e por apreciar o Ti.
      Você já tentou gerar o relatório do Excel em formato Tabela?
      Existe um combo em que você define o tipo de Planilha, faça um teste com o tipo Tabela.
      Abraços.

  6. WAGNER FERREIRA disse:

    Alguem saberia deixar o cabeçalho das células somente na primeira página quando o relatório é gerado em excel? Quando gero ele adiciona uma linha com o cabeçalho das células na quebra de página.

    • Dan_Atilio disse:

      Boa noite Wagner, tudo bem?
      Acho que você pode realizar dois testes.
      1- Gerar o relatório do Excel com o formato tabela, existe um combo na tela do TReport que você define o tipo de planilha Excel que será gerada, tente colocar o tipo Tabela;
      2- Você pode tentar alterar o atributo lXlsHeader do seu objeto do TReport, por exemplo, oReport:lXlsHeader := .F. (essa operação nunca testei);
      Qualquer dúvida, fico à disposição.
      Abraços.

  7. WAGNER FERREIRA disse:

    Bom dia Dan,

    Você teria algum exemplo do programa funcionando junto com o schedule.

    Tenho que enviar de forma automatica mas não estou conseguindo acrescentar o schedule no fonte.

    • Dan_Atilio disse:

      Boa noite Wagner, tudo bem?
      Fiz uma há muito tempo, nem utilizei o SchedDef, utilizei o RPCSetEnv.
      Abaixo o exemplo que fiz (só a user function que está chamando, sem a criação do TReport, que geralmente faço no fReportDef).

      User Function zRAuto()
      	Local aArea := GetArea()
      	Local oReport
      	Local cPara := ""
      	Private cPerg := "X_ZRAUTO"
      	ConOut("> [zRAuto] Início às "+Time()+"!")
      	
      	//Se o dicionário não tiver aberto, faz a conexão para a empresa e filial 01
      	If Select("SX2") == 0
         	 	RPCSetEnv("01", "01", "", "", "", "", {})
      	EndIf 
      	
      	Pergunte(cPerg, .F.)
      	MV_PAR01 := dDataBase	//Data De
      	MV_PAR02 := dDataBase	//Data Até
      	cPara    := "teste@teste.com.br"
      	
      	//Definindo e disparando o TReport
      	oReport := fReportDef()
      	oReport:nRemoteType := NO_REMOTE //Aponta  de  que  forma  o  Server  está  gerando  o  relatório.  Opções:   1-Sem  Remote,  2-Remote Delphi,3-Remote Windows e 4-Remote Linux
      	oReport:cEmail := cPara
      	oReport:nDevice := 3 //1-Arquivo,2-Impressora,3-email,4-Planilha e 5-Html
      	oReport:SetPreview(.F.)
      	oReport:Print(.F., "", .T.)
      	
      	ConOut("> [zRAuto] Término às "+Time()+"!")
      	
      	RestArea(aArea)
      Return
      

      Abraços.

  8. Boa tarde, compilei o fonte porem mesmo chamando a função nao abre, verifiquei no inspetor de objeto e não esta la tambem, sabe oque pode ser ? estou usando o p11.8

  9. marcello disse:

    Dan_Atilio, boa tarde

    Primeiro quero agradecer pela iniciativa, está ótimo o post.
    Eu editei o fonte e após informar os parâmetros de 01/05/2017 até 31/05/2017, o sistema mostra barra de status do andamento… mas está bem longe de finalizar… tanto que eu tenho que derrubar o usuário.. é como se tivesse colocado um período bem maior no parâmetro…
    O que está errado?

  10. marcello disse:

    segue trecho do fonte.

    //Montando consulta de dados
    cQryAux := “”
    cQryAux += “SELECT D2_FILIAL, D2_CLIENTE, D2_ITEM, D2_SERIE, D2_CF, D2_DOC, D2_EMISSAO, D2_COD, B1_COD, D2_QUANT, D2_PRCVEN, D2_TOTAL, D2_TIPO, D2_TP, D2_CONTA, B1_BASE3, A1_GRPTRIB” + STR_PULA
    cQryAux += “FROM SD2010 A” + STR_PULA
    cQryAux += “INNER JOIN SB1010 B” + STR_PULA
    cQryAux += “ON A.D2_COD = B.B1_COD” + STR_PULA
    cQryAux += “AND A.D2_FILIAL = B.B1_FILIAL” + STR_PULA
    cQryAux += “INNER JOIN SA1010 C” + STR_PULA
    cQryAux += “ON A.D2_CLIENTE = C.A1_COD” + STR_PULA
    cQryAux += “AND A.D2_LOJA = C.A1_LOJA” + STR_PULA
    cQryAux += “–AND A.D2_FILIAL = C.A1_FILIAL” + STR_PULA
    cQryAux += “WHERE A.D_E_L_E_T_ = ” AND B.D_E_L_E_T_ = ”” + STR_PULA
    cQryAux += “AND D2_EMISSAO >= ‘”+Dtos(MV_PAR01)+”‘” + STR_PULA
    cQryAux += “AND D2_EMISSAO = ‘”+MV_PAR03+”‘” + STR_PULA
    cQryAux += “AND D2_CF = ‘”+MV_PAR05+”‘” + STR_PULA
    cQryAux += “AND D2_FILIAL <= '"+MV_PAR06+"' " + STR_PULA
    cQryAux := ChangeQuery(cQryAux)

  11. marcello disse:

    Alterado para:
    cQryAux += “SELECT D2_FILIAL, D2_CLIENTE, D2_ITEM, D2_SERIE, D2_CF, D2_DOC, D2_EMISSAO, D2_COD, B1_COD, D2_QUANT, D2_PRCVEN, D2_TOTAL, D2_TIPO, D2_TP, D2_CONTA, B1_BASE3, A1_GRPTRIB” + STR_PULA
    cQryAux += “FROM SD2010 A” + STR_PULA
    cQryAux += “INNER JOIN SB1010 B” + STR_PULA
    cQryAux += “ON A.D2_COD = B.B1_COD” + STR_PULA
    cQryAux += “AND A.D2_FILIAL = B.B1_FILIAL” + STR_PULA
    cQryAux += “INNER JOIN SA1010 C” + STR_PULA
    cQryAux += “ON A.D2_CLIENTE = C.A1_COD” + STR_PULA
    cQryAux += “AND A.D2_LOJA = C.A1_LOJA” + STR_PULA
    cQryAux += “–AND A.D2_FILIAL = C.A1_FILIAL” + STR_PULA
    cQryAux += “WHERE A.D_E_L_E_T_ = ” AND B.D_E_L_E_T_ = ”” + STR_PULA
    cQryAux += “AND D2_EMISSAO >= ‘”+Dtos(MV_PAR01)+”‘” + STR_PULA
    cQryAux += “AND D2_EMISSAO = ‘”+MV_PAR03+”‘” + STR_PULA
    cQryAux += “AND D2_CF = ‘”+MV_PAR05+”‘” + STR_PULA
    cQryAux += “AND D2_FILIAL <= '"+MV_PAR06+"' " + STR_PULA

    • Dan_Atilio disse:

      Então Marcello, foi aquilo que provavelmente você me mandou no e-Mail.
      Estava com um comentário no meio do trecho ( — ). Através disso, quando se usa o ChangeQuery e ele tira os -Enters-, ficou numa linha só, invalidando o resto do seu Where.
      Abraços.

  12. Túlio disse:

    Bom dia Dan, parabéns por compartilhar seu fonte me ajudou bastante,
    sou novato em advpl e estou com uma dúvida, como faço para totalizar um campo por agrupamento ?
    Att, Túlio

    • Dan_Atilio disse:

      Boa noite Túlio, tudo bem?
      Não entendi muito bem a dúvida, mas você pode criar TRFunctions que totalizam, e você pode passar qual é a célula, e inclusive qual é a quebra, caso queira totalizar pela quebra.
      Abaixo os parâmetros do método New, que eu conheço:

      oCell – Objeto da classe TRCell que o totalizador se refere
      cName – Identificação do totalizador
      cFunction – Função que será utilizada pelo totalizador. Exemplo: SUM, COUNT, MAX, MIN
      oBreak – Objeto da classe TRBreak que define em qual quebra o totalizador será impresso
      cTitle – Título do totalizador. Se não informado será utilizado o título da célula que o totalizador se refere
      cPicture – Máscara de impressão do totalizador. Se não informado será utilizado a máscara da célula que o totalizador se refere
      uFormula – Tipo Caracter: Expressão ADVPL para macro execução. Tipo Bloco de código: Bloco de Código com a expressão ADVPL para execução
      lEndSection – Se verdadeiro. Indica se totalizador será impresso na quebra de seção
      lEndReport – Se verdadeiro. Indica se totalizador será impresso no final do relatório
      lEndPage – Se verdadeiro. Indica se totalizador será impresso no final de cada página
      oParent – Objeto da classe TRSection que o totalizador se refere
      bCondition – Bloco de código com a condição de atualização dos valores do totalizador
      lDisable – Se verdadeiro. Define que não irá atualizar os valores do totalizador
      bCanPrint – Bloco de código com a condição de impressão dos valores do totalizador

      Espero ter ajudado.
      Abraços.

  13. Fernando Filho disse:

    Ele faz para duas sessão?

    • Dan_Atilio disse:

      Bom dia Fernando, tudo bem?
      Infelizmente não, talvez futuramente seja adaptado para fazer.
      Mas como o código é open source, caso você necessite, pode dar uma alterada também.
      Um grande abraço.

  14. Herique disse:

    Ele funciona na versão 12 ?

  15. Gilson disse:

    Bom dia,

    Dan,

    você tem este fonte para disponibilizar? Zreport ?

    Atenciosamente,

  16. Rafael Godoy disse:

    Fantástica ferramenta. Recomendo. Muito fácil de usar e relatórios prontos em menos de 10 min.

  17. Rodrigo Pedroso disse:

    Show em Atilio.
    Parabéns.

  18. Amigo meus parabéns excelente ajuda para todos, eu particularmente nunca me dei bem com os desenvolvimentos padrões do Protheus, utilizava o Ireports antes mas era muito trabalhoso configurar. você tem algum modelo no qual é possível fazer cabeçalhos roda-pés ?

Deixe uma resposta