Trabalho Por Equipe DevBras

Capa do artigo: Coletor do Audesp aceitou o arquivo? Confira se o conteúdo bate com a sua base

Coletor do Audesp aceitou o arquivo? Confira se o conteúdo bate com a sua base

O coletor confere formato, não a verdade dos dados. Um roteiro para reconciliar o arquivo gerado com a base de origem antes de enviar, com script de conferência.

Último dia do prazo, 16h. O arquivo de setembro da prefeitura passa pelo coletor sem erro, a equipe respira e envia. Duas semanas depois, o controle interno percebe que o sistema de gestão tem 412 empenhos em setembro e o arquivo enviado tem 409. Os três que faltam foram registrados no dia 30, depois da meia-noite, e a consulta de exportação usava data_empenho <= '2026-09-30' numa coluna com hora. O coletor não tinha como saber: o arquivo estava bem formado, só estava incompleto.

A resposta curta: o coletor e os validadores conferem se o arquivo segue o formato esperado, e às vezes algumas regras de consistência. Eles não sabem o que existe na sua base. Antes de enviar, reconcilie: compare quantidade de registros, totais e uma amostra de casos conhecidos entre o arquivo gerado e o sistema de origem. Guarde o arquivo enviado, a versão do leiaute e o comprovante.

O que o coletor confere, e o que ele não pode conferir

Uma ferramenta de coleta recebe o arquivo pronto. Ela consegue verificar estrutura (os elementos esperados estão lá, na ordem e no tipo certo) e regras que dependem só do próprio arquivo, como um campo obrigatório preenchido ou um código dentro de uma lista permitida. Quanto disso cada ferramenta faz depende dela e da fase; o manual da fase é a referência, como explica manual da fase do Audesp não é opcional.

O que nenhuma ferramenta externa faz é comparar o arquivo com a sua base. Se a exportação esqueceu um filtro, trocou um sinal, arredondou um valor ou deixou de fora um tipo de registro, o arquivo continua bem formado e passa. O tribunal lê o arquivo, não a sua tela, e é por isso que o que segue no arquivo é o que vale.

A confusão comum é tratar "o coletor abriu" como "o arquivo está certo". São perguntas diferentes, e só a segunda importa para quem responde pela prestação de contas.

Como conferir antes de enviar, passo a passo

  1. Anote a versão do leiaute no código que gera o arquivo, numa constante, e no nome ou nos metadados do arquivo gerado.
  2. Gere o arquivo do período a partir do sistema, sem edição manual depois.
  3. Exporte da base, por outra consulta, a lista de controle: os mesmos registros com identificador e valor. De preferência, uma consulta escrita por outra pessoa ou revisada à parte.
  4. Compare as duas: quantidade, soma dos valores, registros que faltam, que sobram e que divergem.
  5. Abra três casos conhecidos na mão: um comum, um com valor alto e um com alguma particularidade (anulação parcial, por exemplo). Leia no arquivo os campos que você esperaria ver.
  6. Só então passe pelo coletor e envie. Guarde o arquivo exato enviado, o comprovante e o resultado da conferência.

Um script de reconciliação

O script abaixo, em Python com biblioteca padrão, compara um arquivo XML com uma lista de controle em CSV. Os nomes de elemento são ilustrativos; os reais estão no leiaute da fase que você envia. Ajuste REGISTRO, CAMPO_ID e CAMPO_VALOR.

import csv
import sys
import xml.etree.ElementTree as ET
from decimal import Decimal, InvalidOperation

REGISTRO = 'Empenho'
CAMPO_ID = 'NumeroEmpenho'
CAMPO_VALOR = 'Valor'


def ler_arquivo(caminho):
    raiz = ET.parse(caminho).getroot()
    itens, problemas = {}, []
    for reg in raiz.findall('.//{*}' + REGISTRO):
        numero = reg.findtext('{*}' + CAMPO_ID)
        valor = reg.findtext('{*}' + CAMPO_VALOR)
        if not numero or not valor:
            problemas.append('registro sem número ou valor')
            continue
        try:
            itens[numero.strip()] = Decimal(valor.strip())
        except InvalidOperation:
            problemas.append('valor inválido no registro ' + numero)
    return itens, problemas


def ler_controle(caminho):
    with open(caminho, newline='', encoding='utf-8-sig') as f:
        leitor = csv.DictReader(f, delimiter=';')
        return {l['numero'].strip(): Decimal(l['valor'].strip()) for l in leitor}


