Como inserir campos customizados na tela de Documento de Entrada

Hoje vou mostrar como criar uma nova aba no rodapé do Documento de Entrada e inserir campos nessa aba.

Muitos alunos me perguntam se é possível incluir campos na tela do Documento de entrada, sem ser pelo intermédio de algum botão.

E sim, é possível. O que devemos fazer basicamente é:

  1. Utilizar a variável oFolder que esta em memória, antes da tela carregar os valores, e o melhor P.E. para tratar isso é o MA103BUT que é responsável por criar outras ações na tela de manipulação, mas antes de liberar pro usuário digitar
  2. Nesse ponto iremos adicionar uma nova aba através do método AddItem
  3. Então, iremos usar uma variável pública (lembre-se que não é recomendado usar escopo Public, estamos usando aqui para testes, e se for usar ai, use nome esdrúxulos como por exemplo com dois underlines) que no nosso caso será do campo F1_X_CAMPO
  4. Iremos criar um MSGET com as informações do campo F1_X_CAMPO
  5. Por último, iremos criar um segundo P.E. que será após a gravação da SF1, e nele iremos testar, se tiver a variável pública criada no passo 3, iremos gravar no campo F1_X_CAMPO

Resumidamente então, iremos usar outro ponto de entrada, para manipular o Folder do rodapé, e adicionar campo(s) nessa aba criada.

Abaixo um print do resultado:

Exemplo de aba criada no Documento de Entrada

E abaixo o código fonte dos dois P.E.:

//Bibliotecas
#Include "TOTVS.ch"

/*/{Protheus.doc} User Function MA103BUT
P.E. para adicionar opções dentro da tela de manipulação do Doc. de Entrada
@type  Function
@author Atilio
@since 08/07/2021
@version version
@see https://tdn.totvs.com/pages/releaseview.action?pageId=102269141
/*/

User Function MA103BUT()
    Local aArea := GetArea()
    Local lEdit
    Local nAba
    Local oCampo
    Public __cCamNovo := ""

    //Adiciona uma nova aba no documento de entrada
    oFolder:AddItem("* Customizados", .T.)
    nAba := Len(oFolder:aDialogs)

    //Se for inclusão, irá criar a variável e será editável, senão irá buscar do banco e não será editável
    If INCLUI
        __cCamNovo := CriaVar("F1_X_CAMPO",.F.)
        lEdit := .T.
    Else
        __cCamNovo := SF1->F1_X_CAMPO
        lEdit := .F.
    EndIf
 
    //Criando na janela o campo OBS
    @ 003, 003 SAY Alltrim(RetTitle("F1_X_CAMPO")) OF oFolder:aDialogs[nAba] PIXEL SIZE 050,006
    @ 001, 053 MSGET oCampo VAR __cCamNovo SIZE 100, 006 OF oFolder:aDialogs[nAba] COLORS 0, 16777215  PIXEL
    oCampo:bHelp := {|| ShowHelpCpo( "F1_X_CAMPO", {GetHlpSoluc("F1_X_CAMPO")[1]}, 5  )}
 
    //Se não houver edição, desabilita os gets
    If ! lEdit
        oCampo:lActive := .F.
    EndIf

    RestArea(aArea)
Return Nil

/*/{Protheus.doc} User Function SF1100I
P.E. após inclusão da SF1
@type  Function
@author Atilio
@since 08/07/2021
@version version
/*/

User Function SF1100I()
    Local aArea := GetArea()

    //Se a variável pública existir
    If Type("__cCamNovo") != "U"

        //Grava o conteúdo na SF1
        RecLock("SF1", .F.)
            SF1->F1_X_CAMPO := __cCamNovo
        SF1->(MsUnlock())
    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.

