Pular para o conteúdo
Fynx
Business Intelligence12 min de leitura

Tabela de datas em DAX: o que faz e quando usar (com exemplos)

Guia prático de tabela de datas DAX: como criar com CALENDAR, marcar como tabela de data, relacionar com a fato e evitar as armadilhas mais comuns.

F
Fynx

Seu relatório compara com o ano passado e o número vem errado

Você monta o dashboard, a diretoria olha e pergunta: "e comparado com o mesmo período do ano anterior?". Aí o cálculo devolve branco, ou pior, um crescimento que não existe. Nove em cada dez vezes o problema não está na medida, está na fundação: falta uma tabela de datas DAX de verdade, contínua e marcada como tabela de data. Sem ela, quase toda função de inteligência de tempo do DAX vira loteria.

A tabela de datas, também chamada de dimensão calendário, é a peça que sustenta acumulado no ano, comparação com período anterior, média móvel e qualquer análise que dependa de tempo. Neste artigo eu explico o que essa tabela faz, como criá-la com CALENDAR ou CALENDARAUTO, quais colunas de apoio incluir, por que marcar como tabela de data importa e as armadilhas que quebram o modelo em produção. É conteúdo de base para qualquer projeto de Power BI que precise de números confiáveis ao longo do tempo.

Por que a tabela de datas DAX é obrigatória para time intelligence

As funções de time intelligence do DAX, como TOTALYTD, SAMEPERIODLASTYEAR e DATEADD, não somam colunas. Elas pegam o conjunto de datas que está no contexto de filtro atual, por exemplo março de 2026, e o deslocam ou expandem no tempo para gerar um novo conjunto de datas, que vira o filtro de uma medida. Para esse deslocamento funcionar de forma previsível, o motor precisa de um eixo temporal completo, sem buracos.

E aqui está a raiz do problema. Se você tenta usar a coluna de data da própria tabela fato, o modelo só conhece os dias em que houve movimento. Feriados, fins de semana sem venda e meses parados simplesmente não existem no eixo. Quando DATESYTD tenta acumular de janeiro até a data corrente, ele passa por cima de períodos inteiros sem perceber, e o resultado sai incompleto. A tabela de datas resolve isso porque tem uma linha por dia, exista ou não movimento naquele dia.

Uma tabela de datas adequada precisa cumprir alguns requisitos que não são negociáveis:

  • Uma linha por dia, sem lacunas, cobrindo todo o intervalo dos dados mais os anos usados para comparação.
  • Uma coluna de data com tipo Date, granularidade de dia e sem horário embutido.
  • Anos completos, de 1 de janeiro a 31 de dezembro, mesmo que os dados comecem no meio do ano.
  • Estar marcada como tabela de data, para o motor tratá-la como o eixo temporal oficial do modelo.

Se algum desses pontos falhar, as funções de tempo podem até rodar, mas devolvem números que não batem com o razão. E número que não bate destrói a confiança na área inteira.

CALENDAR e CALENDARAUTO geram a dimensão calendário

Há duas funções nativas para criar a tabela como tabela calculada. A mais direta é CALENDAR, que recebe uma data inicial e uma final e devolve uma única coluna chamada Date com todos os dias do intervalo.

Calendario =
CALENDAR(
    DATE(2021, 1, 1),
    DATE(2027, 12, 31)
)

Repare que eu fixei o intervalo de forma explícita. Isso é intencional. Prefiro definir início e fim à mão porque assim tenho controle total sobre o alcance do calendário e não fico refém de datas erradas que aparecem na fato, como um pedido lançado com ano 2099 por erro de digitação.

A alternativa é CALENDARAUTO, que varre o modelo, identifica a menor e a maior data em qualquer coluna de tipo data e monta um calendário de anos fiscais completos que cobre tudo. Você pode informar o mês de fim do ano fiscal como argumento, por exemplo CALENDARAUTO(6) para um ano fiscal que fecha em junho.

Calendario = CALENDARAUTO()

CALENDARAUTO é conveniente, mas tem um efeito colateral perigoso: aquela data digitada errada como 2099 estica o calendário até lá e infla o modelo. Por isso, em projeto sério, eu costumo ficar com CALENDAR e um intervalo definido, ou envolver a lógica em CALENDARAUTO com um filtro. A tabela abaixo resume quando usar cada uma.

CritérioCALENDARCALENDARAUTO
IntervaloDefinido manualmente por vocêDetectado automaticamente das datas do modelo
Controle sobre datas fora do padrãoTotal, você fixa início e fimBaixo, uma data errada estica tudo
Ano fiscal customizadoVocê monta a lógicaArgumento nativo com o mês de fim
Melhor cenárioProdução e modelos com regras própriasProtótipo rápido ou modelo com datas confiáveis
Risco principalEsquecer de estender o fim do intervaloInflar o modelo por data espúria na fato

Nenhuma das duas cria as colunas de apoio sozinha. Ambas devolvem só a coluna de datas. O enriquecimento vem no próximo passo.

As colunas de apoio transformam datas em análise

