Como fazer zebrado no TReport | Ti Responde 0097

No vídeo de hoje, vamos demonstrar em como fazer um zebrado no fundo da impressão de linhas usando a TReport.

A dúvida de hoje, nos perguntaram, se seria possível imprimir um fundo colorido usando TReport similar ao que é feito com FWMSPrinter.

 

Pensando nisso, montamos esse exemplo, onde demonstramos em como usar uma lógica para que toda vez que for imprimir uma linha, ele zebrar o conteúdo antes da impressão.

 

Segue abaixo o vídeo exemplificando:

 

E abaixo o código fonte desenvolvido:

//Bibliotecas
#Include "Totvs.ch"

/*/{Protheus.doc} User Function zVid0097
Listagem de Cidades
@author Atilio
@since 10/01/2024
@version 1.0
@type function
@obs Codigo gerado automaticamente pelo Autumn Code Maker
@see http://autumncodemaker.com
/*/

User Function zVid0097()
	Local aArea := FWGetArea()
	Local oReport
	Local aPergs   := {}
	Local cEstDe := "  "
	Local cEstAte := "ZZ"
	Local nOrdPor := 1
    Private lPar  := .F.
	
	//Adicionando os parametros do ParamBox
	aAdd(aPergs, {1, "Estado De", cEstDe,  "", ".T.", "12", ".T.", 40,  .F.})
	aAdd(aPergs, {1, "Estado Até", cEstAte,  "", ".T.", "12", ".T.", 40,  .T.})
	aAdd(aPergs, {2, "Ordenar por", nOrdPor, {"1=Nome da Cidade", "2=Código da Cidade"}, 090, ".T.", .T.})
	
	//Se a pergunta for confirma, cria as definicoes do relatorio
	If ParamBox(aPergs, 'Informe os parâmetros', /*aRet*/, /*bOk*/, /*aButtons*/, /*lCentered*/, /*nPosx*/, /*nPosy*/, /*oDlgWizard*/, /*cLoad*/, .F., .F.)
		MV_PAR03 := Val(cValToChar(MV_PAR03))
		oReport := fReportDef()
		oReport:PrintDialog()
	EndIf
	
	FWRestArea(aArea)
Return

/*/{Protheus.doc} fReportDef
Definicoes do relatorio zVid0097
@author Atilio
@since 10/01/2024
@version 1.0
@type function
@obs Codigo gerado automaticamente pelo Autumn Code Maker
@see http://autumncodemaker.com
/*/

Static Function fReportDef()
	Local oReport
	Local oSection := Nil
	Local oBreak
    Local bBloco := {|| lPar := .F.}
	
	//Criacao do componente de impressao
	oReport := TReport():New( "zVid0097",;
		"Listagem de Cidades",;
		,;
		{|oReport| fRepPrint(oReport),};
		)
	oReport:SetTotalInLine(.F.)
	oReport:lParamPage := .F.
	oReport:oPage:SetPaperSize(9)
	
	//Orientacao do Relatorio
	oReport:SetPortrait()
	
	//Criando a secao de dados
	oSection := TRSection():New( oReport,;
		"Dados",;
		{"QRY_REP"})
	oSection:SetTotalInLine(.F.)
	
	//Colunas do relatorio
	TRCell():New(oSection, "CC2_EST", "QRY_REP", "Estado", /*cPicture*/, 2, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .F.)
	TRCell():New(oSection, "CC2_CODMUN", "QRY_REP", "Codigo", /*cPicture*/, 5, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .F.)
	TRCell():New(oSection, "CC2_MUN", "QRY_REP", "Nome", /*cPicture*/, 60, /*lPixel*/, /*{|| code-block de impressao }*/, "LEFT", /*lLineBreak*/, "LEFT", /*lCellBreak*/, /*nColSpace*/, /*lAutoSize*/, /*nClrBack*/, /*nClrFore*/, .F.)
	
	//Quebras do relatorio
	oBreak := TRBreak():New(oSection, oSection:Cell("CC2_EST"), {||""}, .F.)

	//Define que irá imprimir os títulos após a quebra
	oSection:SetHeaderBreak(.T.)

    //Define que na quebra de página, a flag volta a ser ímpar
    oReport:OnPageBreak(bBloco, .T.)
    oBreak:OnBreak(bBloco)

Return oReport

