Pragiva — Tecnologia na prática

Campo caractere: código sequencial, máscara e validação

Campo caractere no Configurador: código sequencial sem GetSXENum direto no inicializador, nome em maiúsculas com @! e validação de código repetido.

Protheus Tutorial 6 min de leitura

Assista o vídeo

Nesta página8 seções

Antes de começar

  • Tabela customizada criada no dicionário (no exemplo, a ZA1 — Cadastro de motoristas)
  • Acesso ao Configurador com permissão de alterar o dicionário de dados

Um código que se numera sozinho no Protheus é um campo caractere com três peças no dicionário: GetSXENum() para buscar o próximo número, uma máscara que padroniza o que aparece na tela e uma validação que recusa código repetido. O número do pedido de venda, , é montado assim. Este artigo monta o mesmo desenho no cadastro de motoristas da série, a tabela ZA1, com um cuidado que a própria documentação da função pede e o dicionário padrão não mostra. De quebra, monta o campo de nome, o caractere mais comum que existe.

Caractere é o tipo para código, nome, endereço, sigla: tudo que é texto, mesmo quando só tem dígitos. Um código 000123 é caractere. Ninguém soma códigos, e os zeros à esquerda precisam sobreviver.

Onde se cria o campo

No Configurador, em Base de Dados > Dicionário > Arquivos, posicione na tabela, clique em Editar, abra a pasta Campos e clique em Incluir. A tela de inclusão é dividida nas pastas Campo, Informações, Opções, Validações, Uso e Módulos. As propriedades das fichas abaixo estão espalhadas por elas. O título, por exemplo, fica em Informações e tem até 12 caracteres.

O nome do campo

Todo campo começa pelo prefixo da tabela e um sublinhado: ZA1_COD, ZA1_NOME. O nome inteiro cabe em 10 posições, que é o tamanho da coluna X3_CAMPO da SX3.

Numa tabela sua, como a ZA1, o resto do nome é livre. O cuidado aparece quando o campo é seu e a tabela é do padrão, como um motorista no pedido de venda. A recomendação é pôr um X logo depois do prefixo: C5_XMOTOR. No dicionário padrão, nenhum campo de , , ou começa com X depois do prefixo, e o seu fica fácil de distinguir numa leitura da tela, num SELECT ou numa atualização.

Para listar os campos de usuário de uma tabela padrão:

Confira no seu ambienteSQL
SELECT X3_CAMPO, X3_TIPO, X3_TAMANHO, X3_TITULO, X3_PROPRI
  FROM SX3010
 WHERE X3_ARQUIVO = 'SC5'
   AND X3_PROPRI  = 'U'
   AND D_E_L_E_T_ = ' '
 ORDER BY X3_ORDEM

O 010 do nome da tabela é o sufixo da empresa e muda de ambiente para ambiente. Troque pelo seu.

A ficha do ZA1_COD

Propriedade (coluna da SX3)Valor
Tipo (X3_TIPO)C
Tamanho (X3_TAMANHO)6
Título (X3_TITULO)Codigo
Formato (X3_PICTURE)@!
Inicializador padrão (X3_RELACAO)U_ZA1NUM()
Validação (X3_VALID)NaoVazio() .And. ExistChav("ZA1")
Obrigatório (pasta Uso)desmarcado
Browse (X3_BROWSE)S
Contexto (X3_CONTEXT)R
Alterar/Visualizar (X3_VISUAL)V
Proprietário (X3_PROPRI)U

Por que cada valor:

  • Caractere de 6 posições. Os zeros à esquerda contam, e seis posições dão 999.999 motoristas. O C5_NUM também tem 6.
  • @! deixa a tela em maiúsculas. Para um código só de dígitos, não muda nada visível, mas padroniza se um dia entrar letra.
  • Inicializador U_ZA1NUM(), e não GetSXENum direto. O motivo está na seção seguinte.
  • A validação é a mesma do C5_NUM, que no dicionário tem NaoVazio().And.ExistChav("SC5").
  • X3_VISUAL = V deixa o código só para leitura: o usuário não digita código, só recebe. Aqui o exemplo se afasta do C5_NUM, que é editável (X3_VISUAL em branco) e tem máscara @X.

GetSXENum: o que ele faz e o aviso da documentação

A documentação lista seis parâmetros: GetSXENum(cAlias, cCampo, cAliasSXE, nOrdem, cGroup, cBranch). Só os dois primeiros são obrigatórios: a tabela e o campo. A função devolve o próximo número disponível daquela tabela, obtido pelos arquivos de sistema SXE/SXF ou pelo servidor de numeração, quando o ambiente usa essa configuração.

A mesma página traz um aviso que muda o desenho do campo: não é recomendado usar a função diretamente no inicializador padrão, porque ela pode buscar número em momento indesejado, fora da inclusão de um registro. A orientação é proteger a chamada com as validações do seu contexto, e, se preciso, com uma função própria.

O dicionário padrão ainda tem GetSXENum direto no inicializador, como no C5_NUM. Para um campo seu, siga a documentação. A função abaixo só pede número na inclusão:

ADVPL / TLPP
#Include "Protheus.ch"

