Função para executar fórmulas no Protheus 12

Olá pessoal…

Como é de conhecimento de muitos analistas, o Fórmulas foi bloqueado no Protheus 12 para execução de blocos de código, pensando nisso, criei uma função bem prática para executar blocos de código.

Antes de mais nada, eu sei que é possível executar no lançamento padrão, porém essa rotina foi criada devido a praticidade de apenas colocar no menu e executar quantas vezes quiser a expressão digitada.

Essa função, você consegue colocar em um menu (cuidado para deixar exposto para qualquer usuário), e nela você consegue executar a fórmula digitada (até mais de uma vez). A tela é bem simples, tem um campo para digitação e o botão de execução.

Mini Fórmulas

Mini Fórmulas

UPDATE – Setembro de 2023:

Pessoal, como algumas rotinas poderiam travar e ficar em loop eterno, o Begin Sequence, não encerrava, visto que não dava a mensagem de Thread Error.

Foi criado então um checkbox, se deve inibir o Error Log (passando pelo Begin Sequence como era antigamente), ou se deve forçar a execução, mesmo com erros (sem passar pelo Begin Sequence)

UPDATE – Março de 2024:

Foi criado uma tratativa para gravar o histórico das funções executadas, gravando a data, hora, usuário, ambiente e a fórmula digitada.

Abaixo o código fonte criado:

//Bibliotecas
#Include "Protheus.ch"

//Variáveis estáticas
Static cLogNome  := "\system\historico_zMiniForm.log"
Static oLogWrite
Static cLogSepar := "|-|"
 
/*/{Protheus.doc} zMiniForm
Funcao Mini Formulas, para executar formulas
@author Atilio
@since 17/12/2017
@version 1.0
@type function
@obs Assim como o formulas foi bloqueado no Protheus 12, cuidado ao deixar exposto no menu o Mini Formulas
/*/
 
User Function zMiniForm()
    Local aArea := GetArea()
    //Variaveis da tela
    Private oDlgForm
    Private oGrpForm
    Private oGetForm
    Private cGetForm := Space(250)
    Private oGrpAco
    Private oBtnExec
    Private oBtnHist
    Private oInibErro, lInibErro := .F.
    //Tamanho da Janela
    Private nJanLarg := 500
    Private nJanAltu := 120
    Private nTamBtn  := 048

    //Abre o arquivo de log
    fAbreLog()
 
    //Criando a janela
    DEFINE MSDIALOG oDlgForm TITLE "zMiniForm - Execucao de Formulas" FROM 000, 000  TO nJanAltu, nJanLarg COLORS 0, 16777215 PIXEL
        //Grupo Formula com o Get
        @ 003, 003  GROUP oGrpForm TO 30, (nJanLarg/2)-1        PROMPT "Formula: " OF oDlgForm COLOR 0, 16777215 PIXEL
            @ 010, 006  MSGET oGetForm VAR cGetForm SIZE (nJanLarg/2)-9, 013 OF oDlgForm COLORS 0, 16777215 PIXEL
         
        //Grupo Acoes com o Botao
        @ (nJanAltu/2)-30, 003 GROUP oGrpAco TO (nJanAltu/2)-3, (nJanLarg/2)-1 PROMPT "Acoes: " OF oDlgForm COLOR 0, 16777215 PIXEL
            @ (nJanAltu/2)-18, 006 CHECKBOX oInibErro VAR lInibErro PROMPT "Inibe Error Log (utilizar Begin Sequence)" SIZE 200, 010 OF oDlgForm COLORS 0, 16777215 PIXEL
            @ (nJanAltu/2)-24, (nJanLarg/2) - ((nTamBtn*2) + 6) BUTTON oBtnHist PROMPT "Histórico" SIZE nTamBtn, 018 OF oDlgForm ACTION(fHistorico()) PIXEL
            @ (nJanAltu/2)-24, (nJanLarg/2) - ((nTamBtn*1) + 6) BUTTON oBtnExec PROMPT "Executar"  SIZE nTamBtn, 018 OF oDlgForm ACTION(fExecuta()) PIXEL
         
    //Ativando a janela
    ACTIVATE MSDIALOG oDlgForm CENTERED

    //Encerra o arquivo
    fFechaLog()
     
    RestArea(aArea)
Return
 
/*---------------------------------------*
 | Func.: fExecuta                       |
 | Desc.: Executa a formula digitada     |
 *---------------------------------------*/
 
Static Function fExecuta()
    Local aArea     := GetArea()
    Local cFormula  := Alltrim(cGetForm)
    Local cError    := ""
    Local bError    := Nil
    Local cLinhaLog := ""
    Local cCodUsr   := RetCodUsr()
     
    //Se tiver conteudo digitado
    If ! Empty(cFormula)
        //Adiciona no log
        cLinhaLog := PadR(cCodUsr,             06) + cLogSepar
        cLinhaLog += PadR(UsrRetName(cCodUsr), 20) + cLogSepar
        cLinhaLog += PadR(GetEnvServer(),      20) + cLogSepar
        cLinhaLog += PadR(dToC(Date()),        10) + cLogSepar
        cLinhaLog += PadR(Time(),              08) + cLogSepar
        cLinhaLog += cFormula
        cLinhaLog += CRLF
        oLogWrite:Write(cLinhaLog)

        //Se tiver habilitado para inibir erros
        If lInibErro
            bError   := ErrorBlock({ |oError| cError := oError:Description})
 
            //Inicio a utilizacao da tentativa
            Begin Sequence
                &(cFormula)
            End Sequence
             
            //Restaurando bloco de erro do sistema
            ErrorBlock(bError)
             
            //Se houve erro, sera mostrado ao usuario
            If ! Empty(cError)
                MsgStop("Houve um erro na formula digitada: "+CRLF+CRLF+cError, "Atencao")
            EndIf
 
        //Senão, simplesmente executa a fórmula conforme ela foi digitada
        Else
            &(cFormula)
        EndIf
    EndIf
     
    RestArea(aArea)
