Toda análise de tempo no Power BI depende de uma coisa só: uma tabela calendário bem feita. Sem ela, as funções de inteligência de tempo do DAX — TOTALYTD, SAMEPERIODLASTYEAR, DATEADD — simplesmente não funcionam. Ou pior: funcionam errado.

A maioria das pessoas cria uma tabela calendário básica, funciona, e não mexe mais nisso. Aí chega aquele cliente que fecha o ano fiscal em junho, ou a empresa que usa trimestre fiscal diferente do trimestre calendário — e o dashboard inteiro vira um caos de datas erradas.

Neste artigo você vai ver como criar a tabela calendário direto no Power Query (código M), com as colunas que mais aparecem nos relatórios, e como adicionar Ano Fiscal configurável de um jeito que você muda com uma variável e não precisa refazer tudo.

💡 Por que Power Query e não DAX?

Você pode criar a tabela calendário via DAX com CALENDARAUTO() ou CALENDAR(). Funciona. Mas no Power Query você tem mais controle, pode adicionar colunas de texto formatadas em português com localidade correta, e o código fica versionável junto com a query de dados — mais fácil de manter.

O que é uma tabela calendário e por que o Power BI exige uma

Uma tabela calendário é uma tabela com uma linha para cada dia em um intervalo contínuo de datas. Sem lacunas. Sem repetições. Cada data aparece uma vez.

O Power BI usa essa tabela para criar o que chama de "tabela de datas marcada" — uma referência central que o motor DAX usa para calcular acumulados, comparações entre períodos e filtros de tempo.

  • Sem tabela calendário: TOTALYTD vai tentar criar a própria tabela de datas internamente — e vai errar se as datas da sua tabela de fatos tiverem lacunas ou duplicatas.
  • Com tabela calendário incompleta: se o intervalo não cobrir todas as datas da tabela de fatos, o relacionamento vai quebrar ou produzir resultados errados silenciosamente.
  • Com tabela calendário marcada corretamente: todas as funções de inteligência de tempo funcionam como esperado.
⚠️ Erro silencioso comum

Muita gente cria a tabela calendário com datas fixas no código (ex: início em 01/01/2020). Quando a base de dados cresce para além dessas datas, o Power BI não dá erro — ele simplesmente ignora as linhas fora do intervalo. O relatório parece certo mas os totais estão incompletos.

1 Crie a tabela calendário automática no Power Query

A primeira decisão é: o intervalo de datas vai ser fixo ou dinâmico? Sempre prefira dinâmico — o código lê a data mínima e máxima direto da sua tabela de fatos. Quando os dados crescerem, o calendário cresce junto.

No Power BI Desktop, clique em Transformar Dados → Novo Parâmetro → Consulta em Branco. Nomeie a consulta como dCalendario e cole o código abaixo no Editor Avançado.

Substitua fVendas pelo nome da sua tabela de fatos e Data pelo nome da coluna de data.

