Financeiro e Controladoria
DRE gerencial, fluxo de caixa e orçado x realizado
Contexto
Indústria de médio porte, faturamento de R$ 320 milhões por ano, três unidades de negócio e cinco centros de custo por unidade. O fechamento gerencial levava 9 dias úteis e era montado no Excel por duas pessoas. A meta é publicar a DRE no terceiro dia útil, com abertura por unidade, comparação com orçamento e explicação automática das maiores variações.
Perguntas que o painel deve responder
- Qual foi o resultado do mês por unidade de negócio e por centro de custo?
- Quais linhas da DRE mais se afastaram do orçamento e em quanto?
- Temos caixa para os próximos 60 dias, considerando contas a pagar e a receber?
- A margem caiu por preço, por custo de matéria-prima ou por mix de produto?
- Quais clientes concentram a inadimplência?
Indicadores e metas
| Indicador | Meta | Por que importa |
|---|---|---|
| Receita Bruta e Líquida | Conforme orçamento | Base de tudo; a diferença entre elas revela a carga tributária |
| Margem de Contribuição | ≥ 38% | Separa o que é custo variável do que é estrutura |
| EBITDA e Margem EBITDA | ≥ 15% | Geração de caixa operacional, comparável entre empresas |
| Variação Orçamentária | ±5% | Desvio é o que exige ação, não o valor absoluto |
| Saldo e Projeção de Caixa | ≥ 45 dias de cobertura | Lucro não paga fornecedor; caixa paga |
| Prazo Médio de Recebimento | ≤ 42 dias | Cada dia a mais é capital de giro imobilizado |
| Inadimplência > 30 dias | ≤ 2,5% | Antecipa perda que ainda não virou provisão |
Modelo de dados
O coração do modelo financeiro é o plano de contas hierárquico com sinal contábil e ordem de exibição. Sem isso, a DRE nunca sai na ordem certa nem soma corretamente.
| Tabela | Papel | Observação |
|---|---|---|
| fLancamentos | Fato | Um lançamento contábil por linha, com data, conta, centro de custo e valor |
| fOrcamento | Fato | Mês × Conta × Centro de custo |
| fContasReceber | Fato | Título em aberto, com vencimento e data de baixa |
| fContasPagar | Fato | Título a pagar, com vencimento previsto |
| dPlanoContas | Dimensão | Conta, grupo, subgrupo, nível, sinal, ordem |
| dCentroCusto | Dimensão | Centro, área, unidade de negócio |
| dCalendario | Dimensão | Com ano fiscal, se diferente do civil |
-- A coluna Sinal resolve o maior problema da DRE em Power BI:-- despesas gravadas como positivo precisam ser subtraídas.SELECT IdConta, Codigo, -- 3.01.02 Descricao, -- Despesas com Pessoal Grupo, -- Despesas Operacionais Subgrupo, -- Administrativas Nivel, -- 3 Sinal, -- 1 para receita, -1 para custo e despesa OrdemExibicao, -- 310102 (numérico, controla a ordem na DRE) ContaDRE -- Marca quais contas entram no demonstrativoFROM dbo.PlanoContas;Medidas DAX
Valor com sinal contábil
Valor =SUMX( fLancamentos, fLancamentos[Valor] * RELATED( dPlanoContas[Sinal] ) )Aplicar o sinal na medida — e não na carga — permite exibir tanto a visão gerencial (despesa negativa) quanto a analítica (valor absoluto) do mesmo dado.
Linhas da DRE
Receita Bruta = CALCULATE( [Valor], dPlanoContas[Grupo] = "Receita Bruta" )Deduções = CALCULATE( [Valor], dPlanoContas[Grupo] = "Deduções" )Receita Líquida = [Receita Bruta] + [Deduções]CPV = CALCULATE( [Valor], dPlanoContas[Grupo] = "Custo dos Produtos Vendidos" )Lucro Bruto = [Receita Líquida] + [CPV]Despesas Operacionais = CALCULATE( [Valor], dPlanoContas[Grupo] = "Despesas Operacionais" )EBITDA = [Lucro Bruto] + [Despesas Operacionais]Margem EBITDA % = DIVIDE( [EBITDA], [Receita Líquida] )Com o sinal já aplicado, as linhas se somam naturalmente. É por isso que a coluna Sinal é a decisão de modelagem mais importante da controladoria.
DRE em matriz única
Resultado DRE =VAR Grupo = SELECTEDVALUE( dPlanoContas[Grupo] )VAR Subtotal = SELECTEDVALUE( dLinhaDRE[Linha] )RETURNSWITCH( Subtotal, "Receita Líquida", [Receita Líquida], "Lucro Bruto", [Lucro Bruto], "EBITDA", [EBITDA], [Valor])Uma tabela auxiliar dLinhaDRE, desconectada, permite intercalar subtotais calculados entre as contas analíticas na mesma matriz.
Orçado x Realizado
Orçado =CALCULATE( SUM( fOrcamento[Valor] ), TREATAS( VALUES( dCalendario[AnoMes] ), fOrcamento[AnoMes] ), TREATAS( VALUES( dPlanoContas[IdConta] ), fOrcamento[IdConta] ), TREATAS( VALUES( dCentroCusto[IdCentro] ), fOrcamento[IdCentro] )) Variação $ = [Valor] - [Orçado] Variação % = DIVIDE( [Variação $], ABS( [Orçado] ) ) Status Orçamento =VAR Ehreceita = SELECTEDVALUE( dPlanoContas[Sinal] ) = 1VAR V = [Variação %]RETURNSWITCH( TRUE(), ISBLANK( [Orçado] ), "Sem orçamento", Ehreceita && V >= 0.00, "Favorável", Ehreceita && V >= -0.05, "Atenção", Ehreceita, "Desfavorável", NOT Ehreceita && V <= 0.00, "Favorável", NOT Ehreceita && V <= 0.05, "Atenção", "Desfavorável")Gastar menos que o orçado é favorável; faturar menos é desfavorável. O status precisa conhecer a natureza da conta — é o erro mais comum em painéis financeiros.
Fluxo de caixa projetado
Saldo Inicial =CALCULATE( [Movimento de Caixa], dCalendario[Date] < MIN( dCalendario[Date] ), REMOVEFILTERS( dCalendario )) A Receber no Período =CALCULATE( SUM( fContasReceber[Valor] ), USERELATIONSHIP( fContasReceber[DataVencimento], dCalendario[Date] ), ISBLANK( fContasReceber[DataBaixa] )) A Pagar no Período =CALCULATE( SUM( fContasPagar[Valor] ), USERELATIONSHIP( fContasPagar[DataVencimento], dCalendario[Date] ), ISBLANK( fContasPagar[DataBaixa] )) Saldo Projetado =[Saldo Inicial] +SUMX( FILTER( ALLSELECTED( dCalendario[Date] ), dCalendario[Date] <= MAX( dCalendario[Date] ) ), [A Receber no Período] - [A Pagar no Período]) Dias de Cobertura =DIVIDE( [Saldo Atual], DIVIDE( [Despesa Operacional d], 90 ) )USERELATIONSHIP é essencial: os títulos têm data de emissão (relacionamento ativo) e de vencimento (inativo). O fluxo de caixa olha o vencimento.
Aging de recebíveis
-- dFaixaAging: tabela desconectada com Faixa, Min, Max, OrdemValor na Faixa =VAR MinD = SELECTEDVALUE( dFaixaAging[Min] )VAR MaxD = SELECTEDVALUE( dFaixaAging[Max] )RETURNCALCULATE( SUM( fContasReceber[Valor] ), FILTER( fContasReceber, ISBLANK( fContasReceber[DataBaixa] ) && DATEDIFF( fContasReceber[DataVencimento], TODAY(), DAY ) >= MinD && DATEDIFF( fContasReceber[DataVencimento], TODAY(), DAY ) < MaxD )) Inadimplência % =DIVIDE( CALCULATE( [Valor na Faixa], dFaixaAging[Min] >= 30 ), [Total a Receber]) PMR =VAR TitulosBaixados = FILTER( fContasReceber, NOT ISBLANK( fContasReceber[DataBaixa] ) )RETURNAVERAGEX( TitulosBaixados, DATEDIFF( fContasReceber[DataEmissao], fContasReceber[DataBaixa], DAY ))A tabela de faixas desconectada é o padrão para aging: as faixas ficam configuráveis sem alterar o modelo.
Explicação automática da variação
Maiores Desvios =VAR Base = ADDCOLUMNS( VALUES( dPlanoContas[Descricao] ), "@Desvio", [Variação $] )VAR Top3 = TOPN( 3, Base, ABS( [@Desvio] ), DESC )RETURNCONCATENATEX( Top3, dPlanoContas[Descricao] & " (" & FORMAT( [@Desvio], "R$ #,##0;(R$ #,##0)" ) & ")", "; ", ABS( [@Desvio] ), DESC)Essa medida em uma caixa de texto elimina a pergunta 'o que explica a diferença?' antes que ela seja feita.
Layout do painel
- 1Página 1 — DRE: matriz com o plano de contas hierárquico nas linhas, e colunas Realizado, Orçado, Variação R$ e Variação %, com cor por Status Orçamento e ícone de tendência.
- 2Cabeçalho da página 1: cartões de Receita Líquida, Lucro Bruto, EBITDA, Margem EBITDA, todos com variação contra orçamento.
- 3Caixa de texto no topo com a medida Maiores Desvios.
- 4Página 2 — Caixa: linha de saldo projetado nos próximos 90 dias, com faixa sombreada indicando o mínimo de segurança; colunas de entradas e saídas por semana.
- 5Página 3 — Recebíveis: aging em barras por faixa, matriz de clientes ordenada por valor vencido, PMR em linha histórica.
- 6Página 4 — Centro de Custo: árvore hierárquica de decomposição da despesa, permitindo ao gestor achar a origem do estouro.
- 7Drill-through em qualquer conta: lista de lançamentos com número do documento e link para o ERP.
Desafio final
Construa a DRE completa com subtotais intercalados e a análise de variação orçamentária com status sensível à natureza da conta. Depois adicione uma quarta coluna com o acumulado do ano contra o orçamento anual e o percentual de consumo do orçamento.