Automatize o Controle de Despesas para Freelancers no Sheets
Monte um categorizador de despesas autoatualizável no Google Sheets com mapeamento dinâmico de colunas, tabela de regras de fornecedores e saídas que alimentam um DRE real ou modelo de burn rate.
Este guia mostra como construir um categorizador automático de despesas no Google Sheets que normaliza exportações bagunçadas de bancos e processadores de pagamento, mapeia descrições de fornecedores a categorias usando uma tabela de regras de fácil manutenção e alimenta um DRE com os valores mensais reais - uma estrutura que você pode referenciar em um modelo de burn rate ou apresentar a um investidor.
O que você vai precisar
- Conta Google com acesso ao Google Sheets
- Exportação CSV de um banco (Itaú, Nubank, Bradesco), Stripe ou ferramenta de contabilidade
- Familiaridade básica com SUMIFS, INDEX/MATCH e fórmulas de matriz
- Uma lista de categorias alinhada às linhas do seu DRE real (Software, Folha de Pagamento, Marketing etc.) - não às categorias fiscais da Receita Federal
- (Opcional) Acesso ao Google Apps Script para conjuntos de dados acima de 2.000 linhas
Guia passo a passo
Crie a Arquitetura de 3 Abas
Separe o fluxo de dados em 3 abas: Importação, Despesas e Resumo. Parece óbvio, mas a maioria dos rastreadores de despesas quebrados falha porque alguém colou uma exportação CSV diretamente sobre as fórmulas existentes. Isso apaga as fórmulas, os dados ficam crus e nada agrega corretamente.
- Importação**: Uma zona de colagem bruta - nenhuma fórmula vive aqui, jamais. Os dados do CSV chegam aqui e permanecem intocados.
- Despesas**: A camada de normalização. Cada linha aqui é uma fórmula que puxa dados de Importação, limpos e categorizados.
- Resumo**: Agregação pura. SUMIFS contra Despesas, agrupados por categoria e mês.
- Regras**: Uma aba separada que mapeia padrões de palavras-chave de fornecedores para nomes de categorias. Você a mantém independentemente de toda a lógica de fórmulas.
Pro Tip
Proteja a aba Importação de edições acidentais usando Dados → Proteger planilhas e intervalos. É muito fácil digitar em uma célula sem querer e corromper a zona de colagem.Construa um Localizador Dinâmico de Colunas
Exportações de bancos, repasses do Stripe e dumps de ferramentas de contabilidade não chegam na mesma ordem de colunas todo mês. Seu banco pode colocar a data na coluna A; seu software de contabilidade pode colocá-la na coluna D. Essa sequência também pode mudar quando você altera as configurações de exportação ou adiciona um novo campo de dados.
A solução é uma busca na linha de cabeçalho que encontra a coluna certa pelo nome, não pela posição. Na aba Despesas, defina 3 células auxiliares que armazenam o índice de coluna de cada campo que você precisa:
=MATCH("Date", Importação!$1:$1, 0)
=MATCH("Description", Importação!$1:$1, 0)
=MATCH("Amount", Importação!$1:$1, 0)
Nomeie essas células col_date, col_desc, col_amount usando a Caixa de Nome. Depois, nas linhas de Despesas, puxe os dados dinamicamente:
=INDEX(Importação!$A:$Z, ROW(A2), col_date)
=INDEX(Importação!$A:$Z, ROW(A2), col_desc)
=INDEX(Importação!$A:$Z, ROW(A2), col_amount)
Agora, quando sua exportação chegar com Descrição na coluna C em vez da coluna B no próximo mês, nada quebra. A busca na linha de cabeçalho a encontra e todas as fórmulas subsequentes se ajustam automaticamente.
Pro Tip
Adicione um quarto MATCH para qualquer coluna que varie por fonte - "Memo", "Referência", "Contraparte" aparecem em posições diferentes dependendo do banco.Normalize as Descrições de Fornecedores
As descrições brutas de fornecedores nas exportações bancárias são problemáticas: espaços extras, letras maiúsculas e minúsculas misturadas, espaços em branco adicionais de campos OCR, artefatos de codificação. Duas transações do mesmo fornecedor podem parecer completamente diferentes para uma fórmula SEARCH se uma tiver um espaço extra.
Na aba Despesas, adicione uma coluna Fornecedor_Limpo que aplica três transformações em sequência:
=TRIM(UPPER(SUBSTITUTE(C2, " ", " ")))
TRIM remove espaços no início e no final. UPPER elimina diferenças entre maiúsculas e minúsculas. SUBSTITUTE colapsa espaços duplos que às vezes aparecem em campos de memo exportados. Esta única coluna é o que todas as fórmulas subsequentes vão referenciar - a descrição de importação bruta permanece intocada em sua própria coluna como trilha de auditoria.
Para normalização de datas, adicione uma coluna Data_Limpa. Formatos de data mistos - DD/MM/AAAA vs AAAA-MM-DD vs "16 abr 2026" - são comuns ao puxar de múltiplas fontes. Force-os para um valor padrão:
=IF(ISNUMBER(D2), D2, DATEVALUE(D2))
Pro Tip
Formate Data_Limpa como data, não como geral. DATEVALUE retorna um número serial que aparece como "46000-e-algo" até você aplicar a formatação de data.Monte a Tabela de Regras de Fornecedores
A aba Regras contém uma tabela de 2 colunas: Palavra-chave na coluna A, Categoria na coluna B. Este é o único lugar que você toca quando um novo fornecedor aparece ou você quer reclassificar uma categoria.
| Palavra-chave | Categoria |
|---|---|
| ZOOM | Software |
| GOOGLE CLOUD | Software |
| AWS | Software |
| NOTION | Software |
| FACEBOOK ADS | Marketing |
| Marketing | |
| STRIPE FEE | Processamento de Pagamentos |
| TOTVS | Folha de Pagamento |
| LATAM | Viagens |
Algumas regras de design que importam. As palavras-chave devem corresponder à parte mais distintiva da descrição do fornecedor - não "GOOGLE" (muito amplo, captura Google Drive, Google Ads e Google Cloud como a mesma coisa), mas "GOOGLE CLOUD" ou "GOOGLE ADS" especificamente. Não há limite artificial para a quantidade de regras por categoria; use quantas forem necessárias para ser preciso. Um processador de pagamentos que gera 7 variantes diferentes de string para o mesmo fornecedor precisa de 7 linhas de palavras-chave.
Mantenha as palavras-chave ordenadas por especificidade dentro de cada categoria - padrões mais específicos primeiro. O categorizador retorna a primeira correspondência, então "FACEBOOK ADS" deve aparecer antes de "FACEBOOK" se ambos estiverem na tabela.
Pro Tip
Adicione uma terceira coluna, Observações, para registrar por que uma regra existe. Quando você voltar a esta tabela em 6 meses se perguntando por que "AMZN MKTPLACE" mapeia para Software em vez de Diversos, você vai querer esse contexto.Escreva o Categorizador com INDEX/MATCH
A fórmula de categoria varre sua tabela de Regras em busca de qualquer palavra-chave que apareça dentro da descrição limpa do fornecedor. Na aba Despesas, adicione uma coluna Categoria:
=IFERROR(INDEX(Regras!$B$2:$B$100, MATCH(TRUE, ISNUMBER(SEARCH(Regras!$A$2:$A$100, E2)), 0)), "Sem Categoria")
Digite com Ctrl+Shift+Enter para torná-la uma fórmula de matriz (em versões mais recentes do Sheets, você também pode envolver a expressão interna em ARRAYFORMULA). A fórmula retorna a primeira categoria cuja palavra-chave aparece em qualquer lugar da descrição limpa do fornecedor - correspondências parciais funcionam, então "GOOGLE CLOUD STORAGE" acerta corretamente a regra "GOOGLE CLOUD" mesmo sem serem idênticos.
O fallback "Sem Categoria" é mais importante do que parece. Se você retornar "" para linhas sem correspondência, essas transações desaparecem silenciosamente dos totais do SUMIFS - o SUMIFS ignora células em branco. Usar uma string explícita faz com que as despesas sem correspondência apareçam como sua própria categoria no resumo, onde você pode ver exatamente o que ainda não foi mapeado. Essa visibilidade é o que indica quando sua tabela de Regras precisa de atualização.
Pro Tip
Após executar a fórmula, filtre a coluna Categoria por "Sem Categoria" e ordene por Valor em ordem decrescente. As maiores transações sem correspondência mostram exatamente quais regras adicionar primeiro.Monte a Grade de Resumo com SUMIFS
A aba Resumo agrega totais por categoria e mês. Configure uma grade com categorias na coluna A e meses na linha 1 (formatados como o primeiro dia de cada mês, ex.: 2026-01-01). Então, para cada célula na grade:
=SUMIFS(Despesas!$F:$F, Despesas!$G:$G, $A2, Despesas!$H:$H, ">="&B$1, Despesas!$H:$H, "<"&EDATE(B$1, 1))
Onde a coluna F é Valor, a coluna G é Categoria e a coluna H é Data_Limpa. O EDATE(B$1, 1) delimita o intervalo de datas ao mês calendário sem precisar codificar datas de fim.
Adicione uma linha Total na parte inferior (SOMA de cada coluna do mês) e uma linha Orçamento onde você insere seu gasto planejado por categoria. A variância é simplesmente Realizado menos Orçado:
=B3 - B2
Aplique formatação condicional às células de variância: vermelho para acima do orçamento, verde para abaixo. Isso é uma verificação útil, mas não é o resultado final - é uma camada de entrada.
Pro Tip
Use referências de coluna inteira com cuidado.Despesas!$F:$F funciona bem na prática, mas varrer 1.000.000 de linhas para 200 linhas reais desperdiça tempo de recálculo em planilhas grandes. Delimite seu intervalo para Despesas!$F$2:$F$5000 assim que souber seu volume de dados.Conecte o Resumo a uma Estrutura de DRE
Este é o passo que a maioria dos guias de controle de despesas pula. A grade de Resumo do Passo 6 é útil para controle contábil pessoal, mas não é um modelo financeiro - é uma tabela plana. Para torná-la útil como entrada para um modelo de burn rate ou um DRE voltado a investidores, você precisa de uma aba DRE separada que trate o Resumo como uma camada de Realizado.
Configure a aba DRE com sua estrutura completa de linhas na coluna A, alinhada à forma como os custos aparecem em um demonstrativo de resultados real:
| Linha | Jan | Fev | Mar |
|---|---|---|---|
| Receita | |||
| Custo dos Serviços | |||
| - Hospedagem e Infraestrutura | |||
| - Processamento de Pagamentos | |||
| Lucro Bruto | |||
| Despesas Operacionais | |||
| - Software e Assinaturas | |||
| - Folha de Pagamento | |||
| - Marketing | |||
| - Viagens | |||
| Total de OpEx | |||
| EBITDA |
Cada célula de Realizado no DRE puxa do Resumo usando uma referência direta ou um SUMIFS que mapeia as linhas do DRE para as categorias do Resumo:
=SUMIFS(Resumo!$B:$B, Resumo!$A:$A, "Software")
Para categorias que se agrupam em uma linha do DRE (ex.: "Hospedagem e Infraestrutura" pode combinar linhas do Resumo para AWS, Google Cloud e Cloudflare), use múltiplos SUMIFS:
=SUMIFS(Resumo!B:B,Resumo!A:A,"Software") + SUMIFS(Resumo!B:B,Resumo!A:A,"Hospedagem")
Esta é a arquitetura: o categorizador popula o Resumo, o Resumo é a camada de entrada de Realizado e a aba DRE é o modelo. A receita vai direto para o DRE ou de seu próprio feed. A partir daí, seus valores mensais reais fluem naturalmente para os cálculos de burn rate e runway - para essa estrutura, veja como calcular o runway de uma startup e dashboard de burn rate de startup.
Pro Tip
Adicione uma linha Orçamento no DRE que referencia uma aba separada de premissas, não valores fixos. A variância de orçamento no DRE passa a ser=Realizado - Orçado, e qualquer revisão de orçamento exige alterar apenas uma célula nas premissas.Automatize a Ingestão com Apps Script
A fórmula de matriz do Passo 5 executa uma comparação N × M a cada recálculo - cada linha em Despesas é varrida contra cada linha da tabela de Regras. Com 500 linhas de despesas contra uma tabela de 50 regras, são 25.000 buscas por recálculo. Com 10.000 linhas, passam a ser 500.000, e você vai notar a planilha travando por vários segundos sempre que uma célula muda.
Para conjuntos de dados acima de 2.000 linhas, mova a categorização para o Apps Script. A lógica é idêntica, mas executa uma vez e grava os resultados em um único lote:
function categorizeExpenses() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const expenses = ss.getSheetByName('Despesas');
const rules = ss.getSheetByName('Regras');
const expData = expenses.getDataRange().getValues();
const ruleData = rules.getRange(2, 1, rules.getLastRow() - 1, 2).getValues();
const categories = [];
for (let i = 1; i < expData.length; i++) {
const vendor = String(expData[i][4]).toUpperCase(); // coluna Fornecedor_Limpo
let matched = 'Sem Categoria';
for (const [keyword, category] of ruleData) {
if (vendor.includes(String(keyword).toUpperCase())) {
matched = category;
break;
}
}
categories.push([matched]);
}
// Gravação em lote único - nunca grave dentro do loop
expenses.getRange(2, 6, categories.length, 1).setValues(categories);
}
A regra crítica: nunca chame setValue() dentro de um loop. Cada gravação individual aciona uma ida e volta à API do Sheets. Com 10.000 linhas, gravar dentro do loop pode levar mais de 15 minutos. O setValues() em lote no final executa a mesma operação em menos de 10 segundos.
Configure um acionador em Extensões → Apps Script → Acionadores para rodar automaticamente ao editar, ou configure para disparar quando a aba Importação mudar. Em abril de 2026, o tempo de execução do Apps Script é limitado a 6 minutos para contas pessoais e 30 minutos para contas Workspace - o padrão de gravação em lote mantém você bem dentro de ambos os limites, mesmo no máximo de 10 milhões de células do Google Sheets.
Pro Tip
AdicioneSpreadsheetApp.flush() após setValues() se você estiver encadeando múltiplas gravações em lote. Sem isso, o Sheets pode armazenar as alterações em buffer e aplicá-las fora de ordem.Conclusão
O que você construiu é um pipeline de dados, não um rastreador. Importação é uma zona de colagem que sobrevive a qualquer formato de exportação. Despesas normaliza e categoriza. Resumo agrega. DRE consome. Cada camada faz um trabalho e passa para a próxima - o que significa que quando seu banco mudar o formato CSV ou você adicionar uma nova categoria de fornecedor, você muda uma coisa e o restante se atualiza automaticamente.
O erro que a maioria dos sistemas de controle de despesas comete é tratar a grade de Resumo como o resultado final. Não é. É um feed de realizado. No momento em que você conecta isso a uma aba de DRE com receita e uma estrutura adequada de linhas, isso deixa de ser um exercício de escrituração e passa a ser um modelo financeiro.
Escolha um plano do ModelMonkey - funciona tanto no Google Sheets quanto no Excel e pode cuidar da categorização, da configuração das fórmulas e da estrutura do DRE em uma única conversa.
Perguntas frequentes
Por que o categorizador INDEX/MATCH precisa de Ctrl+Shift+Enter?
A fórmula usa ISNUMBER(SEARCH(...)) para verificar todas as linhas de palavras-chave simultaneamente, o que requer avaliação de matriz. Sem Ctrl+Shift+Enter (ou um wrapper explícito de ARRAYFORMULA), o Sheets avalia como uma operação escalar contra apenas a primeira linha da tabela de Regras. Na prática: se seu categorizador está retornando apenas a primeira categoria para todos os fornecedores, você esqueceu de inserir como fórmula de matriz.
Qual é o número certo de linhas para estender as fórmulas?
Estenda suas fórmulas de Despesas para 5.000 linhas se você trabalha sozinho; 20.000 se estiver puxando de múltiplas fontes ou processando um ano inteiro de uma vez. As fórmulas SUMIFS e DRE usam intervalos delimitados de qualquer forma, então linhas vazias no final de Despesas não inflam os totais. Evite estender para 1.000.000 de linhas - referências de coluna inteira em grandes conjuntos de fórmulas causam recálculo lento a cada edição.
Como lidar com o mesmo fornecedor aparecendo com 5 variantes diferentes de string?
Adicione todas as 5 variantes como linhas separadas na tabela de Regras, cada uma mapeando para a mesma Categoria. Se as variantes compartilham uma substring distintiva (ex.: todas contêm "STRIPE"), uma regra com essa substring cobre todas elas. Se não compartilham uma string comum, você precisa de uma linha por variante. Isso é esperado - processadores de pagamento e sistemas de PDV geram strings de fornecedor inconsistentes, e uma tabela de regras robusta lida com isso em vez de tentar limpar na origem.
Isso consegue lidar com despesas em múltiplas moedas?
A lógica das fórmulas é agnóstica a moeda - categoriza pela string do fornecedor independentemente da moeda. Para rastreamento em múltiplas moedas, adicione uma coluna Moeda em Despesas e uma coluna Taxa_FX que converte para sua moeda de referência (Real). O SUMIFS no Resumo deve referenciar a coluna convertida (=Valor * Taxa_FX), não o Valor bruto. As taxas de câmbio podem ser obtidas com =GOOGLEFINANCE("CURRENCY:USDBRL") para taxas ao vivo ou inseridas manualmente para um período de reporte.
Como evitar que a tabela de Regras fique fora de controle?
Faça uma auditoria trimestral. Filtre a coluna Categoria por "Sem Categoria" e adicione regras para qualquer fornecedor com gastos acima de R$ 250/mês que ainda não esteja categorizado. Exclua regras de fornecedores que você não usa mais - regras mortas deixam a varredura da fórmula de matriz mais lenta sem motivo. Uma tabela de regras bem mantida para uma operação freelance típica tem entre 30 e 80 linhas; se a sua estiver se aproximando de 200, provavelmente há regras sobrepostas ou redundantes que podem ser consolidadas.