Uma coluna de datas pura serve para pouco. O que faz a dimensão calendário virar ferramenta de análise são as colunas derivadas: Ano, Trimestre, Mês, número do mês, nome do mês e dia da semana. Elas permitem agrupar, ordenar e filtrar sem escrever DAX toda vez. A forma mais limpa de criá-las é numa única tabela calculada com ADDCOLUMNS.

Calendario =
ADDCOLUMNS(
    CALENDAR(DATE(2021, 1, 1), DATE(2027, 12, 31)),
    "Ano", YEAR([Date]),
    "Trimestre", "T" & QUARTER([Date]),
    "NumeroMes", MONTH([Date]),
    "Mes", FORMAT([Date], "mmm", "pt-BR"),
    "AnoMes", FORMAT([Date], "yyyy-mm"),
    "DiaDaSemana", FORMAT([Date], "dddd", "pt-BR"),
    "NumeroDiaSemana", WEEKDAY([Date], 2)
)

Duas boas práticas que evitam dor de cabeça depois. Primeiro, sempre crie uma coluna numérica de apoio para cada coluna de texto que precise de ordenação. O nome do mês em texto ordena alfabeticamente por padrão, então "abr" viria antes de "jan". Use NumeroMes para configurar "Classificar por coluna" no campo Mes, e faça o mesmo com NumeroDiaSemana para o dia da semana. Segundo, mantenha nomes de coluna em português e consistentes, porque quem consome o modelo no autoatendimento vai arrastar esses campos direto para o visual.

A tabela a seguir mostra o papel de cada coluna típica de uma dimensão calendário madura.

ColunaTipoPara que serve
DateDataChave do relacionamento e eixo de time intelligence
AnoNúmero inteiroFiltro e agrupamento por ano
TrimestreTextoVisões trimestrais em relatórios executivos
NumeroMesNúmero inteiroOrdenar o nome do mês corretamente
MesTextoRótulo amigável no eixo dos gráficos
AnoMesTextoEixo contínuo em séries temporais longas
DiaDaSemanaTextoAnálise de sazonalidade semanal
NumeroDiaSemanaNúmero inteiroOrdenar dias e separar dias úteis de fins de semana

Se o seu negócio usa ano fiscal, feriados ou semanas contábeis, essa é a hora de incluir colunas próprias como AnoFiscal, TrimestreFiscal e um sinalizador de dia útil. Modelar isso bem no começo evita retrabalho quando a diretoria pedir a visão fiscal. Vale revisar nossos princípios em modelagem e boas práticas de DAX antes de escalar o calendário para o modelo corporativo.

Marcar como tabela de data habilita as funções de tempo

Criar a tabela e relacioná-la com a fato não basta. Você precisa ir em Ferramentas de Tabela e usar a opção "Marcar como tabela de data", apontando para a coluna Date. Esse passo não é enfeite. Ele avisa ao motor que aquela é a dimensão temporal oficial do modelo, e é o que garante que o contexto de filtro de data se propague de forma correta quando funções como TOTALYTD e SAMEPERIODLASTYEAR removem e reaplicam filtros internamente.

Sem marcar, algumas funções de time intelligence podem devolver resultados imprevisíveis, porque o motor não sabe qual coluna representa o eixo de tempo confiável. Ao marcar, o Power BI valida a tabela: ela precisa ter valores únicos e contínuos na coluna de data, sem lacunas nem repetições. Se a validação reclamar, é sinal de que o calendário tem buraco ou duplicidade, e é melhor descobrir isso agora do que num fechamento de mês.

Com a tabela marcada, uma medida de acumulado no ano fica assim, e funciona de forma consistente:

Vendas YTD =
CALCULATE(
    [Total Vendas],
    DATESYTD(Calendario[Date])
)

Um detalhe importante: se você usa o recurso de tabelas de data automáticas do Power BI, aquele que cria uma minitabela oculta por coluna de data, desligue em qualquer projeto que se leve a sério. Ele incha o modelo, cria hierarquias duplicadas e tira de você o controle sobre o eixo temporal. Uma dimensão calendário explícita e marcada é sempre superior.

O relacionamento deve ser único e na direção certa

A regra de ouro do modelo em estrela vale aqui integralmente: a dimensão calendário se relaciona com a tabela fato por um relacionamento um para muitos, do lado um na dimensão para o lado muitos na fato, com filtro em direção única. A chave é a coluna Date da dimensão ligada à coluna de data da fato.

Se a sua fato tem mais de uma data relevante, por exemplo data do pedido e data de faturamento, resista à tentação de criar duas tabelas calendário. O caminho correto é ter uma única dimensão calendário com um relacionamento ativo, digamos pela data do pedido, e um relacionamento inativo pela data de faturamento. Você ativa o inativo sob demanda dentro da medida com USERELATIONSHIP.

Faturamento por Emissao =
CALCULATE(
    [Total Faturado],
    USERELATIONSHIP(Calendario[Date], Faturas[DataEmissao])
)

