No artigo de hoje, vamos demonstrar em como gravar log de alteração de campos dos cadastros de Fornecedores, Clientes, etc através da tabela padrão AIF.
Para habilitar esse recurso, vá no configurador e altere o parâmetro MV_HISTTAB.
Feito isso, ao fazer alterações nos cadastros citados abaixo, será gravado um log de alteração (através da função MSGrvHist):
- SA1 – Clientes – MATA030 / CRMA980
- SA2 – Fornecedores – MATA020
- SA4 – Transportadoras – MATA050
- SA5 – Produtos x Fornecedores – MATA060
- SB1 – Produtos – MATA010
Abaixo um print dos logs salvos:
Para consultar em tela, eu não consegui encontrar uma rotina padrão, então desenvolvi uma rotina em MVC básica para fazer as consultas, sendo que ao abrir, será exibido uma tela de parâmetros caso deseja filtrar o browse.
Feito isso será aberto um browse com os registros.
E ao clicar em Visualizar, ele mostra as informações dos logs.
Abaixo o código fonte desenvolvido:
//Bibliotecas #Include "Totvs.ch" #Include "FWMVCDef.ch" //Variveis Estaticas Static cTitulo := "Logs da AIF" Static cAliasMVC := "AIF" /*/{Protheus.doc} User Function zVerAIF Tela para visualizar logs da AIF @author Atilio @since 07/02/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ User Function zVerAIF() Local aArea := FWGetArea() Local oBrowse Private aRotina := {} //Definicao do menu aRotina := MenuDef() //Instanciando o browse oBrowse := FWMBrowse():New() oBrowse:SetAlias(cAliasMVC) oBrowse:SetDescription(cTitulo) oBrowse:DisableDetails() //Adicionando as Legendas oBrowse:AddLegend( "AIF->AIF_TABELA == 'SA2'", "BLACK", "Fornecedores" ) oBrowse:AddLegend( "AIF->AIF_TABELA == 'SB1'", "BLUE", "Produtos" ) oBrowse:AddLegend( "AIF->AIF_TABELA == 'SA5'", "GREEN", "Produtos x Fornecedores" ) oBrowse:AddLegend( "AIF->AIF_TABELA == 'SA1'", "ORANGE", "Clientes" ) oBrowse:AddLegend( "AIF->AIF_TABELA == 'SA4'", "RED", "Transportadoras" ) //Filtrando o browse cFiltro := fMontaFilt() If ! Empty(cFiltro) oBrowse:SetFilterDefault(cFiltro) EndIf //Ativa a Browse oBrowse:Activate() FWRestArea(aArea) Return Nil /*/{Protheus.doc} MenuDef Menu de opcoes na funcao zVerAIF @author Atilio @since 07/02/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function MenuDef() Local aRotina := {} //Adicionando opcoes do menu ADD OPTION aRotina TITLE "Visualizar" ACTION "VIEWDEF.zVerAIF" OPERATION 1 ACCESS 0 Return aRotina /*/{Protheus.doc} ModelDef Modelo de dados na funcao zVerAIF @author Atilio @since 07/02/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function ModelDef() Local oStruct := FWFormStruct(1, cAliasMVC) Local oModel Local bPre := Nil Local bPos := Nil Local bCommit := Nil Local bCancel := Nil //Cria o modelo de dados para cadastro oModel := MPFormModel():New("zVerAIFM", bPre, bPos, bCommit, bCancel) oModel:AddFields("AIFMASTER", /*cOwner*/, oStruct) oModel:SetDescription("Modelo de dados - " + cTitulo) oModel:GetModel("AIFMASTER"):SetDescription( "Dados de - " + cTitulo) oModel:SetPrimaryKey({}) Return oModel /*/{Protheus.doc} ViewDef Visualizacao de dados na funcao zVerAIF @author Atilio @since 07/02/2023 @version 1.0 @type function @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ Static Function ViewDef() Local oModel := FWLoadModel("zVerAIF") Local oStruct := FWFormStruct(2, cAliasMVC) Local oView //Cria a visualizacao do cadastro oView := FWFormView():New() oView:SetModel(oModel) oView:AddField("VIEW_AIF", oStruct, "AIFMASTER") oView:CreateHorizontalBox("TELA" , 100 ) oView:SetOwnerView("VIEW_AIF", "TELA") Return oView /*/{Protheus.doc} fMontaFilt Função que abre a tela de parâmetros para montagem de filtro no browse @author Atilio @since 07/02/2023 @version 1.0 /*/ Static Function fMontaFilt() Local aArea := FWGetArea() Local cFiltro := "" Local aPergs := {} Local cTabela := Space(TamSX3('AIF_TABELA')[01]) Local cCampo := Space(TamSX3('AIF_CAMPO')[01]) Local dDataDe := FirstDate(MonthSub(Date(), 1)) Local dDataAte := Date() //Adiciona os parâmetros que serão exibidos aAdd(aPergs, {1, "Tabela", cTabela, "", ".T.", "HSPSX2", ".T.", 40, .F.}) aAdd(aPergs, {1, "Campo", cCampo, "", ".T.", "JURSX3", ".T.", 70, .F.}) aAdd(aPergs, {1, "Data De", dDataDe, "", ".T.", "", ".T.", 80, .T.}) aAdd(aPergs, {1, "Data Até", dDataAte, "", ".T.", "", ".T.", 80, .T.}) //Se a pergunta for confirmada If ParamBox(aPergs, "Informe os parâmetros", , , , , , , , , .F., .F.) //Filtro da Tabela If ! Empty(MV_PAR01) cFiltro += "AIF->AIF_TABELA == '" + MV_PAR01 + "'" EndIf //Filtro do campo If ! Empty(MV_PAR02) If ! Empty(cFiltro) cFiltro += " .And. " EndIf cFiltro += "AIF->AIF_CAMPO == '" + MV_PAR02 + "'" EndIf //Filtro da Data De If ! Empty(MV_PAR03) If ! Empty(cFiltro) cFiltro += " .And. " EndIf cFiltro += "AIF->AIF_DATA >= sToD('" + dToS(MV_PAR03) + "')" EndIf //Filtro da Data Até If ! Empty(MV_PAR04) If ! Empty(cFiltro) cFiltro += " .And. " EndIf cFiltro += "AIF->AIF_DATA <= sToD('" + dToS(MV_PAR04) + "')" EndIf EndIf FWRestArea(aArea) Return cFiltro
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Muito boa essa dica, não conhecia essa funcionalidade, valeu Atilio.
Opa, nós que agradecemos pelo comentário.
Um grande abraço.