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, C5_NUM, é 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 SA1, SB1, SC5 ou SC6 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:
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_ORDEMO 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_NUMtambé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ãoGetSXENumdireto. O motivo está na seção seguinte. - A validação é a mesma do
C5_NUM, que no dicionário temNaoVazio().And.ExistChav("SC5"). X3_VISUAL = Vdeixa o código só para leitura: o usuário não digita código, só recebe. Aqui o exemplo se afasta doC5_NUM, que é editável (X3_VISUALem 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:
#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 cCodO 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,@Rinsere caracteres que não são gravados,@Eusa 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 template99/99/9999.
| Máscara | Exemplo real no dicionário padrão |
|---|---|
@! | A1_NOME, A1_COD, B1_DESC |
@R 99999-999 | A1_CEP, 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 B1_COD 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:
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_ORDEMOs 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
TDNtdn.totvs.com
TDN — GETSXENUM()TDNtdn.totvs.com
TDN — Campos (CFGX034 - SIGACFG)TDNtdn.totvs.com
TDN — Pasta Validações (CFGX034 - SIGACFG)TDNtdn.totvs.com
TDN — EXISTCHAV()TDNtdn.totvs.com
TDN — TRANSFORM()TDNtdn.totvs.com
TDN — Tipos de dados (Dicionário de Dados)
Continue por aqui
- Vídeo
ProtheusReferência técnica
Campos reservados: log de inclusão e alteração, bloqueio e imagem
Campos reservados do Protheus (USERLGI, USERLGA, MSBLQL, BITMAP): o que o dicionário define, por que em tabela de três letras o log vira USERGI.