let
    // --- CONFIGURAÇÃO: ajuste aqui ---
    TabelaFatos     = fVendas,
    ColunaData      = TabelaFatos[Data],
    MesInicioFiscal = 7,   // julho = início do ano fiscal; mude para 1 se não usar ano fiscal
    // ----------------------------------

    DataInicio = Date.StartOfYear(List.Min(ColunaData)),
    DataFim    = Date.EndOfYear(List.Max(ColunaData)),
    Duracao    = Duration.Days(DataFim - DataInicio) + 1,

    ListaDatas = List.Dates(DataInicio, Duracao, #duration(1, 0, 0, 0)),
    Tabela     = Table.FromList(ListaDatas, Splitter.SplitByNothing(), {"Data"}),
    TipoData   = Table.TransformColumnTypes(Tabela, {{"Data", type date}}),

    cAno         = Table.AddColumn(TipoData,   "Ano",          each Date.Year([Data]),                             Int64.Type),
    cMesNum      = Table.AddColumn(cAno,        "Mês Número",   each Date.Month([Data]),                            Int64.Type),
    cMesNome     = Table.AddColumn(cMesNum,     "Mês",          each Date.ToText([Data], "MMM", "pt-BR"),           type text),
    cMesAno      = Table.AddColumn(cMesNome,    "Mês-Ano",      each Date.ToText([Data], "MMM/yy", "pt-BR"),        type text),
    cDia         = Table.AddColumn(cMesAno,     "Dia",          each Date.Day([Data]),                              Int64.Type),
    cDiaSemana   = Table.AddColumn(cDia,        "Dia da Semana",each Date.ToText([Data], "dddd", "pt-BR"),          type text),
    cDiaSemanaN  = Table.AddColumn(cDiaSemana,  "Dia Semana Nº",each Date.DayOfWeek([Data], Day.Monday) + 1,       Int64.Type),
    cTrimestre   = Table.AddColumn(cDiaSemanaN, "Trimestre",    each "T" & Text.From(Date.QuarterOfYear([Data])),   type text),
    cSemana      = Table.AddColumn(cTrimestre,  "Semana ISO",   each Date.WeekOfYear([Data]),                       Int64.Type),

    cAnoFiscal   = Table.AddColumn(cSemana, "Ano Fiscal",
                      each if Date.Month([Data]) >= MesInicioFiscal
                           then Date.Year([Data]) + 1
                           else Date.Year([Data]),
                      Int64.Type),

    cMesFiscal   = Table.AddColumn(cAnoFiscal, "Mês Fiscal",
                      each let m = Date.Month([Data])
                           in if m >= MesInicioFiscal
                              then m - MesInicioFiscal + 1
                              else m + (12 - MesInicioFiscal) + 1,
                      Int64.Type),

    cTrimestreFiscal = Table.AddColumn(cMesFiscal, "Trimestre Fiscal",
                      each "TF" & Text.From(Number.RoundUp([#"Mês Fiscal"] / 3)),
                      type text),

    cAnoFiscalLabel  = Table.AddColumn(cTrimestreFiscal, "Ano Fiscal Label",
                      each "AF " & Text.From([Ano Fiscal]),
                      type text)
in
    cAnoFiscalLabel

2 Entenda o que cada bloco faz

Bloco de configuração

As três variáveis no topo são os únicos pontos que você precisa alterar para adaptar a qualquer projeto:

  • TabelaFatos: referência à sua tabela de fatos.
  • ColunaData: a coluna de data que vai definir o intervalo.
  • MesInicioFiscal: o número do mês em que o seu ano fiscal começa. 7 = julho, 4 = abril, 1 = janeiro.

Colunas de texto em português

Date.ToText([Data], "MMM", "pt-BR") retorna o nome abreviado do mês em português, como jan, fev, mar. Sem o "pt-BR", o Power Query usa o locale do seu sistema — e se você publicar no serviço, os nomes podem vir em inglês.

💡 Dica de ordenação

Colunas de texto como "Mês" e "Dia da Semana" precisam ser ordenadas pela coluna numérica correspondente para aparecer na ordem certa nos visuais. No Power BI Desktop: selecione a coluna de texto → Ferramentas de Coluna → Classificar por Coluna.

3 Como o Ano Fiscal funciona no código

Vamos supor que seu ano fiscal começa em julho (MesInicioFiscal = 7):

  • Julho de 2024 a junho de 2025 = Ano Fiscal 2025
  • Julho de 2025 a junho de 2026 = Ano Fiscal 2026

A lógica do Ano Fiscal: se o mês da data é maior ou igual ao mês de início do fiscal, o ano fiscal é o ano calendário + 1. Caso contrário, é o próprio ano calendário.

O Mês Fiscal recalcula o número do mês dentro do ano fiscal. Julho vira mês 1, agosto vira mês 2, e assim por diante até junho = mês 12.

⚠️ Atenção ao referenciar "Mês Fiscal" no código

Note que na etapa cTrimestreFiscal, o campo é referenciado como [#"Mês Fiscal"] com o #"..." porque o nome contém acento. Se você renomear a coluna sem acento (ex: Mes Fiscal), pode usar [Mes Fiscal] normalmente.

Quer levar esse nível de análise para os seus clientes?

Na formação Chora API Revolution você aprende a conectar ERPs, bancos e plataformas direto no Power BI via API — sem exportar arquivo nenhum.

Ver a Formação

Erros comuns ao configurar a tabela calendário

Erro 1

Esqueceu de marcar como Tabela de Datas
Você criou o calendário, criou o relacionamento, mas as funções de time intelligence continuam com comportamento estranho.

Correção: No Power BI Desktop, clique com o botão direito na tabela dCalendarioMarcar como Tabela de Datas → selecione a coluna Data.

Erro 2

Calendário com lacunas nas datas
Se o intervalo tiver datas faltando, o Power BI vai rejeitar a marcação como tabela de datas.

Correção: Verifique se a tabela de fatos tem registros. Adicione proteção: DataInicio = if List.Min(ColunaData) = null then #date(2020,1,1) else Date.StartOfYear(List.Min(ColunaData)).

Erro 3

Nomes de meses em inglês no serviço do Power BI
Funcionou no Desktop, mas depois de publicar os meses aparecem como "Jan", "Feb", "Mar".

Correção: Sempre passe o locale explicitamente: Date.ToText([Data], "MMM", "pt-BR").

Erro 4

Ano Fiscal calculado com off-by-one
O ano fiscal está tudo certo, mas está adiantado ou atrasado um ano em relação ao esperado.

Correção: Defina a convenção com o cliente antes de codar. A forma mais comum no Brasil: o Ano Fiscal leva o nome do ano em que ele termina. Julho/2024–Junho/2025 = AF 2025.

Erro 5

Relacionamento criado na direção errada
Criou o relacionamento, mas os filtros do visual de data não estão filtrando a tabela de fatos corretamente.

Correção: O relacionamento deve ser de um para muitos — a coluna Data da tabela calendário (lado "um") ligada à coluna de data da tabela de fatos (lado "muitos"). Direção do filtro cruzado: "Única".

Bônus

Coluna extra que vale adicionar: Mês Fechado

Se o seu relatório trabalha com metas ou comparações de período fechado vs. período aberto, adicione essa coluna logo antes do in final. Ela marca true para todos os meses anteriores ao mês atual — perfeito para filtros de "somente meses fechados" em medidas DAX.

cMesFechado = Table.AddColumn(cAnoFiscalLabel, "Mês Fechado",
                each Date.EndOfMonth([Data]) < Date.From(DateTime.LocalNow()),
                type logical)

Depois, no DAX, você usa essa coluna diretamente em filtros de measure ou em segmentações — sem precisar de lógica de data condicional nas próprias medidas.

Resumindo o que você tem agora

Com o código deste artigo você tem uma tabela calendário que:

  • Lê o intervalo de datas direto da tabela de fatos — sem hardcode
  • Gera colunas de mês, trimestre, semana e dia da semana em português
  • Calcula Ano Fiscal, Mês Fiscal e Trimestre Fiscal com uma única variável de configuração
  • Funciona corretamente depois de publicar no serviço do Power BI

Para adaptar ao seu ano fiscal, mude só o valor de MesInicioFiscal no topo do código. Quer ano fiscal iniciando em abril? MesInicioFiscal = 4. Outubro? MesInicioFiscal = 10. O restante do código se ajusta automaticamente.

Quer dominar Power BI com dados de API — sem exportar arquivo nenhum?

Na formação Chora API Revolution você conecta ERPs, bancos e plataformas direto no Power BI via API, com automação em n8n e banco de dados no Supabase.

Ver a Formação