/*/{Protheus.doc} ZA1NUM
Inicializador padrão do ZA1_COD: só reserva número na inclusão.
@type user function
@return character, próximo código ou branco
/*/
User Function ZA1NUM()

    Local cCod := Space(TamSX3("ZA1_COD")[1])

    If Type("INCLUI") == "L" .And. INCLUI
        cCod := GetSXENum("ZA1", "ZA1_COD")
    EndIf

Return cCod

O teste com Type("INCLUI") evita erro quando a variável não existe no contexto em que o inicializador roda. O uso de Type() para esse tipo de teste está em Tipos de dados em AdvPL.

O número pedido fica reservado até alguém decidir o que fazer com ele: ConfirmSX8() confirma o uso e RollBackSX8() devolve. Na numeração por SXE/SXF, o número reservado e não confirmado não se perde de imediato: a função procura primeiro as sobras antes de avançar a sequência. Quando o próximo número ainda assim sai do trilho, o diagnóstico e a rotina do Configurador que corrige a sequência estão em Controle de numeração.

Quando cada inicializador da SX3 roda (o padrão e o de browse) está em Inicializador padrão e inicializador de browse.

A validação que impede código repetido

  • NaoVazio() não permite brancos em campo caractere (nem zero em campo numérico).
  • ExistChav("ZA1") verifica se o código já existe na própria tabela. Se não existe, devolve .T.; se existe, devolve .F. e mostra um help.

As duas se combinam com .And., e a expressão inteira precisa devolver .T. para o valor ser aceito. Vale para função sua também: qualquer U_... que devolva lógico pode entrar ali.

A pasta Validações tem a validação do sistema e a do usuário, e a SX3 tem uma coluna para cada (X3_VALID e X3_VLDUSER). A documentação diz que a validação do usuário é somada à do sistema. Quando usar cada uma, com ExistCpo, Positivo e as outras funções, é assunto de Validação de campo.

A máscara

A máscara (X3_PICTURE) formata o que o usuário vê e digita. É a mesma linguagem da cláusula PICTURE das telas e da função Transform(), e tem duas partes que se combinam:

  • Função de formatação, iniciada por @, que vale para o campo inteiro: @! converte para maiúsculas, @R insere caracteres que não são gravados, @E usa o formato numérico brasileiro.
  • Template, sem @, que desenha o campo posição a posição: !!!!! põe cinco posições em maiúsculas, e há campos de data do padrão com o template 99/99/9999.
MáscaraExemplo real no dicionário padrão
@!, ,
@R 99999-999, campo de tamanho 8

O A1_CEP mostra bem o @R: o template desenha nove posições com o hífen, mas o campo tem 8. O hífen aparece na tela e não vai para o banco.

A ficha do ZA1_NOME

Propriedade (coluna da SX3)Valor
Tipo (X3_TIPO)C
Tamanho (X3_TAMANHO)40
Título (X3_TITULO)Nome
Formato (X3_PICTURE)@!
Validação (X3_VALID)NaoVazio()
Obrigatório (pasta Uso)marcado
Browse (X3_BROWSE)S
Contexto (X3_CONTEXT)R
Alterar/Visualizar (X3_VISUAL)A
Proprietário (X3_PROPRI)U

Quarenta posições cabem um nome completo sem abreviar. As maiúsculas facilitam pesquisa e relatório. O obrigatório fica na pasta Uso: quando o usuário deixa o campo em branco na inclusão ou alteração, o sistema avisa e destaca o campo.

A marca de obrigatório vai para a coluna X3_OBRIGAT, mas ela não guarda um S legível. Para saber se um campo é obrigatório, confie na tela do Configurador, não numa comparação com 'S'.

Como o caractere fica no banco

Campo caractere tem tamanho fixo e ocupa no banco o espaço definido pelo tamanho: o conteúdo é completado com espaços à direita. O tem 15 posições, e um código de 8 caracteres fica gravado com 7 espaços no fim.

Isso quase não aparece em SQL, porque o SQL Server ignora espaços à direita na comparação com =. Aparece em AdvPL: SB1->B1_COD == "PGV001" é falso com o produto certo posicionado. A explicação e as duas saídas (AllTrim ou PadR) estão em Operadores em AdvPL.

Com os dois campos criados, confira o dicionário da tabela:

Confira no seu ambienteSQL
SELECT X3_CAMPO, X3_TIPO, X3_TAMANHO, X3_PICTURE,
       X3_RELACAO, X3_VALID, X3_VLDUSER, X3_VISUAL, X3_PROPRI
  FROM SX3010
 WHERE X3_ARQUIVO = 'ZA1'
   AND X3_CAMPO IN ('ZA1_COD', 'ZA1_NOME')
   AND D_E_L_E_T_ = ' '
 ORDER BY X3_ORDEM

Os outros tipos da tabela seguem na série: a data de nascimento em Campo data, e a visão geral dos cinco tipos em Os cinco tipos de campo do Protheus.

Referências

  1. TDNtdn.totvs.com

    TDN — GETSXENUM()
  2. TDNtdn.totvs.com

    TDN — Campos (CFGX034 - SIGACFG)
  3. TDNtdn.totvs.com

    TDN — Pasta Validações (CFGX034 - SIGACFG)
  4. TDNtdn.totvs.com

    TDN — EXISTCHAV()
  5. TDNtdn.totvs.com

    TDN — TRANSFORM()
  6. TDNtdn.totvs.com

    TDN — Tipos de dados (Dicionário de Dados)

Continue por aqui