Esse padrão, conhecido como role-playing dimension, mantém o modelo enxuto e evita a confusão de ter duas tabelas de tempo competindo pelo mesmo eixo. Uma dimensão calendário compartilhada por todas as fatos é o que permite cruzar vendas, compras e estoque no mesmo período com segurança. Se o seu desafio é integrar várias fontes num modelo assim, nossa engenharia de dados resolve a base antes de o problema chegar ao DAX.

As armadilhas que quebram a tabela de datas em produção

Depois de dezenas de modelos revisados, os erros se repetem. Vale conhecer os principais antes de tropeçar neles:

  • Usar a data da fato como eixo. Sem tabela dedicada, dias sem movimento somem e o acumulado fica furado. Sempre crie a dimensão.
  • Calendário curto demais. Se os dados vão até 2027 mas o calendário para em 2026, a comparação com o ano seguinte devolve branco. Estenda o intervalo com folga.
  • Ano incompleto. Começar o calendário em uma data no meio do ano quebra o DATESYTD, que espera anos fechados de janeiro a dezembro.
  • Não marcar como tabela de data. As funções de tempo até rodam, mas o resultado fica imprevisível em cenários de remoção de filtro.
  • Deixar as tabelas de data automáticas ligadas. Elas incham o modelo e criam hierarquias que competem com a sua dimensão.
  • Relacionamento bidirecional sem necessidade. Filtro nos dois sentidos entre calendário e fato abre caminho para ambiguidade e números errados. Mantenha direção única.
  • Ignorar a cardinalidade. O VertiPaq, motor que roda por baixo do Power BI, comprime cada coluna por cardinalidade. Ano, Mês e Trimestre têm cardinalidade baixa e comprimem bem, então o calendário fica leve mesmo com vários anos. Evite só o que é desnecessário, como um horário embutido na coluna de data.

Nenhuma dessas armadilhas é difícil de evitar. O que elas têm em comum é que só aparecem quando o modelo já está em uso e a diretoria já confiou no número. Corrigir antes custa minutos, corrigir depois custa credibilidade.

Perguntas frequentes

Preciso de uma tabela de datas mesmo em um relatório simples de vendas?

Sim, se o relatório tiver qualquer comparação temporal. Assim que alguém pedir acumulado no ano, mês anterior ou variação contra o ano passado, você vai precisar da dimensão calendário. Montar depois, com o modelo já em produção, dá muito mais trabalho do que começar certo.

CALENDAR ou CALENDARAUTO, qual eu uso?

Em produção, prefira CALENDAR com intervalo definido à mão, porque você controla o alcance e não fica exposto a datas erradas na fato. CALENDARAUTO é ótimo para protótipo rápido ou quando as datas do modelo são confiáveis e você quer praticidade.

Posso criar a tabela de datas no Power Query em vez de DAX?

Pode, e em muitos casos é até melhor. Uma tabela de datas no Power Query ou vinda de um data warehouse não precisa ser recalculada a cada refresh e centraliza a regra em um lugar. A escolha entre DAX e Power Query é de arquitetura, não de certo ou errado. O que não muda é a necessidade de marcar como tabela de data.

Por que minha função de time intelligence retorna em branco?

Quase sempre por calendário incompleto ou por falta de anos fechados. Verifique se o intervalo cobre o período comparado, se cada ano vai de janeiro a dezembro e se a tabela está marcada como tabela de data. Esses três pontos resolvem a maioria dos brancos inesperados.

O que "marcar como tabela de data" muda de verdade?

Ele declara ao motor qual é o eixo temporal oficial e garante que o contexto de filtro de data se propague corretamente quando as funções removem e reaplicam filtros. Também valida se a coluna de data é única e contínua, o que pega buracos no calendário antes de eles virarem erro de número.

Como lidar com duas datas na fato, como pedido e faturamento?

Use uma única dimensão calendário com um relacionamento ativo e outro inativo, e ative o inativo dentro da medida com USERELATIONSHIP. Evite criar duas tabelas de tempo, porque isso duplica lógica e abre espaço para inconsistência.

Comece pela base e o resto do modelo agradece

A tabela de datas é o item mais barato de fazer certo e o mais caro de fazer errado. Uma dimensão calendário contínua, enriquecida com colunas de apoio, marcada como tabela de data e ligada à fato por um relacionamento único é o que separa a time intelligence confiável do número que ninguém audita. Se o seu modelo já tem esse alicerce, escalar para YTD, ano anterior e média móvel é rotina.

Se a sua equipe está apanhando de comparações temporais ou herdou um modelo com o calendário mal resolvido, fale com a gente. A Fynx acumula mais de 10.000 horas de desenvolvimento em Power BI e resolve a base antes de o problema chegar ao dashboard.

Quer aplicar isso na sua empresa?

A Fynx implementa BI, Power BI e Power Platform de ponta a ponta. Conte seu cenário e devolvemos um diagnóstico direto ao ponto.

Falar com um especialista

Vamos transformar seus dados em decisão?

Conte seu cenário. Devolvemos um diagnóstico e uma proposta com faixa de investimento em poucos dias úteis, sem folheto, direto ao ponto.