Olá pessoal…
Recentemente criei um relatório que compara os campos do grupo de campos (SXG) com o dicionário (SX3), e verifica se há campos diferentes.
O relatório tem dois parâmetros, o se irá trazer todos, somente diferentes ou somente iguais. E se irá considerar também o campo filial.
Abaixo um print do relatório gerado.
Abaixo o código completo.
//Bibliotecas #Include "Protheus.ch" /*/{Protheus.doc} zCompX3XG Função que compara o grupo de campos (SX3 e SXG) @type function @author Atilio @since 02/04/2017 @version 1.0 @example u_zCompX3XG() /*/ User Function zCompX3XG() Local aArea := GetArea() Local oReport Private cPerg := "X_zCompX3XG" fValidPerg(cPerg) //Cria as definições do relatório If Pergunte(cPerg, .T.) oReport := fReportDef() oReport:PrintDialog() EndIf RestArea(aArea) Return /*-------------------------------------------------------------------------------* | Func: fReportDef | | Desc: Função que monta a definição do relatório | *-------------------------------------------------------------------------------*/ Static Function fReportDef() Local oReport Local oSectPar := Nil Local oSectDad := Nil //Criação do componente de impressão oReport := TReport():New( "zCompX3XG",; //Nome do Relatório "Comparação de Grupo de Campos (SX3 x SXG)",; //Título cPerg,; //Pergunte ... Se eu defino a pergunta aqui, será impresso uma página com os parâmetros, conforme privilégio 101 {|oReport| fRepPrint(oReport)},; //Bloco de código que será executado na confirmação da impressão ) //Descrição oReport:SetTotalInLine(.F.) oReport:lParamPage := .F. oReport:oPage:SetPaperSize(9) //Folha A4 oReport:SetPortrait() oReport:SetLineHeight(60) oReport:nFontBody := -16 //Criando a seção de dados oSectPar := TRSection():New( oReport,; //Objeto TReport que a seção pertence "Parâmetros",; //Descrição da seção {}) //Tabelas utilizadas, a primeira será considerada como principal da seção oSectPar:SetTotalInLine(.F.) //Define se os totalizadores serão impressos em linha ou coluna. .F.=Coluna; .T.=Linha //Colunas dos Parâmetros TRCell():New(oSectPar, "XX_PARAM", "", "Parametro", /*Picture*/, 030, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) TRCell():New(oSectPar, "XX_CONTE", "", "Conteudo", /*Picture*/, 030, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) //Criando a seção de dados oSectDad := TRSection():New( oReport,; //Objeto TReport que a seção pertence "Dados",; //Descrição da seção {}) //Tabelas utilizadas, a primeira será considerada como principal da seção oSectDad:SetTotalInLine(.F.) //Define se os totalizadores serão impressos em linha ou coluna. .F.=Coluna; .T.=Linha //Colunas do relatório TRCell():New(oSectDad, "XX_GRUPO", "", "Grupo", /*Picture*/, 003, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) TRCell():New(oSectDad, "XX_GRDES", "", "Grup. Desc.", /*Picture*/, 015, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) TRCell():New(oSectDad, "XX_CAMPO", "", "Campo", /*Picture*/, 010, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) TRCell():New(oSectDad, "XX_CPTIT", "", "Camp. Tit.", /*Picture*/, 012, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) TRCell():New(oSectDad, "XX_GRTAM", "", "Tam. Grupo", /*Picture*/, 003, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) TRCell():New(oSectDad, "XX_CPTAM", "", "Tam. Campo", /*Picture*/, 003, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) TRCell():New(oSectDad, "XX_STATU", "", "Status", /*Picture*/, 015, /*lPixel*/,/*{|| code-block de impressao }*/,/*cAlign*/,/*lLineBreak*/,/*cHeaderAlign */,/*lCellBreak*/,/*nColSpace*/,/*lAutoSize*/,/*nClrBack*/,/*nClrFore*/,/*lBold*/) Return oReport /*-------------------------------------------------------------------------------* | Func: fRepPrint | | Desc: Função que imprime o relatório | *-------------------------------------------------------------------------------*/ Static Function fRepPrint(oReport) Local aArea := GetArea() Local aAreaX3 := SX3->(GetArea()) Local aAreaXG := SXG->(GetArea()) Local oSectPar := Nil Local oSectDad := Nil Local nAtual := 0 Local nTotal := 0 Local nTipo := MV_PAR01 Local lFil := MV_PAR02 == 1 Local cStatus := "" //Pegando as seções do relatório oSectPar := oReport:Section(1) oSectDad := oReport:Section(2) //Parâmetros oSectPar:Init() oSectPar:Cell("XX_PARAM"):SetValue("Tipo?") oSectPar:Cell("XX_CONTE"):SetValue(Iif(nTipo==1, "TODOS", Iif(nTipo==2, "SOMENTE DIFERENTES", "SOMENTE IGUAIS"))) oSectPar:PrintLine() oSectPar:Cell("XX_PARAM"):SetValue("Campo Filial?") oSectPar:Cell("XX_CONTE"):SetValue(Iif(lFil, "SIM", "NAO")) oSectPar:PrintLine() oSectPar:Finish() DbSelectArea("SXG") SXG->(DbSetOrder(1)) //XG_GRUPO DbSelectArea("SX3") SX3->(DbSetOrder(1)) //X3_ARQUIVO+X3_ORDEM SX3->(DbSetFilter({|| X3_GRPSXG != ' ' }, "X3_GRPSXG != ' '")) SX3->(DbGoTop()) //Setando o tamanho da régua Count To nTotal oReport:SetMeter(nTotal) SX3->(DbGoTop()) //Enquanto houver dados oSectDad:Init() While !SX3->(EOF()) nAtual++ oReport:SetMsgPrint("Processando campo "+cValToChar(nAtual)+" de "+cValToChar(nTotal)+" ("+Alltrim(SX3->X3_CAMPO)+")...") oReport:IncMeter() //Se for pular campo de filial If !lFil .And. "_FILIAL" $ SX3->X3_CAMPO SX3->(DbSkip()) Loop EndIf //Se conseguir posicionar no grupo de campso SXG->(DbGoTop()) If SXG->(DbSeek(SX3->X3_GRPSXG)) oSectDad:Cell("XX_GRUPO"):SetValue(SXG->XG_GRUPO) oSectDad:Cell("XX_GRDES"):SetValue(SXG->XG_DESCRI) oSectDad:Cell("XX_CAMPO"):SetValue(SX3->X3_CAMPO) oSectDad:Cell("XX_CPTIT"):SetValue(SX3->X3_TITULO) oSectDad:Cell("XX_GRTAM"):SetValue(SXG->XG_SIZE) oSectDad:Cell("XX_CPTAM"):SetValue(SX3->X3_TAMANHO) oSectDad:Cell("XX_STATU"):SetValue("") //Verificando se é igual ou diferente If SXG->XG_SIZE == SX3->X3_TAMANHO cStatus := "IGUAIS" Else cStatus := "DIFERENTES" EndIf oSectDad:Cell("XX_STATU"):SetValue(cStatus) //Se for todos, ou somente diferentes ou somente iguais If nTipo == 1 .Or. (nTipo == 2 .And. cStatus == "DIFERENTES") .Or. (nTipo == 3 .And. cStatus == "IGUAIS") oSectDad:PrintLine() EndIf EndIf SX3->(DbSkip()) EndDo oSectDad:Finish() SX3->(DbClearFilter()) RestArea(aAreaXG) RestArea(aAreaX3) RestArea(aArea) Return /*---------------------------------------------------------------------* | Func: fValidPerg | | Desc: Função para criação do grupo de perguntas | *---------------------------------------------------------------------*/ Static Function fValidPerg(cPerg) //( cGrupo, cOrdem, cPergunt, cPergSpa, cPergEng, cVar, cTipo, nTamanho, nDecimal, nPreSel, cGSC, cValid, cF3, cGrpSXG, cPyme, cVar01, cDef01, cDefSpa1, cDefEng1, cCnt01, cDef02, cDefSpa2, cDefEng2, cDef03, cDefSpa3, cDefEng3, cDef04, cDefSpa4, cDefEng4, cDef05, cDefSpa5, cDefEng5, aHelpPor, aHelpEng, aHelpSpa, cHelp) PutSx1( cPerg, "01", "Tipo?", "", "", "mv_ch0", "N", 1, 0, 1, "C", "", "", "", "", "mv_par01", "Todos", "", "", "", "Somente Diferentes", "", "", "Somente Iguais", "", "", "", "", "", "", "", "", {}, {}, {}, "") PutSx1( cPerg, "02", "Campo Filial?", "", "", "mv_ch1", "N", 1, 0, 1, "C", "", "", "", "", "mv_par02", "Sim", "", "", "", "Não", "", "", "", "", "", "", "", "", "", "", "", {}, {}, {}, "") Return
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Excelente relatório . ajuda muito na minha migração do p11 x p12
Opa, obrigado Willian.
Um grande abraço.