Resposta rápida
- Onde fica
- Configurador, no dicionário da tabela, opção Índices — gravado na
SIX. - Regra quase sem exceção
- o índice começa pelo campo de filial.
- Ordem
- um caractere só — de
1a9, depoisA,B,C… - Quando o nickname importa
- índice seu em tabela padrão.
- Armadilha
dbSetOrder(n)num índice seu em tabela padrão aponta para outro índice depois de uma atualização.
Consulta rápida6 seções
Índice é o que permite ao Protheus ir direto a um registro em vez de ler a tabela inteira. Numa tabela sua, ele é quase burocracia: filial, código, pronto. Numa tabela padrão, o índice que você cria disputa espaço com os que a TOTVS entrega — e é aí que o nickname deixa de ser um campo opcional.
O que a SIX guarda
Cada linha da SIX é um índice. As colunas que decidem alguma coisa:
| Coluna | O que guarda |
|---|---|
INDICE | O alias da tabela (SC5, ZA1) |
ORDEM | A posição do índice na tabela — um caractere |
CHAVE | A expressão da chave, campos somados com + |
DESCRICAO | O texto que o usuário vê ao escolher a ordem de pesquisa |
PROPRI | S no índice do padrão; numa base com customização, os criados pelo cliente aparecem com U |
F3 | Consulta padrão associada ao índice (no padrão, a ordem 3 da SC5 usa CLI) |
NICKNAME | O apelido do índice, de uso restrito em customizações |
SHOWPESQ | S ou N: a opção Mostra Pesq da tela — com S, o índice é mostrado no browse |
É a mesma estrutura para tabela padrão e customizada. A diferença está no que você faz com ela.
Filial primeiro
Veja os índices do pedido de venda no dicionário padrão:
| Ordem | Chave | Descrição |
|---|---|---|
| 1 | C5_FILIAL+C5_NUM | Numero |
| 2 | C5_FILIAL+DTOS(C5_EMISSAO)+C5_NUM | DT Emissao + Numero |
| 3 | C5_FILIAL+C5_CLIENTE+C5_LOJACLI+C5_NUM | Cliente + Loja + Numero |
| 4 | C5_FILIAL+C5_OS | Gerado p/ OS |
| 5 | C5_FILIAL+C5_NUMENT | Entrega |
| 6 | C5_FILIAL+C5_CODED+C5_NUMPR | Cod. Edital + Nr. Processo |
| 7 | C5_FILIAL+C5_CODEMB | Cod. Embarc. |
| 8 | C5_FILIAL+C5_MODANP | Modal ANP |
| 9 | C5_FILIAL+C5_CODVGLP | Cod.Vas.GLP |
| A | C5_FILIAL+C5_MDCONTR+C5_MDNUMED+C5_MDPLANI | Num.Contrato + Num.Medicao + Num.Planilha |
| B | C5_FILIAL+C5_CLIENTE+C5_LOJACLI+DTOS(C5_EMISSAO)+C5_TIPO | Cliente + Loja + DT Emissao + Tipo Pedido |
Três coisas saltam dessa tabela.
Todas começam por C5_FILIAL. A mesma tabela física guarda os registros
de todas as filiais, e a busca parte de “desta filial”. Por isso o DbSeek
num índice desses começa com xFilial("SC5"): a chave montada precisa casar
com a chave do índice, na mesma ordem de campos. Num índice que começa por
outro campo (as exceções logo abaixo), a chave do DbSeek segue aquele
índice, não a regra.
No dicionário padrão inteiro, praticamente todos os índices seguem essa
regra. As exceções existem e são deliberadas: índices que começam por outro
campo de filial (a filial de entrega do pedido de compra, C7_FILENT),
índices de busca global por um identificador (E1_IDCNAB, no contas a
receber) e alguns em que a filial vem depois do campo buscado. Para uma tabela
sua, não há motivo para imitar a exceção: comece pela filial.
Depois do 9 vem o A. A ORDEM tem um caractere só. Passou de nove
índices, a numeração segue em letras — no dicionário padrão há tabela
chegando à ordem T. Em código, dbSetOrder(10) é a ordem A.
Data entra com DTOS(). O índice é de texto; o campo data é convertido
para AAAAMMDD para ordenar certo. Mais sobre o formato em
Tipos de dados em AdvPL.
Mostra Pesq
A documentação da SIX define SHOWPESQ assim: preenchido com S, o
índice é mostrado no browse do sistema. Com S, ele entra nas ordens que o
usuário escolhe ao pesquisar; com N, continua existindo e funcionando para o
código (DbSetOrder, DbOrderNickName), só não é oferecido a quem pesquisa.
No padrão há os dois casos — na SB1, as ordens A (B1_FILIAL+B1_BASE3),
C (B1_FILIAL+B1_CONTA) e D (B1_FILIAL+B1_CC) são N.
A mesma página traz a regra que pega tabela nova: toda tabela precisa de
pelo menos um índice com SHOWPESQ = S para poder ser exibida dentro de
um browse. Na ZA1, é o índice 1 que cumpre esse papel.
Na ZA1 desta série, os dois índices ficam visíveis:
| Ordem | Chave | Descrição | Mostra Pesq |
|---|---|---|---|
| 1 | ZA1_FILIAL+ZA1_COD | Codigo | S |
| 2 | ZA1_FILIAL+ZA1_NOME | Nome | S |
Onde se cria
Pela documentação da TOTVS, o caminho é o Configurador, em Base de Dados > Dicionário: abra o Dicionário de Dados, localize a tabela, entre em edição, vá em Índices e inclua. No campo da chave, as ações relacionadas oferecem a lista de campos para montar a expressão — filial primeiro. Marque Mostra Pesq se o usuário deve ver o índice e informe o Nickname. Confirme duas vezes, clique em Atualizar Base de Dados e vá avançando até Finalizar — sem esse passo, o índice fica só no que você digitou.
Nickname: por que o índice seu em tabela padrão precisa dele
Suponha que a transportadora desta série criou na SC5 o campo
C5_XMOTOR, com o código do motorista do pedido, e quer achar os pedidos de
um motorista. O índice novo entra depois dos onze do padrão — digamos, na
ordem C. O código natural seria:
SC5->(DbSetOrder(12)) // ordem C, hojeFunciona até a próxima atualização de dicionário. A documentação da TOTVS
pede que, antes de rodar um compatibilizador, os índices personalizados
estejam identificados pelo nickname: se o compatibilizador precisar criar
índices, vai adicioná-los a partir da ordem original instalada pelo Protheus,
o que pode sobrescrever índices personalizados sem nickname. A ordem C que
era sua passa a ser de um índice do padrão. O DbSetOrder(12) continua
compilando e rodando, só que agora num índice com outra chave. O DbSeek não acha o que deveria, ou acha outra
coisa, e nenhum erro aparece.
O nickname tira a posição da equação. O índice ganha um nome — ZMOTOR — e o
código chama pelo nome:
| Ordem | Chave | Nickname | Mostra Pesq |
|---|---|---|---|
| (a próxima livre) | C5_FILIAL+C5_XMOTOR+C5_NUM | ZMOTOR | N |
DBOrderNickname(cApelido) seleciona o índice pelo apelido. Se o apelido não
existir, a função mostra erro e devolve .F. — o que é bem melhor que
pesquisar em silêncio no índice errado:
#Include "Protheus.ch"
/*/{Protheus.doc} ZPEDMOT
Conta os pedidos de venda de um motorista usando o indice customizado
de nickname ZMOTOR (C5_FILIAL+C5_XMOTOR+C5_NUM), e nao a posicao dele.
@type user function
@param cMotor, character, codigo do motorista (ZA1_COD)
@return numeric, quantidade de pedidos encontrados
/*/
User Function ZPEDMOT(cMotor)
Local aArea := GetArea()
Local aAreaSC5 := {}
Local cChave := ""
Local nQtd := 0
DbSelectArea("SC5")
aAreaSC5 := SC5->(GetArea())
// A chave precisa ter o tamanho do campo: codigo curto nao casa.
cChave := xFilial("SC5") + PadR(cMotor, TamSX3("C5_XMOTOR")[1])
// Pelo nome, nunca pela posicao.
If SC5->(DbOrderNickName("ZMOTOR"))
SC5->(DbSeek(cChave))
While SC5->(!Eof()) .And. SC5->(C5_FILIAL + C5_XMOTOR) == cChave
nQtd++
SC5->(DbSkip())
EndDo
EndIf
RestArea(aAreaSC5)
RestArea(aArea)
Return nQtdO próprio padrão usa esse desenho — há rotina da TOTVS chamando
SB7->(DbOrderNickName("ACDSB701")). O GetArea/RestArea em volta existe
porque a função troca a ordem da SC5; quem chamou não pode sentir isso
(GetArea e RestArea em AdvPL).
Na tabela customizada (ZA1), não há índice do padrão disputando posição.
Ali o nickname é opcional.
Confira no seu ambiente
Os índices de uma tabela, na ordem em que o código os enxerga:
SELECT ORDEM, CHAVE, DESCRICAO, NICKNAME, SHOWPESQ, PROPRI
FROM SIX010
WHERE INDICE = 'SC5'
AND D_E_L_E_T_ = ' '
ORDER BY ORDEMO sufixo 010 é o da empresa; troque pelo do seu ambiente.
E a consulta que vale rodar antes de qualquer atualização de dicionário: os índices criados pelo cliente que ainda não têm nickname.
SELECT INDICE, ORDEM, CHAVE, DESCRICAO
FROM SIX010
WHERE PROPRI = 'U'
AND LTRIM(RTRIM(NICKNAME)) = ''
AND D_E_L_E_T_ = ' '
ORDER BY INDICE, ORDEMCada linha numa tabela padrão é candidata a nickname — e cada fonte que usa
aquele índice por DbSetOrder é candidato a revisão.
Se a sua base tem índice customizado sem nickname e uma atualização pela frente, fale com a gente.
Referências
Central de Atendimentocentraldeatendimento.totvs.com
Central de Atendimento TOTVS — Como criar índices no ProtheusCaminho de inclusão, Mostra Pesq, nickname, Atualizar Base de Dados e criação física do índice só quando a tabela é aberta.TDNtdn.totvs.com
TDN — SIX, Índice das TabelasColunas da SIX, ordem de 1 a 9 e depois letras, e a regra de ao menos um índice com SHOWPESQ = S para a tabela aparecer em browse.TDNtdn.totvs.com
TDN — DBOrderNicknameSintaxe DBOrderNickname(cApelido) e retorno .F. quando o apelido não existe.TDNtdn.totvs.com
TDN — Atualização de dicionário de dados do ACDOrientação de identificar índices customizados por nickname antes de rodar o compatibilizador.
Continue por aqui
- Vídeo
ProtheusReferência técnica
Modo de edição (X3_WHEN): quando o campo pode ser editado
X3_WHEN decide quando um campo pode ser editado além de Alterar ou Visualizar: a edição passa a depender da operação, de outro campo ou do usuário.