Deixar pré-salvo os dados em uma tela | Ti Responde 0204

No vídeo de hoje, vamos demonstrar em como deixar os dados de uma grid de uma tela pré salva, para que caso a tela seja fechada, seja possível recuperar o que foi digitado.

A dúvida de hoje, nos perguntaram, se seria possível em uma customização, por exemplo no Documento de Entrada, ao digitar os produtos, por algum motivo o usuário precisou fechar a tela, ou o sistema caiu devido a timeout, e ai ele perdeu tudo o que digitou, então teria alguma forma de recuperar essa informação digitada?

 

Pensando nisso, montamos um exemplo, onde vamos mostrar em como salvar um txt temporário na máquina do usuário e através de dois pontos de entrada, um para gravar a informação e outro para fazer a leitura quando necessário, preenchendo a grid.

 

Segue abaixo o vídeo exemplificando:

 

E abaixo o código fonte desenvolvido:

//Bibliotecas
#Include "TOTVS.ch"

/*/{Protheus.doc} User Function MA103BUT
Adiciona botões dentro da tela de manipulação do Documento de Entrada
@type  Function
@author Atilio
@since 19/08/2024
@version version
@see https://tdn.totvs.com/pages/releaseview.action?pageId=102269141
/*/

User Function MA103BUT()
	Local aArea   := FWGetArea()
	Local aAreaF1 := SF1->(FWGetArea())
	Local aAreaD1 := SD1->(FWGetArea())
    Local aBotoes := {}

    //Adiciona no array de botões do Outras Ações
	aAdd(aBotoes, {"BUDGETY", {|| U_zVid0204(.F.)} , "* Buscar Produtos Informados" })

	FWRestArea(aAreaD1)
	FWRestArea(aAreaF1)
	FWRestArea(aArea)
Return aBotoes

/*/{Protheus.doc} User Function MT100LOK
Ponto de Entrada na validação da linha do documento de entrada
@type  Function
@author Atilio
@since 19/08/2024
@version version
@see https://tdn.totvs.com/pages/releaseview.action?pageId=6085397
/*/

User Function MT100LOK()
	Local aArea   := FWGetArea()
	Local aAreaF1 := SF1->(FWGetArea())
	Local aAreaD1 := SD1->(FWGetArea())
    Local lRet    := .T.

    //Se não tiver sendo acionado pela própria função de popular a grid
	If ! FWIsInCallStack("U_zVid0204")
		u_zVid0204(.T.)
	EndIf
	
	FWRestArea(aAreaD1)
	FWRestArea(aAreaF1)
	FWRestArea(aArea)
Return lRet

/*/{Protheus.doc} User Function zVid0204
Grava ou le os produtos que estavam informados na grid do documento de entrada
@type  Function
@author Atilio
@since 17/08/2024
@param lGravar, Lógico, Define se vai gravar o log (.T.) ou vai ler (.F.)
/*/

User Function zVid0204(lGravar)
    Local aArea       := FWGetArea()
    Local cUsrAtu     := RetCodUsr()
    Local cUsrsLog    := SuperGetMV("MV_X_USENT", .F., "000000;")
    Private cPastaTmp := GetTempPath() + "entr_" + dToS(Date()) + "\"
    Default lGravar   := .F.
    
    //Se não for processo automático
    If ! IsBlind() .And. ! l103Auto
        //Se o usuário tiver nos logs
        If cUsrAtu $ cUsrsLog

            //Se a pasta não existir, cria
            If ! ExistDir(cPastaTmp)
                MakeDir(cPastaTmp)
            EndIf

            //Se for para gravar o log
            If lGravar
                //Somente se tiver mais de uma linha
                fGravaLog()
            Else
                //Somente se foi iniciado o cálculo fiscal (tiver inserido um produto)
                If ! Empty(aCols[1][GDFieldPos("D1_COD")])
                    fBuscaLog()
                Else
                    ExibeHelp("Help u_zVid0204", "Não foi inicializado os cálculos fiscais!", "Insira ao menos 1 produto na primeira linha!")
                EndIf
            EndIf

        Else
            If ! lGravar
                ExibeHelp("Help u_zVid0204", "Usuário sem acesso nessa rotina!", "Contate o Administrador (parâmetro MV_X_USENT)!")
            EndIf
        EndIf
    EndIf

    FWRestArea(aArea)
Return

Static Function fGravaLog()
    Local cArquiTmp := cA100For + "_" + cNFiscal + "_" + cSerie + ".txt"
    Local cTexto    := ""
    Local nAtual    := 0
    Local aColsAux  := aClone(aCols)
    Local nPosItem  := GDFieldPos("D1_ITEM")
    Local nPosProd  := GDFieldPos("D1_COD")
    Local nPosQtde  := GDFieldPos("D1_QUANT")
    Local nPosVUni  := GDFieldPos("D1_VUNIT")
    Local nPosCTES  := GDFieldPos("D1_TES")
    Local nPosPedi  := GDFieldPos("D1_PEDIDO")
    Local nPosIPed  := GDFieldPos("D1_ITEMPC")
    Local nPosCFOP  := GDFieldPos("D1_CF")
    Local nPosDele  := Len(aHeader) + 1

    //Percorre as linhas, e se não tiver excluida, grava na variável
    For nAtual := 1 To Len(aColsAux)
        If ! aColsAux[nAtual][nPosDele]
            cTexto += aColsAux[nAtual][nPosItem] + ";"
            cTexto += aColsAux[nAtual][nPosProd] + ";"
            cTexto += cValToChar(aColsAux[nAtual][nPosQtde]) + ";"
            cTexto += cValToChar(aColsAux[nAtual][nPosVUni]) + ";"
            cTexto += aColsAux[nAtual][nPosCTES] + ";"
            cTexto += aColsAux[nAtual][nPosPedi] + ";"
            cTexto += aColsAux[nAtual][nPosIPed] + ";"
            cTexto += aColsAux[nAtual][nPosCFOP] + ";"
            cTexto += CRLF
        EndIf
    Next

    //Gera o arquivo texto
    MemoWrite(cPastaTmp + cArquiTmp, cTexto)
