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 (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.

18 Responses

  1. mrcoelho68 disse:

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

  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 😀

  6. Ederson Guerra disse:

    https://tdn.totvs.com.br/display/framework/SetMVValue
    Segue uma função para manipulação do conteúdo dos campos no pergunte.

    • Boa tarde Ederson, tudo joia?
      Opa, obrigado pelo comentário. Se você notar, logo no começo do artigo, onde tem “Atualização (16/07/2020)”, eu já cito a SetMVValue.
      Mesmo assim, agradeço a gentileza em compartilhar aqui na área de comentários.
      Um grande abraço.

  7. José Vitor Rodrigues disse:

    Boa Tarde Atilio, tudo bem?

    Deixa eu te perguntar teria como alterar automáticamente uma pergunta dada outra, por exemplo, ao preencher o mv_par01, que é o código do cliente, preencher automaticamente com um dado o mv_par02, que é o prefixo E1_Prefixo, e preencher o mv_par03 que é o E1_NUM

    • Bom dia José, tudo joia graças a Deus e você?

      Você gostaria de “gatilhar” uma informação ao preencher um parâmetro na tela do Pergunte ou ParamBox, seria isso né?

      Recentemente inclusive, perguntaram algo parecido no nosso grupo do WhatsApp, segue abaixo a resposta que enviamos lá:

      […]
      Se for ParamBox, é o exemplo 4 nesse link – https://terminaldeinformacao.com/2021/12/02/como-fazer-validacoes-em-um-parambox/

      Se for Pergunte, você tem que:
      a. Criar uma User Function, vamos chamar de zVldPar
      b. Essa função, você vai colocar na validação da pergunta la no configurador, exemplo, u_zVldPar()
      c. Dentro dessa função, ela tem que retornar .T. ou .F. (para continuar ou barrar)
      d. E você aproveita ela, e atualiza os outros MV_PAR que precisar, exemplo:

      User Function zVldPar()
      Local aArea := FWGetArea()
      Local lContinua := .T.

      //Atualiza os MVs
      MV_PAR02 := “aaaa”
      MV_PAR03 := “bbbb”
      MV_PAR04 := “cccc”

      FWRestArea(aArea)
      Return lContinua
      […]

      Um grande abraço.

Deixe uma resposta

Terminal de Informação