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):
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 += " CONVERT(VARCHAR,DATEADD(DAY,CONVERT(INT,CONCAT(ASCII(SUBSTRING(B1_USERLGI,12,1)) - 50, ASCII(SUBSTRING(B1_USERLGI,16,1)) - 50)),'1996-01-01'), 112) AS DATA_INC, " + 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) != ' ' THEN " + CRLF cQryReport += " CONVERT(VARCHAR,DATEADD(DAY,((ASCII(SUBSTRING(B1_USERLGA,12,1)) - 50) * 100 + (ASCII(SUBSTRING(B1_USERLGA,16,1)) - 50)),'19960101'),112) " + 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.
Que top hein, dúvida que muita gente tem.
Opa, obrigado pelo feedback Súlivan.
Grande abraço.