/*/{Protheus.doc} fRepPrint
Impressao do relatorio zVid0097
@author Atilio
@since 10/01/2024
@version 1.0
@type function
@obs Codigo gerado automaticamente pelo Autumn Code Maker
@see http://autumncodemaker.com
/*/

Static Function fRepPrint(oReport)
	Local aArea    := FWGetArea()
	Local cQryReport  := ""
	Local oSectDad := Nil
	Local nAtual   := 0
	Local nTotal   := 0
    //Variáveis usadas no brush, documentações no TDN - https://tdn.totvs.com/display/public/framework/TReport
    Local nLinAtu    := 0
    Local nColIni    := oReport:LeftMargin() //Margem da esquerda, vai ser a coluna inicial
    Local nColFin    := oReport:PageWidth()  //Largura da página, vai ser a coluna final
    Local nEspLin    := oReport:LineHeight() //Espaçamento entre as linhas, para saber a altura que irá pintar
    Local oBrushLin  := TBrush():New(, RGB(215, 245, 243)) //Pincel em um tom de claro

	//Pegando as secoes do relatorio
	oSectDad := oReport:Section(1)
	
	//Montando consulta de dados
	cQryReport := "SELECT "		+ CRLF
	cQryReport += "    CC2_EST, "		+ CRLF
	cQryReport += "    X5_DESCRI, "		+ CRLF
	cQryReport += "    CC2_CODMUN, "		+ CRLF
	cQryReport += "    CC2_MUN "		+ CRLF
	cQryReport += "FROM "		+ CRLF
	cQryReport += "    " + RetSQLName("CC2") + " CC2 "		+ CRLF
	cQryReport += "    INNER JOIN " + RetSQLName("SX5") + " SX5 ON ( "		+ CRLF
	cQryReport += "        X5_FILIAL = '" + FWxFilial("SX5") + "' "		+ CRLF
	cQryReport += "        AND X5_TABELA = '12' "		+ CRLF
	cQryReport += "        AND X5_CHAVE = CC2_EST "		+ CRLF
	cQryReport += "        AND SX5.D_E_L_E_T_ = ' ' "		+ CRLF
	cQryReport += "    ) "		+ CRLF
	cQryReport += "WHERE "		+ CRLF
	cQryReport += "    CC2_FILIAL = '" + FWxFilial("CC2") + "' "		+ CRLF
	cQryReport += "    AND CC2_EST >= '" + MV_PAR01 + "' "		+ CRLF
	cQryReport += "    AND CC2_EST <= '" + MV_PAR02 + "' "		+ CRLF
	cQryReport += "    AND CC2.D_E_L_E_T_ = ' ' "		+ CRLF
	cQryReport += "ORDER BY "		+ CRLF
	cQryReport += "    CC2_EST "		+ CRLF
    If MV_PAR03 == 1
	    cQryReport += "    , CC2_MUN"		+ CRLF
    ElseIf MV_PAR03 == 2
        cQryReport += "    , CC2_CODMUN"		+ CRLF
    EndIf
	
	//Executando consulta e setando o total da regua
	PlsQuery(cQryReport, "QRY_REP")
	DbSelectArea("QRY_REP")
	Count to nTotal
	oReport:SetMeter(nTotal)
	
	//Se houver dados
	QRY_REP->(DbGoTop())
	If ! QRY_REP->(EoF())

		//Temos que acionar a primeira vez o StartPage para poder sair certo o texto do primeiro estado
		//oReport:StartPage() // to-do

		//Enquanto houver dados
		oSectDad:Init()
		While ! QRY_REP->(Eof())
		
			//Incrementando a regua
			nAtual++
			oReport:SetMsgPrint("Imprimindo registro " + cValToChar(nAtual) + " de " + cValToChar(nTotal) + "...")
			oReport:IncMeter()

            //Se for uma linha Par, irá imprimir o fundo
            If lPar
                nLinAtu := oReport:Row() //Pega a linha atual no relatório
                oReport:FillRect({nLinAtu, nColIni, nLinAtu + nEspLin, nColFin}, oBrushLin)
            EndIf
			
			//Imprimindo a linha atual
			oSectDad:PrintLine()

            //Atualiza entre par e ímpar
            lPar := ! lPar
			
			QRY_REP->(DbSkip())
		EndDo
		oSectDad:Finish()
	EndIf
	QRY_REP->(DbCloseArea())

	
	FWRestArea(aArea)
Return

Bom pessoal, por hoje é só.

 

Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

Deixe uma resposta

Terminal de Informação