Como fazer um relatório lendo os campos UserLG

Hoje irei mostrar duas formas de se criar um relatório em AdvPL, mostrando os campos de Log de Inclusão e Alteração (USERLGI e USERLGA).

1 – Através de Query SQL (se seu dicionário estiver no Banco)

Essa primeira forma, funciona apenas se seu dicionário estiver no Banco de Dados, pois dessa forma conseguimos fazer um join entre as tabelas para exibir a informação.

Eu até cheguei a mostrar como ver o conteúdo dos campos LGI e LGA no SQL Server (saiba mais clicando aqui).

No caso, nós realizamos o join com a tabela SYS_USR e depois imprimimos a informação. Abaixo um print do resultado no SQL Server (na minha base de testes eu só tenho o usuário Administrador):

Exemplo da query executada

Abaixo o código fonte (nesse exemplo foi usado como base um TReport):

//...
    //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 += "      " + CRLF
    cQryReport += "     USR_I.USR_ID AS USRINC_COD, " + CRLF
    cQryReport += "     USR_I.USR_NOME AS USRINC_NOM, " + CRLF
    cQryReport += "     CASE WHEN SUBSTRING(B1_USERLGI, 03, 1) != ' ' AND B1_USERLGI != '' THEN " + CRLF
    cQryReport += "         CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGI,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGI,16,1)) - 50) + IIF(SUBSTRING(B1_USERLGI,08,1) = '<',10000,0)),'1996-01-01'), 103) " + CRLF
    cQryReport += "     ELSE  " + CRLF
    cQryReport += "         '' " + CRLF
    cQryReport += "     END AS DATA_INCL, " + CRLF
    cQryReport += "      " + CRLF
    cQryReport += "     USR_A.USR_ID AS USRALT_COD, " + CRLF
    cQryReport += "     USR_A.USR_NOME AS USRALT_NOM, " + CRLF
    cQryReport += "     CASE WHEN SUBSTRING(B1_USERLGA, 03, 1) != ' ' AND B1_USERLGA != '' THEN " + CRLF
    cQryReport += "         CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGA,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGA,16,1)) - 50) + IIF(SUBSTRING(B1_USERLGA,08,1) = '<',10000,0)),'1996-01-01'), 103) " + CRLF
    cQryReport += "     ELSE '' " + CRLF
    cQryReport += "     END AS DATA_ALT " + CRLF
    cQryReport += " FROM " + CRLF
    cQryReport += "     " + RetSQLName("SB1") + " SB1 " + CRLF
    cQryReport += "     LEFT JOIN SYS_USR USR_I ON ( " + CRLF
    cQryReport += "         USR_I.USR_ID = ( " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 11, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 15, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 19, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 02, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 06, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 10, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 14, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 01, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 18, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 05, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 09, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 13, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 17, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 04, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGI, 08, 1) " + CRLF
    cQryReport += "         ) " + CRLF
    cQryReport += "     ) " + CRLF
    cQryReport += "     LEFT JOIN SYS_USR USR_A ON ( " + CRLF
    cQryReport += "         USR_A.USR_ID = ( " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 11, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 15, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 19, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 02, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 06, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 10, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 14, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 01, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 18, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 05, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 09, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 13, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 17, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 04, 1) + " + CRLF
    cQryReport += "             SUBSTRING(B1_USERLGA, 08, 1) " + CRLF
    cQryReport += "         ) " + CRLF
    cQryReport += "     ) " + CRLF
    cQryReport += " WHERE " + CRLF
    cQryReport += "     B1_FILIAL = '' " + CRLF
    cQryReport += "     AND B1_MSBLQL != '1' " + CRLF
    cQryReport += "     AND SB1.D_E_L_E_T_ = ' ' " + CRLF
     
    //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())
     
//...

2 – Manualmente durante o While de impressão

A segunda forma, é posicionar na tabela (seja com DbSeek ou DbGoTo) e usar a função FWLeUserLG.

Abaixo o código fonte (nesse exemplo foi usado como base um TReport):

//...
    //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 += " FROM " + CRLF
    cQryReport += "     " + RetSQLName("SB1") + " SB1 " + CRLF
    cQryReport += " WHERE " + CRLF
    cQryReport += "     B1_FILIAL = '' " + CRLF
    cQryReport += "     AND B1_MSBLQL != '1' " + CRLF
    cQryReport += "     AND SB1.D_E_L_E_T_ = ' ' " + CRLF
     
    //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()
         
        //Posicionando no cadastro de produtos
        DbSelectArea('SB1')
        SB1->(DbSetOrder(1))
        SB1->(DbSeek(FWxFilial('SB1') + QRY_REP->B1_COD))
         
        //Obtendo dados da Inclusão e Alteração conforme produto posicionado
        cUsrCodInc := FWLeUserLg("B1_USERLGI", 1)
        cUsrNomInc := UsrRetName(cUsrCodInc)
        cDatInc    := FWLeUserLg("B1_USERLGI", 2)
        cUsrCodAlt := FWLeUserLg("B1_USERLGA", 1)
        cUsrNomAlt := UsrRetName(cUsrCodAlt)
        cDatAlt    := FWLeUserLg("B1_USERLGA", 2)
         
        //Definindo na célula antes da impressão da linha
        oSectDad:Cell("USRINC_COD"):SetValue(cUsrCodInc)
        oSectDad:Cell("USRINC_NOM"):SetValue(cUsrNomInc)
        oSectDad:Cell("USRINC_DAT"):SetValue(cDatInc)
        oSectDad:Cell("USRALT_COD"):SetValue(cUsrCodAlt)
        oSectDad:Cell("USRALT_NOM"):SetValue(cUsrNomAlt)
        oSectDad:Cell("USRALT_DAT"):SetValue(cDatAlt)
         
        //Imprimindo a linha atual
        oSectDad:PrintLine()
         
        QRY_REP->(DbSkip())
    EndDo
    oSectDad:Finish()
    QRY_REP->(DbCloseArea())
     
//...

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.

4 Responses

  1. Súlivan disse:

    Que top hein, dúvida que muita gente tem.

  2. ARLINDO disse:

    não funciona mais a do Banco

Deixe uma resposta

Terminal de Informação