arquivo, problemas = ler_arquivo(sys.argv[1])
controle = ler_controle(sys.argv[2])

faltando = sorted(set(controle) - set(arquivo))
sobrando = sorted(set(arquivo) - set(controle))
divergentes = [n for n in sorted(set(controle) & set(arquivo)) if controle[n] != arquivo[n]]

print('registros  base:', len(controle), ' arquivo:', len(arquivo))
print('total      base:', sum(controle.values()), ' arquivo:', sum(arquivo.values()))
for n in faltando:
    print('FALTA no arquivo:', n)
for n in sobrando:
    print('SOBRA no arquivo:', n)
for n in divergentes:
    print('VALOR diferente:', n, controle[n], 'x', arquivo[n])
for p in problemas:
    print('PROBLEMA:', p)

sys.exit(1 if faltando or sobrando or divergentes or problemas else 0)

O CSV de controle usa ponto como separador decimal e ponto e vírgula entre colunas, com cabeçalho numero;valor; a codificação utf-8-sig aceita o arquivo com ou sem a marca BOM que planilhas costumam gravar. Os valores são lidos como Decimal, não como número de ponto flutuante, para a soma não ganhar centavos fantasmas (o mesmo cuidado de dinheiro em centavos).

No caso da prefeitura, a saída teria sido esta:

registros  base: 412  arquivo: 409
total      base: 1873420.55  arquivo: 1851090.55
FALTA no arquivo: 2026/004118
FALTA no arquivo: 2026/004119
FALTA no arquivo: 2026/004120

Três linhas, um minuto de leitura, e o erro da consulta aparece antes do envio. O conserto da exportação foi trocar o filtro para data_empenho >= '2026-09-01' AND data_empenho < '2026-10-01', que pega o mês inteiro qualquer que seja a hora.

Guardar o que foi enviado

Depois do envio, a pergunta deixa de ser "está certo?" e passa a ser "o que exatamente mandamos?". Guarde, para cada período, o arquivo enviado sem alterações, o comprovante de entrega, a versão do leiaute, a saída da reconciliação e um hash do arquivo (por exemplo, com sha256sum no Linux ou Get-FileHash no PowerShell). Se houver retificação, guarde as duas versões, nunca sobrescreva.

Quando o leiaute mudar, a constante de versão no código muda junto, num commit próprio, com link para o documento oficial. Assim, quem gerar um arquivo antigo de novo sabe com qual regra ele foi feito. O mesmo raciocínio vale para outros arquivos públicos, como mostra XML de compras públicas tem versão.

Este roteiro é uma prática de conferência técnica. Ele não substitui o manual oficial, as orientações do tribunal nem a análise do controle interno e da contabilidade do órgão.

Erros comuns

  • Tratar "o coletor aceitou" como conferência. Um arquivo bem formado e incompleto chega ao tribunal, e o erro aparece na análise, não no envio.
  • Filtro de data com <= em coluna com hora. Os registros do último dia, depois da meia-noite, somem do arquivo sem nenhum aviso.
  • Planilha paralela como verdade. A planilha diz uma coisa, o arquivo outra, e ninguém sabe qual das duas foi para o tribunal.
  • Editar o arquivo na mão depois de gerado. O próximo envio repete o erro, porque o sistema continua gerando errado.
  • Versão do leiaute só na memória. Um arquivo gerado com a regra antiga passa despercebido até ser rejeitado ou questionado.
  • Não guardar o arquivo enviado. Numa diligência, o órgão não consegue mostrar o que mandou, só o que o sistema gera hoje.

Checklist

  • A versão do leiaute está numa constante no código e no arquivo gerado.
  • Existe uma lista de controle tirada da base por consulta independente.
  • Quantidade e totais do arquivo batem com a lista de controle.
  • Três casos conhecidos foram lidos no arquivo, campo a campo.
  • Filtros de período usam intervalo fechado no início e aberto no fim.
  • O arquivo enviado, o comprovante, o hash e a saída da conferência estão guardados juntos.
  • Retificações não sobrescrevem a versão anterior.

Pegue o último arquivo que a sua equipe enviou: a quantidade de registros e o total dele batem com o que o sistema mostra para o mesmo período, e você consegue provar isso agora?

Avalie este artigo

Referência: https://www.tce.sp.gov.br/audesp/coletor