Vamos falar sobre TReport. Será um relatório simples de se fazer, mas ainda assim um bom exemplo para quem esta começando.
No nosso exemplo faremos a impressão do cadastro de Produtos com a opção de filtro de “Produto de?” e “Produto Ate?”. Utilizaremos também o comando PutSx1 para criação das perguntas via programa, caso tenha alguma dúvida a respeito desta função clique aqui e veja o artigo no qual explicamos o seu funcionamento.
Neste exemplo precisaremos de dois includes. O TopConn.ch e o Protheus.ch.
A primeira parte do programa ficará da seguinte forma.
#INCLUDE "Topconn.ch" #INCLUDE "Protheus.ch" /* ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ±±ÉÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍ»±± ±±ºPrograma ³RCOMR01 ºAutor ³ Vinícius Moreira º Data ³ 12/11/2013 º±± ±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍ͹±± ±±ºDesc. ³ Impressão de cadastro de produtos em TReport simples. º±± ±±º ³ º±± ±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹±± ±±ºUso ³ AcademiaERP º±± ±±ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ±± ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß */ User Function RCOMR01() //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³Declaracao de variaveis ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Private oReport := Nil Private oSecCab := Nil Private cPerg := PadR ("RCOMR01", Len (SX1->X1_GRUPO)) //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³Criacao e apresentacao das perguntas ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ PutSx1(cPerg,"01","Código de?" ,'','',"mv_ch1","C",TamSx3 ("B1_COD")[1] ,0,,"G","","SB1","","","mv_par01","","","","","","","","","","","","","","","","") PutSx1(cPerg,"02","Código ate?" ,'','',"mv_ch2","C",TamSx3 ("B1_COD")[1] ,0,,"G","","SB1","","","mv_par02","","","","","","","","","","","","","","","","") //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³Definicoes/preparacao para impressao ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ReportDef() oReport:PrintDialog() Return Nil
Note que neste primeiro trecho temos a definição de algumas variáveis para controle do relatório e também chamamos a função ReportDef e a função PrintDialog que pertence ao objeto oReport.
- ReportDef -> Nesta função nos definimos a estrutura do relatório, por exemplo as seções, campos, totalizadores e etc.
- PrintDialog -> Essa função serve para disparar a impressão do TReport, ela que faz com que seja exibida a tela de configuração de impressora e os botões de parâmetros.
Abaixo é possível visualizar a função ReportDef do nosso exemplo. Dentro dela carregamos a variável criada anteriormente com o nome de oReport que serve para controle do relatório, carregamos também a variável oSecCab que serve para controle da seção e criamos os campos da seção através da função TRCell. Então para adicionar novos campos é só adicionar mais comandos TRCell com os parâmetros de acordo com o campo que precisa e para remover é só remover as linhas do TRCell que você não quer mais. Lembre-se de inserir os novos campos também na query que veremos mais pra frente neste artigo. Para aprender mais sobre o TRCell utilize este link aqui do site Tdn da Totvs.
Dentro da função ReportDef também temos a criação de um totalizador, para contagem da quantidade de registros exibidos, através da função TRFunction. Existem outros tipos de totalizadores que podem ser utilizados com a função TRFunction e vocês podem aprender mais sobre eles neste link aqui do site Tdn da Totvs.
/* ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ±±ÉÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍ»±± ±±ºPrograma ³ReportDef ºAutor ³ Vinícius Moreira º Data ³ 12/11/2013 º±± ±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍ͹±± ±±ºDesc. ³ Definição da estrutura do relatório. º±± ±±º ³ º±± ±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹±± ±±ºUso ³ º±± ±±ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ±± ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß */ Static Function ReportDef() oReport := TReport():New("RCOMR01","Cadastro de Produtos",cPerg,{|oReport| PrintReport(oReport)},"Impressão de cadastro de produtos em TReport simples.") oReport:SetLandscape(.T.) oSecCab := TRSection():New( oReport , "Produtos", {"QRY"} ) TRCell():New( oSecCab, "B1_COD" , "QRY") TRCell():New( oSecCab, "B1_DESC" , "QRY") TRCell():New( oSecCab, "B1_TIPO" , "QRY") TRCell():New( oSecCab, "B1_UM" , "QRY") //TRFunction():New(/*Cell*/ ,/*cId*/,/*Function*/,/*oBreak*/,/*cTitle*/,/*cPicture*/,/*uFormula*/,/*lEndSection*/,/*lEndReport*/,/*lEndPage*/,/*Section*/) TRFunction():New(oSecCab:Cell("B1_COD"),/*cId*/,"COUNT" ,/*oBreak*/,/*cTitle*/,/*cPicture*/,/*uFormula*/,.F. ,.T. ,.F. ,oSecCab) Return Nil
Tendo feita a definição da estrutura do relatório na ReportDef criaremos a PrintReport para realizar a busca dos registros que deverão ser impressos. Repare que na função abaixo, existe uma query que é a responsável por carregar os registros e depois apenas passamos esta query e seu alias para o TReport utilizando as funções BeginQuery e EndQuery. Depois é chamada a função Print que dispara a impressão. Neste exemplo, o alias da query é o mesmo alias que informamos na chamada da função TRSection dentro da nossa ReportDef.
/* ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ±±ÉÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍ»±± ±±ºPrograma ³RCOMR01 ºAutor ³ Vinícius Moreira º Data ³ 12/11/2013 º±± ±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍ͹±± ±±ºDesc. ³ º±± ±±º ³ º±± ±±ÌÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹±± ±±ºUso ³ º±± ±±ÈÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ±± ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß */ Static Function PrintReport(oReport) Local cQuery := "" Pergunte(cPerg,.F.) cQuery += " SELECT " + CRLF cQuery += " SB1.B1_COD " + CRLF cQuery += " ,SB1.B1_DESC " + CRLF cQuery += " ,SB1.B1_TIPO " + CRLF cQuery += " ,SB1.B1_UM " + CRLF cQuery += " FROM " + RetSqlName("SB1") + " SB1 " + CRLF cQuery += " WHERE SB1.B1_FILIAL = '" + xFilial ("SB1") + "' " + CRLF cQuery += " AND SB1.B1_COD BETWEEN '" + mv_par01 + "' AND '" + mv_par02 + "' " + CRLF cQuery += " AND SB1.D_E_L_E_T_ = ' ' " + CRLF cQuery := ChangeQuery(cQuery) If Select("QRY") > 0 Dbselectarea("QRY") QRY->(DbClosearea()) EndIf TcQuery cQuery New Alias "QRY" oSecCab:BeginQuery() oSecCab:EndQuery({{"QRY"},cQuery}) oSecCab:Print() Return Nil
Esse é o resultado da impressão do relatório TReport normal.
Esse é o resultado da geração do relatório TReport em planilha com o formato tabela.
Bom galera agora é com vocês, baixem o fonte aqui e realizem alguns testes para aprenderem um pouco mais.
Abraço
Bom dia , otimo post sou novo no advpl e me ajudou muito porém estou com uma duvida como relacionar 2 tabelas na query para o Treport no caso eu quero relacionar a SA1 + SF2 para criar um relatorio de clientes inativos no sistema
Voce pode colocar os inner joins na query com as tabelas que desejar.
Ótimo, como faço para criar um totalizador de quantidade de registros exibidos pelo SIGARPM, vi que no seu código ele calcula esse total, mas não achei como fazer isso pelo SIGARPM.
Opa, voce precisa utilizar o trecho do programa, onde tem a função TRFunction…
Ela que gera o totalizador no fonte, voce precisará apenas ver se quer usar o COUNT, SUM e\ou etc…
Dê uma olhada nas opções disponíveis para isso lá no TDN.
Abraço
Muito obrigado
Consegui entender bem como o TReport funciona. Esse guia foi o melhor guia que encontrei, precisava atualizar um relatório escrito com SetPrint para TReport, a idéia de como montar a Query para consulta ficou bem mais claro e mais próxima do que se faz com SetPrint.
Valeu Paulo, fico feliz em ter ajudado.
Abraço.
Vinícius parabéns e muito obrigado..
Esse exemplo que você chama como “simples”..rs abre muito para inicio de aprendizado, ideias e assim vai.
Abraço
Opa galera, bom que curtiram…
Em breve colocaremos alguns conceitos mais avançados do TReport.
Abraço
Muito bom!!!
Bacana gostei ficou simples para entender.
Gostei demais da dica.. quando puder me envie mais..