Função que altera conteúdo de perguntas (MV_PAR) em AdvPL

Olá pessoal…

Hoje vou mostrar uma função criada em AdvPL para alterar o conteúdo dos parâmetros antes de mostrar a tela de Pergunte.

AdvPL

AdvPL

Atualização (16/07/2020):

A TOTVS lançou uma função nova que faz esse procedimento, chamada de SetMVValue, segue o link do TDN – https://tdn.totvs.com/display/public/PROT/SetMVValue .

Portanto, tentem usar a forma nova, pois pode ser que que a zAtuPerg não funcione mais.


Post Original (28/02/2017):

Imagine que você criou um relatório de pedido de venda, chamado no Ações Relacionadas do Pedido, e na tela de Pergunte, tem um parâmetro Pedido De e outro Pedido Até, mas o usuário quer que a pergunta já venha preenchida, como fazer então para resolver?

A princípio é só alterar o X1_CNT01 da pergunta, porém se o usuário estiver utilizando o Profile, ficará ou na SXK ou no próprio Profile, pensando nisso, criei uma rotina que ao chamar, você passa o conteúdo do parâmetro antes da pergunta, funcionaria dessa forma:

 
//... 
u_zAtuPerg("SUAPERG", "MV_PAR01", "000001") //Pedido De 
u_zAtuPerg("SUAPERG", "MV_PAR02", "000001") //Pedido Até 
//... 

Dessa forma ao chamar o Pergunte, os parâmetros já vem com o conteúdo padrão estabelecido.

Abaixo o código fonte desenvolvido.

//Bibiliotecas
#Include "Protheus.ch"
 
/*/{Protheus.doc} zAtuPerg
Função que atualiza o conteúdo de uma pergunta no X1_CNT01 / SXK / Profile
@author Atilio
@since 06/10/2016
@version 1.0
@type function
    @param cPergAux, characters, Código do grupo de Pergunta
    @param cParAux, characters, Código do parâmetro
    @param xConteud, variavel, Conteúdo do parâmetro
    @example u_zAtuPerg("LIBAT2", "MV_PAR01", "000001")
/*/
 
User Function zAtuPerg(cPergAux, cParAux, xConteud)
    Local aArea      := GetArea()
    Local nPosCont   := 8
    Local nPosPar    := 14
    Local nLinEncont := 0
    Local aPergAux   := {}
    Default xConteud := ''
     
    //Se não tiver pergunta, ou não tiver ordem
    If Empty(cPergAux) .Or. Empty(cParAux)
        Return
    EndIf
     
    //Chama a pergunta em memória
    Pergunte(cPergAux, .F., /*cTitle*/, /*lOnlyView*/, /*oDlg*/, /*lUseProf*/, @aPergAux)
     
    //Procura a posição do MV_PAR
    nLinEncont := aScan(aPergAux, {|x| Upper(Alltrim(x[nPosPar])) == Upper(cParAux) })
     
    //Se encontrou o parâmetro
    If nLinEncont > 0
        //Caracter
        If ValType(xConteud) == 'C'
            &(cParAux+" := '"+xConteud+"'")
         
        //Data
        ElseIf ValType(xConteud) == 'D'
            &(cParAux+" := sToD('"+dToS(xConteud)+")'")
             
        //Numérico ou Lógico
        ElseIf ValType(xConteud) == 'N' .Or. ValType(xConteud) == 'L'
            &(cParAux+" := "+cValToChar(xConteud)+"")
         
        EndIf
         
        //Chama a rotina para salvar os parâmetros
        __SaveParam(cPergAux, aPergAux)
    EndIf
     
    RestArea(aArea)
Return

Bom pessoal, por hoje é só.
Abraços e até a próxima.

Dan Atilio (Daniel Atilio)
Especialista em Engenharia de Software pela FIB. Entusiasta de soluções Open Source. E blogueiro nas horas vagas.