16 Responses

  1. MARCOS BISPO ABRAHAO disse:

    Bom dia Daniel! Ótima dica, mas teria como fazer este procedimento também na Pré-Nota?

  2. Michael Fernando Camilo disse:

    Olá Daniel! Excelente dica! Poderia usar escopo private para a variável __cCamNovo?

    • Opa, eu que agradeço pelo comentário Michael.
      No caso, no exemplo do artigo não, pois, uma variável Private fica disponível para a função que a criou e para todas as que forem acionadas internamente por ela.
      Então ela só vai existir até o Return da função que a criou. Por isso foi necessário criar uma Public, para que ela ficasse na memória do sistema.
      Grande abraço.

  3. MARCOS BISPO ABRAHAO disse:

    Obrigado Daniel!

  4. Daniele Diniz Magalhães disse:

    Estou tentando usar o código, mas criando dois campos, fazendo no mesmo padrão que você fez só um. O problema é que a informação que coloco no primeiro campo, preenche automaticamente o segundo campo. Teria ideia do que eu posso estar fazendo de errado?

    • Você criou uma segunda variável pública, por exemplo, __cCamNov2 para usar no seu campo?
      No caso, como as variáveis em AdvPL tem limitação de 10 caracteres, veja isso também, pois se estiver com o nome __cCamNovo2, ele irá considerar até a última letra “o”.

  5. Mayco A. Ranghetti disse:

    Atílio, tudo bem?
    e como ficaria a construção do PE para campos do tipo combobox, que tem as opções de escolha na SX3?

    • Bom dia Mayco, tudo sim graças a Deus e você?

      Certo, o que você vai precisar é:
      1. Uma variável Array, buscando o GetSX3Cache(“F1_X_CAMPO”, “X3_CBOX”), lembrando que será necessário você transformar em array com algum comando como o StrTokArr
      2. Criar um TComboBox, e nos itens passar esse Array do item 1

      Um grande abraço.

  6. Victor disse:

    Olá, tudo bem? Obrigado por compartilhar, consegui utilizar exatamente da forma como informado. O que só não consegui foi adicionar um focus na aba ‘Totais’ ao visualizar o registro. Alterei o nOption para 1 (que é o Totais), a aba é até alterada, mas, os campos ainda ficam focados nos customizados. Abri um chamado na Totvs para um retorno de qual ou quais propriedades alterar, assim que tiver retorno, eu posto aqui. Obrigado novamente por compartilhar essa alteração.

  7. Thyago Pedro Romeiro disse:

    Bom dia Daniel

    O Victor postou uma dúvida sobre o alterar a aba via nOption e o campo continuar sendo exibido e ficou de ver com a Totvs sobre isso. Teve algum retorno sobre?

    Obrigado

  8. Ronan Felipe Gomes disse:

    Olá pessoal,

    Teria como adicionar um campo customizado no cabeçalho do documento?
    Estou tentando adicionar o nome do fornecedor para gatilhar pelo campo loja… alguma dica?

    Agradeço desde já.

    • Bom dia Ronan, tudo joia?

      No cabeçalho eu desconheço uma forma de adicionar um campo, somente dessa do artigo que é no rodapé.

      Agora sobre gatilhar a informação, teve uma dúvida parecida no nosso grupo do WhatsApp, segue aqui o que respondemos na ocasião:
      […]
      Então caso você queira gatilhar informações para o campo customizado no rodapé, você precisa fazer o seguinte:
      a. No campo do cabeçalho, você vai incluir uma validação de usuário customizada, por exemplo, no F1_FORNECE, na validação de usuário você coloca u_SuaFuncao()
      b. Dentro dessa sua User Function customizada, você atualiza a variável pública, ai você pode usar posicione, query, ou outros recursos
      c. Acione então a GetDRefresh() para atualizar a tela

      Abaixo um pequeno exemplo:

      User Function SuaFuncao()
      Local lContinua := .T.

      //Atualiza a variável pública vinculada ao get que foi criado no rodapé
      __cSuaVar := Posicione(“SA2”, 1 …. //aqui você passa o restante dos parâmetros

      //Atualiza a tela
      GetDRefresh()
      Return lContinua
      […]

      Um grande abraço.

Deixe uma resposta para Dan Atilio (Daniel Atilio)Cancelar resposta

Terminal de Informação