Return

Static Function fBuscaLog()
    Processa( {|| fLeArquiv()}, "Lendo arquivo...")
Return

Static Function fLeArquiv()
    Local nAtual   := 0
    Local cArquivo := cPastaTmp + cA100For + "_" + cNFiscal + "_" + cSerie + ".txt"
    Local oFile
    Local nColuna   := 0
    Local aCampos   := {"D1_ITEM", "D1_COD", "D1_QUANT", "D1_VUNIT", "D1_TES", "D1_PEDIDO", "D1_ITEMPC", "D1_CF"}
    Local aLinMold  := aClone(aCols[1])
    Local aDadosAux := {}
    Local cCampo    := ""
    Local nPosCampo := 0

    //Somente se o arquivo existir
    If File(cArquivo)
        //Abrindo o arquivo
        oFile := FWFileReader():New(cArquivo)

        //Se o arquivo pode ser aberto
        If (oFile:Open())

            //Se não for fim do arquivo
            If ! (oFile:EoF())
                //Zera o aCols
                aCols := {}
                MaFisClear()

                //Definindo o tamanho da régua
                aLinhas := oFile:GetAllLines()
                ProcRegua(Len(aLinhas))

                //Método GoTop não funciona, deve fechar e abrir novamente o arquivo
                oFile:Close()
                oFile := FWFileReader():New(cArquivo)
                oFile:Open()

                While (oFile:HasLine())
                
                    //Incrementando a régua
                    nAtual++
                    IncProc("Analisando linha " + cValToChar(nAtual) + " de " + cValToChar(Len(aLinhas)) + "...")
                    
                    //Buscando o texto da linha atual
                    cLinAtu := oFile:GetLine()

                    //Se tiver conteúdo na linha atual
                    If ! Empty(cLinAtu)
                        aDadosAux := Separa(cLinAtu, ";")

                        //Se tiver a mesma quantidade de campos
                        If Len(aDadosAux) >= Len(aCampos)
                            //Adiciona uma linha no aCols
                            aAdd(aCols, aClone(aLinMold))
                            n := Len(aCols)
                            //oGetDados:oBrowse:nAt := n

                            //Define o produto e aciona as validações e gatilhos
                            MaFisIniLoad(n)
                            For nColuna := 1 To Len(aCampos)
                                //Busca o campo atual
                                cCampo    := aCampos[nColuna]
                                nPosCampo := GDFieldPos(cCampo)

                                //Se o tipo do campo for numérico, atualiza
                                If GetSX3Cache(cCampo, "X3_TIPO") == "N"
                                    aDadosAux[nColuna] := Val(aDadosAux[nColuna])
                                EndIf

                                //Atualiza o campo em memória
                                aCols[n][nPosCampo] := aDadosAux[nColuna]
                                __readVar           := "M->" + cCampo
                                &(__readVar)        := aCols[n][nPosCampo]

                                //Se não for os campos que não são digitáveis
                                If ! Alltrim(cCampo) + ";" $ "D1_ITEM;D1_PEDIDO;D1_ITEMPC;"

                                    //Executa as validações de campo
                                    &( GetSX3Cache(cCampo, "X3_VALID") )
                                    &( GetSX3Cache(cCampo, "X3_VLDUSER") )

                                    //Executa os gatilhos
                                    If ExistTrigger(cCampo)
                                        RunTrigger( ;
                                            2,;           //nTipo (1=Enchoice; 2=GetDados; 3=F3)
                                            n,;           //Linha atual da Grid quando for tipo 2
                                            Nil,;         //Não utilizado
                                            ,;            //Objeto quando for tipo 1
                                            cCampo;       //Campo que dispara o gatilho
                                        )
                                    EndIf
                                EndIf

                                //Atualiza a grid
                                //eVal(bGDRefresh)
                            Next

                            //Atualiza o total
                            aCols[n][GDFieldPos("D1_TOTAL")] := aCols[n][GDFieldPos("D1_QUANT")] * aCols[n][GDFieldPos("D1_VUNIT")]

                            //Atualiza o MaFis* para calculo dos impostos
                            MaFisLoad("IT_PRODUTO", aCols[n][GDFieldPos("D1_COD")],   n)
                            MaFisLoad("IT_QUANT",   aCols[n][GDFieldPos("D1_QUANT")], n)
                            MaFisLoad("IT_PRCUNI",  aCols[n][GDFieldPos("D1_VUNIT")], n)
                            MaFisLoad("IT_VALMERC", aCols[n][GDFieldPos("D1_TOTAL")], n)
                            MaFisLoad("IT_TES",     aCols[n][GDFieldPos("D1_TES")],   n)
                            MaFisEndLoad(n)

                            //Executa a validação de linha
                            A103LinOk()
                        EndIf
                    EndIf
                EndDo

                //Atualiza a tela
                If Len(aCols) == 0
                    aAdd(aCols, aClone(aLinMold))
                EndIf
                n := 1
                GetDRefresh()
            EndIf

            //Fecha o arquivo e finaliza o processamento
            oFile:Close()
        EndIf

    Else
        FWAlertError("Arquivo não encontrado!", "Atenção")
    EndIf
Return

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.

Deixe uma resposta

Terminal de Informação