14 Responses

  1. mrcoelho68 disse:

    Show Cara…. Você é demais!!! Estava procurando isso agora…. Me ajudou muito … Valeu!!!

    • mrcoelho68 disse:

      Cara… sou eu novamente…

      Me permita apenas fazer uma correção em sua função zAtuPerg:

      Onde está:
      ElseIf ValType(xConteud) == ‘D’
      &(cParAux+” := sToD(“+dToS(xConteud)+”)”)

      Necessita de uma “aspas” na conversão da função dToS() da seguinte forma:

      ElseIf ValType(xConteud) == ‘D’
      &(cParAux+” := sToD( ‘ “+dToS(xConteud)+” ‘ )”)

      Obs.Claro que sem estes espaços adicionais que coloquei apenas para destacar a correção.

      Valeu amigo!!

    • Dan_Atilio disse:

      Opa, obrigado jovem.
      Abraços.

  2. Daniel disse:

    Muito obrigado Dan_Atilio.
    Me ajudou de mais.

    Abração!

  3. Fátima Falcão disse:

    Olá, boa tarde!

    Dan_Atilio, será que você consegue me ajudar?
    Estou tentando utilizar tua função mas é apresentado o erro “variable does not exist CACESSO on VERSENHA(MSLIB.PRW)”. Tem ideia do que pode ser?

    • Dan_Atilio disse:

      Boa noite Fátima, tudo bem?
      Você está executando no programa inicial, ou em menu do Protheus?
      Tente executar pelo menu do Protheus, seja pelo Fórmulas ou adicionando como opção de menu. É que provavelmente ao executar via programa inicial ou via debug, você teria que adaptar a rotina com RPCSetEnv.
      Qualquer dúvida, fico à disposição.

  4. Rafael Lien disse:

    Olá, Dan_Atilio,

    Esse artigo é muito bom, parabéns, seu código resolvia meus problemas!

    No entanto, depois de migrar para 12.1.25, esse código parou de funcionar. Se o comando pergunte(cPerg, .T.) vier depois de manipular os valores, o sistema ainda carrega com os aqueles valores armazenados nos profiles antes da manipulação.

    Por exemplo, vamos supor que no perfil do usuário o valor do parametro MV_PAR01 é “AAAAA”

    u_zAtuPerg(“SUAPERG”, “MV_PAR01”, “BBBBB”) —> atualiza o valor no profile
    Pergunte(“SUAPERG”, .T.) —–> O sistema carrega o valor “AAAAA” na pergunta e mostrar para usuário mas não “BBBBB”.

    Pode me ajudar?

    • Dan_Atilio disse:

      Boa tarde Rafael, tudo bem?
      Então jovem, a TOTVS nas atualizações e versões mais novas do Protheus, foram retirando funções e funcionalidades que manipulam o dicionário de dados (como PutSX1), e as funções internas usadas dentro do zAtuPerg também foram afetadas com isso.
      Portanto, se quiser criar uma tela com parâmetros que fiquem sendo atualizados em tempo de execução, recomendo utilizar a função ParamBox, onde você cria a tela de parâmetros através de um array, e consegue definir os valores de cada linha de array.
      Segue uma página com exemplos: https://terminaldeinformacao.com/knowledgebase/parambox/
      Abraços.

      • Lien Kuan Min disse:

        obrigado pela resposta, já pensei nisso também, e isso vai me ajudar resolver o problema pela metade. Pois tem outra situação onde o grupo de perguntas que quero manipular os valores é o MT461A, que fica entro da rotina MATA460, nesse caso já não tenho como recriar perguntas com parambox e jogar para dentro da MATA460….

        Existe alguma forma de fazer o sistema não puxar os valores do profile do ususário para determinadas perguntas?

        • Dan_Atilio disse:

          Então, você pode estudar para ver se a rotina tem ExecAuto, se tiver, você altera as variáveis públicas MV_PAR01, MV_PAR02, etc… assim por diante.
          Outra forma, é tentar achar um ponto de entrada antes da gravação e alterar também.

  5. Súlivan Simões disse:

    Como sempre salvando a vida!
    Parabéns manolo 😀

Deixe uma resposta