Return

Static Function fAbreLog()
    Local cLinhaLog := ""
    Local oFile

    //Se o arquivo não existir, terá uma linha de cabeçalho
    If ! File(cLogNome)
        cLinhaLog := PadR("Usr.",              06) + cLogSepar
        cLinhaLog += PadR("Nome do Usuário",   20) + cLogSepar
        cLinhaLog += PadR("Ambiente",          20) + cLogSepar
        cLinhaLog += PadR("Data",              10) + cLogSepar
        cLinhaLog += PadR("Hora",              08) + cLogSepar
        cLinhaLog += "Fórmula"
        cLinhaLog += CRLF
        cLinhaLog += Replicate("-", 06) + cLogSepar
        cLinhaLog += Replicate("-", 20) + cLogSepar
        cLinhaLog += Replicate("-", 20) + cLogSepar
        cLinhaLog += Replicate("-", 10) + cLogSepar
        cLinhaLog += Replicate("-", 08) + cLogSepar
        cLinhaLog += Replicate("-", Len(cGetForm))
        cLinhaLog += CRLF

    //Senão, faz a leitura do que já existe
    Else
        //Tenta abrir o arquivo e pegar o conteudo
        oFile := FwFileReader():New(cLogNome)
        If oFile:Open()
 
            //Se deu certo abrir o arquivo, pega o conteudo e exibe
            cLinhaLog  := oFile:FullRead()
        EndIf
        oFile:Close()
    EndIf

    //Abre o arquivo
    oLogWrite := FWFileWriter():New(cLogNome, .F.)
    oLogWrite:Create()

    //Se tiver linha, escreve no arquivo
    If ! Empty(cLinhaLog)
        oLogWrite:Write(cLinhaLog)
    EndIf
Return

Static Function fFechaLog()
    oLogWrite:Close()
Return

Static Function fHistorico()
    Local aArea     := FWGetArea()
    Local cArqLocal := GetTempPath() + "zMiniForm.log"

    //Fecha o log para permitir a cópia
    fFechaLog()

    //Se o arquivo já existir na máquina local, apaga ele
    If File(cArqLocal)
        FErase(cArqLocal)
    EndIf

    //Agora efatua a cópia da Protheus Data para a máquina local
    __CopyFile(cLogNome, cArqLocal)

    //Se o arquivo existir, exibe o conteúdo dele
    If File(cArqLocal)
        ShowMemo(cArqLocal)
    Else
        FWAlertError("Arquivo não encontrado na máquina local!", "Falha")
    EndIf

    //Abre o arquivo de log novamente
    fAbreLog()

    FWRestArea(aArea)
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.

24 Responses

  1. macatubs disse:

    essa ficou show em mestre… topp!

  2. Erick disse:

    Ótimo, continua com este Blog sucesso…

  3. Lucimar dos Santos disse:

    Desculpa, mas eu não entendi… usamos o P12 desde a versão 12.1.7 hoje estamos na 12.1.17 e eu sempre usei o Fórmulas para testar várias rotinas…. Quando que ele foi bloqueado??? Foi esses dias???

  4. Rafael Achôa disse:

    Que ótima ferramenta, Atilião!
    Sucesso!

  5. RUBEM DA SILVA CERQUEIRA disse:

    Muito Bom meu mano!

    Parabéns pelo conteúdo.

    Um abraço

    ATT

  6. Mozart Lima disse:

    Atilio, hoje coloquei essa função em um cliente e está me ajudando muito.
    Você sempre preciso nos seus desenvolvimentos criando as ferramentas que nos ajudam na execução do trabalho.
    Obrigado, parabéns.
    Att.
    Mozart.

  7. Fábio disse:

    Parabéns meu amigo, garanto que vai ajudar muito!!

  8. Manoel Carlos De Oliveira Ramos Junior disse:

    Muito top Dan !! Me ajudou e muito !

  9. Daniel Machado disse:

    Como executar no configurador?

    • Dan_Atilio disse:

      Então Daniel, no Configurador, atualmente com o dicionário no banco, acho que não tem como adicionar no menu.
      Porém o que você pode testar, é criar o ponto de entrada AfterLogin, colocar em um atalho, por exemplo, Shift+F7 a chamada para o mini fórmulas, e ao logar no configurador, vc pressionar o Shift+F7.

      User Function AfterLogin() 
      	SetKey(K_SH_F7, { || u_zMiniForm() })    //Shift + F7
      Return
      
  10. cesteves disse:

    Obrigado Dan. Deu certo aqui! Sou iniciante nesse mundo ADVPL

  11. emilli disse:

    Onde eu adiciono esse código??

  12. HIARLY ALVES RODRIGUES PAIVA disse:

    Bom dia… não consegui compilar…tá pedindo “vkey.ch” . Poderiam me ajudar ??

    • Bom dia Hiarly, tudo joia?

      Que estranho, nesse fonte não é usado a vkey.ch, ele é usado apenas a Protheus.ch.

      Se for o caso tente trocar no fonte para a TOTVS.ch que é mais nova que a Protheus.ch e faça um teste novamente.

      Fico no aguardo.

      Um grande abraço.

Deixe uma resposta

Terminal de Informação