No vídeo de hoje, vamos demonstrar em como configurar em um mesmo relatório em FWMSPrinter para que saia como paisagem ou retrato usando a FWPrintSetup.
A dúvida de hoje, nos perguntaram, conforme o exemplo do Ti Responde 73, se seria possível fazer a impressão entre paisagem e retrato, mas colocando do tipo Spool e usando a configuração escolhida na FWPrintSetup.
Pensando nisso, montamos um exemplo, onde é definido através da FWPrintSetup se a orientação vai ser em paisagem ou retrato e em qual impressora imprimir.
Segue abaixo o vídeo exemplificando:
E abaixo o código fonte desenvolvido:
//Bibliotecas #Include "Totvs.ch" #Include "TopConn.ch" #Include "RPTDef.ch" #Include "FWPrintSetup.ch" //Alinhamentos #Define PAD_LEFT 0 #Define PAD_RIGHT 1 #Define PAD_CENTER 2 #Define PAD_JUSTIFY 3 //Opção disponível somente a partir da versão 1.6.2 da TOTVS Printer //Cor(es) Static nCorCinza := RGB(110, 110, 110) Static nCorLinha := RGB(204, 255, 214) //Variável de setup que será acionada na primeira impressão Static oSetupRel /*/{Protheus.doc} User Function zVid0147 Exemplo de Paisagem (800 pixels) e Retrato (580 pixels de largura) - baseado no zVid0147 @author Atilio @since 20/11/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ User Function zVid0147() Local aArea := FWGetArea() Local aPergs := {} Local cProdDe := Space(TamSX3("B1_COD")[1]) Local cProdAte := StrTran(cProdDe, " ", "Z") //Adicionando os parametros do ParamBox aAdd(aPergs, {1, "Produto De", cProdDe, "", ".T.", "SB1", ".T.", 80, .F.}) aAdd(aPergs, {1, "Produto Até", cProdAte, "", ".T.", "SB1", ".T.", 80, .T.}) //Se a pergunta for confirma, cria o relatorio If ParamBox(aPergs, 'Informe os parâmetros', /*aRet*/, /*bOk*/, /*aButtons*/, /*lCentered*/, /*nPosx*/, /*nPosy*/, /*oDlgWizard*/, /*cLoad*/, .F., .F.) Processa({|| fImprime()}) EndIf FWRestArea(aArea) Return /*/{Protheus.doc} fImprime Faz a impressão do relatório zVid0147 @author Atilio @since 20/11/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function fImprime() Local aArea := FWGetArea() Local nTotAux := 0 Local nAtuAux := 0 Local cQryAux := '' Private lRetrato := .F. Private oPrintPvt Private oBrushLin := TBrush():New(,nCorLinha) Private cHoraEx := Time() Private nPagAtu := 1 Private cLogoEmp := fLogoEmp() //Linhas e colunas Private nLinAtu := 0 Private nLinFin := 0 Private nColIni := 0 Private nColFin := 0 Private nColMeio := 0 //Colunas dos relatorio Private nColCodPro := 0 Private nColDescri := 0 Private nColTipPro := 0 Private nColUniMed := 0 //Declarando as fontes Private cNomeFont := 'Arial' Private oFontDet := TFont():New(cNomeFont, /*uPar2*/, -11, /*uPar4*/, .F., /*uPar6*/, /*uPar7*/, /*uPar8*/, /*uPar9*/, .F.) Private oFontDetN := TFont():New(cNomeFont, /*uPar2*/, -13, /*uPar4*/, .T., /*uPar6*/, /*uPar7*/, /*uPar8*/, /*uPar9*/, .F.) Private oFontRod := TFont():New(cNomeFont, /*uPar2*/, -8, /*uPar4*/, .F., /*uPar6*/, /*uPar7*/, /*uPar8*/, /*uPar9*/, .F.) Private oFontMin := TFont():New(cNomeFont, /*uPar2*/, -7, /*uPar4*/, .F., /*uPar6*/, /*uPar7*/, /*uPar8*/, /*uPar9*/, .F.) Private oFontTit := TFont():New(cNomeFont, /*uPar2*/, -15, /*uPar4*/, .T., /*uPar6*/, /*uPar7*/, /*uPar8*/, /*uPar9*/, .F.) //Zera o Setup oSetupRel := Nil While ValType(oSetupRel) == 'U' fConfImpr() EndDo //Busca do Setup a configuração lRetrato := oSetupRel:aOptions[PD_ORIENTATION] == 1 //Se for Retrato If lRetrato nLinAtu := 0 nLinFin := 800 nColIni := 010 nColFin := 580 nColMeio := (nColFin-nColIni)/2 nColCodPro := nColIni nColDescri := nColCodPro + 050 nColTipPro := nColDescri + 200 nColUniMed := nColTipPro + 050 //Se for Paisagem Else nLinAtu := 0 nLinFin := 580 nColIni := 010 nColFin := 820 nColMeio := (nColFin-nColIni)/2 nColCodPro := nColIni nColDescri := nColCodPro + 080 nColTipPro := nColDescri + 300 nColUniMed := nColTipPro + 080 EndIf //Monta a consulta de dados cQryAux += "SELECT " + CRLF cQryAux += " B1_COD, B1_DESC, B1_TIPO, B1_UM " + CRLF cQryAux += "FROM " + CRLF cQryAux += " " + RetSQLName("SB1") + " SB1 " + CRLF cQryAux += "WHERE " + CRLF cQryAux += " B1_FILIAL = '" + FWxFilial("SB1") + "' " + CRLF cQryAux += " AND B1_COD >= '" + MV_PAR01 + "' " + CRLF cQryAux += " AND B1_COD <= '" + MV_PAR02 + "' " + CRLF cQryAux += " AND B1_MSBLQL != '1' " + CRLF cQryAux += " AND SB1.D_E_L_E_T_ = ' '" + CRLF PLSQuery(cQryAux, 'QRY_AUX') //Define o tamanho da régua DbSelectArea('QRY_AUX') QRY_AUX->(DbGoTop()) Count to nTotAux ProcRegua(nTotAux) QRY_AUX->(DbGoTop()) //Somente se tiver dados If ! QRY_AUX->(EoF()) //Criando a impressão oPrintPvt := FWMSPrinter():New(; 'RELATORIO_0147',; // cFilePrintert ,; // nDevice .F.,; // lAdjustToLegacy GetTempPath(),; // cPathInServer .T.; // lDisabeSetup ) //Puxa as definições da impressora If oSetupRel:GetProperty(PD_PRINTTYPE) == IMP_SPOOL oPrintPvt:nDevice := IMP_SPOOL oPrintPvt:cPrinter := oSetupRel:aOptions[PD_VALUETYPE] EndIf //Se for Retrato If lRetrato oPrintPvt:SetPortrait() //Se for Paisagem Else oPrintPvt:SetLandscape() EndIf //Imprime os dados fImpCab() While ! QRY_AUX->(EoF()) nAtuAux++ IncProc('Imprimindo registro ' + cValToChar(nAtuAux) + ' de ' + cValToChar(nTotAux) + '...') //Se atingiu o limite, quebra de pagina fQuebra() //Faz o zebrado ao fundo If nAtuAux % 2 == 0 oPrintPvt:FillRect({nLinAtu - 2, nColIni, nLinAtu + 12, nColFin}, oBrushLin) EndIf //Imprime a linha atual oPrintPvt:SayAlign(nLinAtu, nColCodPro, Alltrim(QRY_AUX->B1_COD), oFontDetN, (nColDescri - nColCodPro), 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColDescri, Alltrim(QRY_AUX->B1_DESC), oFontDet, (nColTipPro - nColDescri), 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColTipPro, Alltrim(QRY_AUX->B1_TIPO), oFontDet, (nColUniMed - nColTipPro), 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColUniMed, Alltrim(QRY_AUX->B1_UM), oFontDet, (nColFin - nColUniMed), 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) nLinAtu += 15 oPrintPvt:Line(nLinAtu-3, nColIni, nLinAtu-3, nColFin, nCorCinza) //Se atingiu o limite, quebra de pagina fQuebra() QRY_AUX->(DbSkip()) EndDo fImpRod() oPrintPvt:Preview() Else FWAlertError('Não foi encontrado informações com os parâmetros informados!', 'Atenção') EndIf QRY_AUX->(DbCloseArea()) FWRestArea(aArea) Return /*/{Protheus.doc} fLogoEmp Função que retorna o logo da empresa conforme configuração da DANFE @author Atilio @since 20/11/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function fLogoEmp() Local cLogo := '\x_imagens\logo.png' Return cLogo /*/{Protheus.doc} fImpCab Função que imprime o cabeçalho do relatório @author Atilio @since 20/11/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function fImpCab() Local cTexto := '' Local nLinCab := 015 //Iniciando Pagina oPrintPvt:StartPage() //Imprime o logo If File(cLogoEmp) oPrintPvt:SayBitmap(015, nColIni, cLogoEmp, 020, 020) EndIf //Cabecalho cTexto := 'Listagem de Produtos' oPrintPvt:SayAlign(nLinCab, nColMeio-200, cTexto, oFontTit, 400, 20, /*nClrText*/, PAD_CENTER, /*nAlignVert*/) //Linha Separatoria nLinCab += 020 oPrintPvt:Line(nLinCab, nColIni, nLinCab, nColFin) //Atualizando a linha inicial do relatorio nLinAtu := nLinCab + 5 If nPagAtu == 1 //Imprimindo os parâmetros oPrintPvt:SayAlign(nLinAtu, nColIni, 'Produto De', oFontDetN, 200, 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColIni+200, MV_PAR01, oFontDet, 200, 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) nLinAtu += 15 oPrintPvt:SayAlign(nLinAtu, nColIni, 'Produto Até', oFontDetN, 200, 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColIni+200, MV_PAR02, oFontDet, 200, 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) nLinAtu += 15 cTexto := "" If lRetrato cTexto := "1 - Retrato" Else cTexto := "2 - Paisagem" EndIf oPrintPvt:SayAlign(nLinAtu, nColIni, 'Tipo do Relatório', oFontDetN, 200, 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColIni+200, cTexto, oFontDet, 200, 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) nLinAtu += 15 oPrintPvt:Line(nLinAtu-3, nColIni, nLinAtu-3, nColFin, nCorCinza) nLinAtu += 5 EndIf oPrintPvt:SayAlign(nLinAtu, nColCodPro, 'Codigo', oFontMin, (nColDescri - nColCodPro), 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColDescri, 'Descricao', oFontMin, (nColTipPro - nColDescri), 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColTipPro, 'Tipo', oFontMin, (nColUniMed - nColTipPro), 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) oPrintPvt:SayAlign(nLinAtu, nColUniMed, 'Unid.Medida', oFontMin, (nColFin - nColUniMed), 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) nLinAtu += 15 Return /*/{Protheus.doc} fImpRod Função que imprime o rodapé e encerra a página @author Atilio @since 20/11/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function fImpRod() Local nLinRod:= nLinFin Local cTexto := '' //Linha Separatoria oPrintPvt:Line(nLinRod, nColIni, nLinRod, nColFin) nLinRod += 3 //Dados da Esquerda cTexto := dToC(dDataBase) + ' ' + cHoraEx + ' ' + FunName() + ' (zVid0147) ' + UsrRetName(RetCodUsr()) oPrintPvt:SayAlign(nLinRod, nColIni, cTexto, oFontRod, 500, 10, /*nClrText*/, PAD_LEFT, /*nAlignVert*/) //Direita cTexto := 'Pagina '+cValToChar(nPagAtu) oPrintPvt:SayAlign(nLinRod, nColFin-40, cTexto, oFontRod, 040, 10, /*nClrText*/, PAD_RIGHT, /*nAlignVert*/) //Finalizando a pagina e somando mais um oPrintPvt:EndPage() nPagAtu++ Return /*/{Protheus.doc} fQuebra Função que valida se a linha esta próxima do final, se sim quebra a página @author Atilio @since 20/11/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function fQuebra() If nLinAtu >= nLinFin-10 fImpRod() fImpCab() EndIf Return /*/{Protheus.doc} fConfImpr Abre a tela para selecionar a impressora da zZebra @author Daniel Atilio @since 13/02/2024 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function fConfImpr() Local aArea := FWGetArea() Local aDevice := {'DISCO', 'SPOOL', 'EMAIL', 'EXCEL', 'HTML', 'PDF'} Local oSetup Local cSession := GetPrinterSession() Local cDevice := If(Empty(fwGetProfString(cSession,'PRINTTYPE','SPOOL',.T.)),'PDF',fwGetProfString(cSession,'PRINTTYPE','SPOOL',.T.)) Local nPrintType := aScan(aDevice, {|x| x == cDevice }) Local nOrientation := 1 //If(fwGetProfString(cSession, 'ORIENTATION', 'PORTRAIT', .T.) == 'PORTRAIT', 1, 2) Local nLocal := 2 //If(fwGetProfString(cSession, 'LOCAL', 'SERVER', .T.) == 'SERVER', 1, 2) Local nFlags := PD_ISTOTVSPRINTER + PD_DISABLEPAPERSIZE + PD_DISABLEPREVIEW + PD_DISABLEMARGIN //Cria o setup do relatório oSetup := FWPrintSetup():New(nFlags, 'TST_IMPRESSORA') oSetup:SetPropert(PD_DESTINATION , nLocal) oSetup:SetPropert(PD_ORIENTATION , nOrientation) oSetup:SetPropert(PD_PRINTTYPE , nPrintType) oSetup:SetPropert(PD_MARGIN , {0,0,0,0}) oSetupRel := Nil //Se a tela for confirmada, atualiza o setup default do relatório If oSetup:Activate() == PD_OK If oSetup:GetProperty(PD_PRINTTYPE) == IMP_SPOOL .And. oSetup:GetProperty(PD_DESTINATION) == 2 oSetupRel := oSetup Else FWAlertInfo('Escolha o tipo SPOOL e LOCAL para impressão!') EndIf EndIf FWRestArea(aArea) Return
Bom pessoal, por hoje é só.
Abraços e até a próxima.