Nesse vídeo demonstraremos a utilização das classes TReport, TRFunction, TRSection e TRCell, que servem para criar um relatório com opções de imprimir, gerar PDF, gerar Excel, entre outras.
Abaixo o código fonte desenvolvido para o exemplo em vídeo acima:
//Bibliotecas
#Include "TOTVS.ch"
/*/{Protheus.doc} User Function zExe505
Classes para montagem de um relatório com listagem de informações
@type Function
@author Atilio
@since 04/04/2023
@see https://tdn.totvs.com/display/public/framework/TReport e https://tdn.totvs.com/display/public/framework/TRSection e https://tdn.totvs.com/display/public/framework/TRFunction e https://tdn.totvs.com/display/public/framework/TRCell
@obs
**** Apoie nosso projeto, se inscreva em https://www.youtube.com/TerminalDeInformacao ****
/*/
User Function zExe505()
Local aArea := FWGetArea()
Local oReport
Local aPergs := {}
Local cProdDe := Space(TamSX3('B1_COD')[1])
Local cProdAte := StrTran(cProdDe, ' ', 'Z')
Local cTipoDe := Space(TamSX3('B1_TIPO')[1])
Local cTipoAte := StrTran(cTipoDe, ' ', 'Z')
Local nOrden := 1
//Adicionando os parametros do ParamBox
aAdd(aPergs, {1, "Produto De", cProdDe, "", ".T.", "SB1", ".T.", 80, .F.}) // MV_PAR01
aAdd(aPergs, {1, "Produto Até", cProdAte, "", ".T.", "SB1", ".T.", 80, .T.}) // MV_PAR02
aAdd(aPergs, {1, "Tipo De", cTipoDe, "", ".T.", "02", ".T.", 40, .F.}) // MV_PAR03
aAdd(aPergs, {1, "Tipo Até", cTipoAte, "", ".T.", "02", ".T.", 40, .T.}) // MV_PAR04
aAdd(aPergs, {2, "Ordenar por", nOrden, {"1=Código do Produto", "2=Descrição do Produto", "3=Unidade de Medida"}, 100, ".T.", .T.}) // MV_PAR05
//Se a pergunta for confirma, cria as definicoes do relatorio
If ParamBox(aPergs, "Informe os parâmetros", , , , , , , , , .F., .F.)
MV_PAR05 := Val(cValToChar(MV_PAR05))
oReport := fReportDef()
oReport:PrintDialog()
EndIf
FWRestArea(aArea)
Return
Static Function fReportDef()
Local oReport
Local oSection := Nil
//Criacao do componente de impressao
oReport := TReport():New( "zRel02",;
"Relatório de Produto",;
,;
{|oReport| fRepPrint(oReport),};
)
oReport:SetTotalInLine(.F.)
oReport:lParamPage := .F.
oReport:oPage:SetPaperSize(9)
//Orientacao do Relatorio
oReport:SetPortrait()
//Definicoes da fonte utilizada
oReport:SetLineHeight(50)
oReport:nFontBody := 12
//Criando a secao de dados
oSection := TRSection():New( oReport,;
"Dados",;
{"QRY_REP"})
oSection:SetTotalInLine(.F.)
//Colunas do relatorio
TRCell():New(oSection, "B1_COD", "QRY_REP", "Codigo", /*cPicture*/, 15, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .T.)
TRCell():New(oSection, "B1_DESC", "QRY_REP", "Descricao", /*cPicture*/, 30, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .F.)
TRCell():New(oSection, "B1_TIPO", "QRY_REP", "Tipo", /*cPicture*/, 02, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .F.)
TRCell():New(oSection, "TIPODESCR", "QRY_REP", "Tp. Descr.", /*cPicture*/, 55, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .F.)
TRCell():New(oSection, "B1_UM", "QRY_REP", "Unid. Med.", /*cPicture*/, 02, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .F.)
TRCell():New(oSection, "UMDESCR", "QRY_REP", "UM. Descr.", /*cPicture*/, 40, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .F.)
//Quebras do relatorio
oBreak := TRBreak():New(oSection, oSection:Cell("B1_TIPO"), {||"Total da Quebra"}, .F.)
//Totalizadores
TRFunction():New(oSection:Cell("B1_COD"), , "COUNT", , , "@E 999,999,999", , .F.)
Return oReport
Static Function fRepPrint(oReport)
Local aArea := FWGetArea()
Local cQryReport := ""
Local oSectDad := Nil
Local nAtual := 0
Local nTotal := 0
//Pegando as secoes do relatorio
oSectDad := oReport:Section(1)
//Montando consulta de dados
cQryReport += "SELECT " + CRLF
cQryReport += " B1_COD, " + CRLF
cQryReport += " B1_DESC, " + CRLF
cQryReport += " B1_TIPO, " + CRLF
cQryReport += " ISNULL(X5_DESCRI, '') AS TIPODESCR, " + CRLF
cQryReport += " B1_UM, " + CRLF
cQryReport += " ISNULL(AH_DESCPO, '') AS UMDESCR " + CRLF
cQryReport += "FROM " + CRLF
cQryReport += " " + RetSQLName("SB1") + " SB1 " + CRLF
cQryReport += " LEFT JOIN " + RetSQLName("SX5") + " SX5 ON ( " + CRLF
cQryReport += " X5_FILIAL = '" + FWxFilial("SX5") + "' " + CRLF
cQryReport += " AND X5_TABELA = '02' " + CRLF
cQryReport += " AND X5_CHAVE = B1_TIPO " + CRLF
cQryReport += " AND SX5.D_E_L_E_T_ = ' ' " + CRLF
cQryReport += " ) " + CRLF
cQryReport += " LEFT JOIN " + RetSQLName("SAH") + " SAH ON ( " + CRLF
cQryReport += " AH_FILIAL = '" + FWxFilial("SAH") + "' " + CRLF
cQryReport += " AND AH_UNIMED = B1_UM " + CRLF
cQryReport += " AND SAH.D_E_L_E_T_ = ' ' " + CRLF
cQryReport += " ) " + CRLF
cQryReport += "WHERE " + CRLF
cQryReport += " B1_FILIAL = '" + FWxFilial("SB1") + "' " + CRLF
cQryReport += " AND B1_COD >= '" + MV_PAR01 + "' " + CRLF
cQryReport += " AND B1_COD <= '" + MV_PAR02 + "' " + CRLF
cQryReport += " AND B1_TIPO >= '" + MV_PAR03 + "' " + CRLF
cQryReport += " AND B1_TIPO <= '" + MV_PAR04 + "' " + CRLF
cQryReport += " AND B1_MSBLQL != '1' " + CRLF
cQryReport += " AND SB1.D_E_L_E_T_ = ' ' " + CRLF
cQryReport += "ORDER BY " + CRLF
cQryReport += " B1_TIPO, " + CRLF
If MV_PAR05 == 1
cQryReport += " B1_COD " + CRLF
ElseIf MV_PAR05 == 2
cQryReport += " B1_DESC " + CRLF
ElseIf MV_PAR05 == 3
cQryReport += " B1_UM " + CRLF
EndIf
//Executando consulta e setando o total da regua
PlsQuery(cQryReport, "QRY_REP")
DbSelectArea("QRY_REP")
Count to nTotal
oReport:SetMeter(nTotal)
//Enquanto houver dados
oSectDad:Init()
QRY_REP->(DbGoTop())
While ! QRY_REP->(Eof())
//Incrementando a regua
nAtual++
oReport:SetMsgPrint("Imprimindo registro " + cValToChar(nAtual) + " de " + cValToChar(nTotal) + "...")
oReport:IncMeter()
//Imprimindo a linha atual
oSectDad:PrintLine()
QRY_REP->(DbSkip())
EndDo
oSectDad:Finish()
QRY_REP->(DbCloseArea())
FWRestArea(aArea)
Return
Bom pessoal, por hoje é só.
Abraços e até próxima.
eu to duvida no relatório treport e na secao2 eu coloco a mesma coisa que na seção5 mas só a 5 sai do jeito que eu quero
Tipo aqui
TRCell():New(oSection2, “C9_Pedido+C9_SEQUEN” ,””/Onde é buscado o campo */,”Numero O.F” /*Titulo/,/Picture/,20 /Tamanho/,/lPixel/,/{|| bloco-de-impressao }/, “LEFT” /Alinhamento/, .T./lLineBreak ou SetBlock/, “LEFT”, /lCellBreak/, /nColSpace/, /lAutoSize/, /nClrBack/, /nClrForce/, .T./*Negrito = T sem negrito = F */)
TRCell():New(oSection5, “C9_XENTREG” ,””/Onde é buscado o campo */,”** Data Entrega” /Titulo/,/Picture/,20 /Tamanho/,/lPixel/,/{|| bloco-de-impressao }/, “LEFT” /Alinhamento/, .T./lLineBreak ou SetBlock/, “LEFT”, /lCellBreak/, /nColSpace/, /lAutoSize/, /nClrBack/, /nClrForce/, .T./*Negrito = T sem negrito = F */)
Bom dia Matheus, tudo joia?
Eu não me lembro de ter visto nome composto em célula, por exemplo, isso aqui:
Ao invés disso, um teste que eu faria seria, colocar um nome:
E depois dentro do laço de repetição de impressão, antes do PrintLine, exemplo:
oSuaSection:Cell("PEDSEQUEN"):SetValue(SC9->C9_Pedido + SC9->C9_SEQUEN) oSuaSection:PrintLine()Tenha um ótimo e abençoado fim de semana.
Um forte abraço.