cFilAnt, cEmpAnt, SM0 — quem realmente manda
A diferenca entre cFilAnt, cEmpAnt e a tabela SM0. Quem e definido por quem e o que acontece em JOB sem RpcSetEnv.
Trio inseparavel do Protheus que confunde dev novo:
| Coisa | Onde mora | O que e |
|---|---|---|
cEmpAnt | Variavel Public em memoria | Codigo da empresa logada |
cFilAnt | Variavel Public em memoria | Codigo da filial atual |
| SM0 | Arquivo binario em disco | Cadastro mestre de empresas/filiais |
Quem define quem
Quando o usuario faz login no SmartClient:
- AppServer le SM0 e mostra a lista de empresas/filiais
- Usuario escolhe empresa
99, filial01 - AppServer carrega
cEmpAnt := "99"ecFilAnt := "01"na sessao - Todas as operacoes herdam esse contexto via
xFilial()
Em JOB e que mora a confusao
JOB nao tem login. Se voce nao chamar RpcSetEnv(), cFilAnt e cEmpAnt ficam vazios. xFilial() retorna em branco. DBSeek falha sem voce notar.
// ERRADO em JOB
User Function MeuJob()
ConOut(cFilAnt) // "" — vazio!
SA1->(DBSeek(xFilial("SA1") + "000001"))
// Busca em "" + "000001" — nao acha
Return
// CERTO
User Function MeuJob()
RpcSetType(3)
RpcSetEnv("99", "01", "admin", "senha", "FAT", "Job")
ConOut(cFilAnt) // "01"
// ...
RpcClearEnv()
Return
SM0 e arquivo binario, nao tabela SQL
O cadastro de empresas mora em \system\sigamat.emp — arquivo proprietario, nao tabela SQL. Pra ler ele programaticamente, use FwLoadSM0() ou OpenSM0().
aEmp := FwLoadSM0()
For i := 1 To Len(aEmp)
ConOut(aEmp[i][1] + "/" + aEmp[i][2] + " - " + aEmp[i][7])
Next
Pegadinhas
- Sao Public, nao Private — qualquer User Function pode sobrescrever (e quebrar tudo).
- Multifilial em batch — pra processar todas, loop SM0 + RpcSetEnv em cada uma.
- cEmpAnt + cFilAnt = chave — combine os dois pra log/auditoria.