SA1 — Clientes
A tabela central de clientes do Protheus. Cadastra PF e PJ, dados de cobranca, limite de credito, endereco, contato. Chave A1_FILIAL+A1_COD+A1_LOJA.
SA1 e a tabela mais importante do lado de Vendas/Faturamento. Cada cliente PF ou PJ tem 1 ou mais registros aqui (chave A1_COD + A1_LOJA — varias "lojas" = filiais do mesmo CNPJ).
Estrutura essencial
| Campo | Tipo | Descricao |
|---|---|---|
| A1_FILIAL | C | Filial (xFilial) |
| A1_COD | C | Codigo do cliente |
| A1_LOJA | C | Loja (geralmente "01" pra matriz) |
| A1_PESSOA | C | F = PF, J = PJ |
| A1_TIPO | C | F=Consumidor Final, R=Revendedor, S=Solidario, X=Exportacao, L=Produtor Rural |
| A1_NOME | C | Nome/Razao social |
| A1_NREDUZ | C | Nome reduzido |
| A1_CGC | C | CNPJ/CPF (so digitos) |
| A1_INSCR | C | IE ou ISENTO |
| A1_END | C | Endereco |
| A1_BAIRRO | C | Bairro |
| A1_MUN | C | Municipio |
| A1_EST | C | UF |
| A1_CEP | C | CEP |
| A1_TEL | C | Telefone |
| A1_EMAIL | C | |
| A1_LC | N | Limite de credito |
| A1_VENCLC | D | Vencimento do limite |
| A1_MSBLQL | C | 1=Bloqueado, 2=Ativo |
| A1_RISCO | C | A, B, C, D, E (risco credito) |
| A1_GRPVEN | C | Grupo de vendas (segmentacao) |
Indices padrao (SIX)
| Ordem | Chave | Uso |
|---|---|---|
| 1 | A1_FILIAL+A1_COD+A1_LOJA | Busca padrao por codigo |
| 2 | A1_FILIAL+A1_NOME | Pesquisa por nome |
| 3 | A1_FILIAL+A1_CGC | Busca por CNPJ/CPF |
| 5 | A1_FILIAL+A1_NREDUZ | Por nome reduzido |
| 6 | A1_FILIAL+A1_PESSOA+A1_NOME | Filtro PF/PJ + nome |
Modo de compartilhamento (SX2)
SA1 e tipicamente compartilhada (X2_MODO = 'C') — uma vez cadastrado, vale pra todas filiais da empresa. Mas pode ser configurado como exclusiva. Por isso SEMPRE use xFilial("SA1") em vez de hardcoded.
Como ler em codigo
// Buscar cliente por codigo
SA1->(DBSetOrder(1))
If SA1->(DBSeek(xFilial("SA1") + "000123" + "01"))
cNome := AllTrim(SA1->A1_NOME)
cEmail := AllTrim(SA1->A1_EMAIL)
EndIf
// Buscar por CNPJ
SA1->(DBSetOrder(3))
If SA1->(DBSeek(xFilial("SA1") + "12345678000195"))
cCodigo := AllTrim(SA1->A1_COD)
EndIf
// Loop por todos clientes ativos
SA1->(DBSetOrder(1))
SA1->(DBSeek(xFilial("SA1")))
While !SA1->(Eof()) .And. SA1->A1_FILIAL == xFilial("SA1")
If SA1->A1_MSBLQL != "1" // nao bloqueado
// processar
EndIf
SA1->(DBSkip())
EndDo
Tabelas relacionadas
| Tabela | Relacao |
|---|---|
| SE1 | Titulos a receber do cliente (E1_CLIENTE+E1_LOJA) |
| SC5 | Pedidos do cliente (C5_CLIENTE+C5_LOJACLI) |
| SF2 | NFs emitidas (F2_CLIENTE+F2_LOJA) |
| SA3 | Vendedores (vinculados em A1_VEND) |
| SE4 | Condicoes de pagamento (A1_COND) |
| SU5 | Contatos do cliente |
Pegadinhas
- Mesmo CNPJ pode ter varios codigos via A1_LOJA — matriz + filiais.
- Chave de busca padrao envolve A1_COD + A1_LOJA — esqueceu A1_LOJA = busca errada.
- A1_CGC sem formatacao — so digitos. Pra exibir, use Transform.
- Modo compartilhado — A1_FILIAL geralmente fica vazio.
xFilial("SA1")retorna vazio nesse caso. - Bloqueio: A1_MSBLQL "1" bloqueia operacoes (impede pedido). Cheque antes de criar pedido.
- Limite de credito vencido: A1_VENCLC < dDataBase = cliente nao pode comprar a prazo. Geralmente o sistema gera bloqueio C9_BLCRED=04.
Operacoes comuns
Inclusao via ExecAuto (MATA030)
Ver tutorial: ExecAuto MATA030 — incluir cliente
Inativar cliente (em vez de excluir)
RecLock("SA1", .F.)
SA1->A1_MSBLQL := "1"
SA1->(MsUnlock())
// Inativacao logica e melhor que delete fisico
Anti-padroes
- Hardcodar limite de credito em codigo — sempre ler de A1_LC.
- Buscar cliente sem xFilial — pode pegar de outra filial.
- Excluir cliente em base com SF2/SE1 vinculados — quebra integridade fiscal.