A importância da tabela dimensão calendário no Power BI

A tabela dimensão calendário, também chamada de DCalendario, é um dos
componentes mais importantes de um modelo de dados no Power BI. Ela
centraliza datas, anos, meses, trimestres, semanas e outros atributos
temporais utilizados nos cálculos e visuais do relatório.

Por que criar uma dimensão calendário?

Utilizar somente as datas existentes em uma tabela de vendas, cadastros ou
movimentações pode provocar problemas. Essas tabelas geralmente possuem
períodos sem registros, datas repetidas e mais de uma coluna relacionada
ao tempo. A dimensão calendário cria uma sequência contínua, com uma linha
para cada dia, permitindo análises cronológicas mais confiáveis.

Com essa estrutura, torna-se mais fácil analisar resultados por mês,
trimestre, semestre e ano. Também é possível comparar períodos, acompanhar
acumulados e usar funções de inteligência de tempo do DAX com maior
segurança.

Exemplo: em um projeto de Recursos Humanos, a mesma
dimensão pode auxiliar nas análises de admissões e desligamentos,
garantindo que todos os períodos apareçam nos gráficos, inclusive aqueles
sem movimentações.

Como adicionar a DCalendario ao Power BI

O código abaixo foi escrito em linguagem M e deve ser utilizado no Power
Query. Antes de colá-lo, verifique os nomes da tabela e das colunas de
datas que serão usadas para determinar o início e o fim do calendário.

  1. Abra o projeto no Power BI Desktop.
  2. Clique em Transformar dados para abrir o Power Query.
  3. Crie uma Consulta Nula.
  4. Selecione a nova consulta e abra o Editor Avançado.
  5. Apague o conteúdo existente.
  6. Copie o código abaixo e cole no Editor Avançado.
  7. Clique em Concluído e renomeie a consulta para DCalendario.

 

let
    // Alterar somente a Tabela e a coluna de datas
    /* A Tabela é onde possui uma coluna Data que deseja usar em seus cálculos ou visuais. 
       Exemplo. Tabela fVendas que possui a coluna Data Pedido ficaria:
       List.Min (fVendas[Data Pedido]).
       Se possuir mais de uma coluna, ficaria:
       List.Min (fVendas[Data Pedido] & fVendas[Data Vencimento]).
    */

    MenorData = List.Min (fCadastro[Data de Admissão] & fCadastro[Data de Desligamento]),
    MaiorData = List.Max (fCadastro[Data de Admissão] & fCadastro[Data de Desligamento]),

    // Não alterar daqui pra baixo
    DataInicio = Date.StartOfYear(MenorData),
    DataFim = Date.EndOfYear(MaiorData),
    Dias = Duration.Days(DataFim - DataInicio) + 1,
    ListarDatas = List.Dates(DataInicio, Dias, #duration(1,0,0,0)),

    Tabela =
        #table(
            type table[
                Data = date,
                Ano = Int64.Type,
                NomeMes = text,
                MesAbre = text,
                MesAno = text,
                MesNum = number,
                AnoMesINT = number,
                InicioMes = date,
                Trimestre = Int64.Type,
                TrimestreAbreviado = text,
                Bimestre = text,
                Semestre = text,
                Semana = Int64.Type,
                DiaSemana = Int64.Type,
                NomeDia = text,
                Passado = logical,
                AnoAtual = text,
                MesAtual = text,

                // ======= Novas colunas (equivalentes aos DAX) =======
                #"Dia Nome" = text,
                #"Dia útil" = text,
                Dia = Int64.Type,
                #"Semana Ano" = Int64.Type,
                #"Semana Dia" = Int64.Type,
                #"Semana do Mês" = Int64.Type
                // =====================================================
            ],
            List.Transform(
                ListarDatas,
                each
                    let
                        d = _,
                        // Para equivalências com DAX:
                        // WEEKDAY(...,2)  => segunda=1..domingo=7
                        Weekday_2 = Date.DayOfWeek(d, Day.Monday) + 1,
                        // WEEKDAY(...,1)  => domingo=1..sábado=7
                        Weekday_1 = Date.DayOfWeek(d, Day.Sunday) + 1,
                        // WEEKNUM padrão DAX inicia no domingo
                        WeekNum_Sun = Date.WeekOfYear(d, Day.Sunday),
                        // INT(ROUNDUP(DAY/7,0))
                        SemanaDoMes = Number.RoundUp(Date.Day(d) / 7, 0)
                    in
                    {
                        d,                                             // Data
                        Date.Year(d),                                   // Ano
                        Text.Proper(Date.MonthName(d)),                 // NomeMes
                        Text.Proper(Text.Start(Date.MonthName(d), 3)),  // MesAbre
                        Text.Proper(Text.Start(Date.MonthName(d), 3)) & "-" & Text.End(Text.From(Date.Year(d)), 2), // MesAno
                        Date.Month(d),                                  // MesNum
                        Date.Year(d) * 100 + Date.Month(d),             // AnoMesINT
                        Date.StartOfMonth(d),                           // InicioMes
                        Date.QuarterOfYear(d),                          // Trimestre
                        Text.From(Date.QuarterOfYear(d)) & "º Trim ",   // TrimestreAbreviado
                        Text.From(Number.RoundUp(Date.Month(d)/2, 0)) & "º Bim",   // Bimestre
                        Text.From(Number.RoundUp(Date.Month(d)/6, 0)) & "º Sem",   // Semestre
                        Date.WeekOfMonth(d),                            // Semana
                        Date.DayOfWeek(d),                              // DiaSemana (0=Domingo por padrão)
                        Date.DayOfWeekName(d),                          // NomeDia
                        if d <= MaiorData then true else false,         // Passado
                        if Date.IsInCurrentYear(d) then "Ano Atual" else Text.From(Date.Year(d)), // AnoAtual
                        if Date.IsInCurrentYear(d) and Date.IsInCurrentMonth(d) then "Mês Atual" else Text.Proper(Date.MonthName(d)), // MesAtual

                        // ======= Valores das novas colunas =======
                        Date.ToText(d, "ddd"),                          // Dia Nome (equivalente ao FORMAT(...,"ddd"))
                        if Weekday_2 <= 5 then "True" else "false",     // Dia útil (strings como no seu DAX)
                        Date.Day(d),                                    // Dia
                        WeekNum_Sun,                                    // Semana Ano
                        Weekday_1,                                      // Semana Dia
                        SemanaDoMes                                     // Semana do Mês
                        // =========================================
                    }
            )
        )
in
    Tabela

O que o código cria automaticamente?

O código identifica a menor e a maior data das colunas informadas. Em
seguida, amplia o intervalo para o primeiro dia do ano inicial e o último
dia do ano final. Dessa maneira, o calendário sempre contém anos
completos.

Além da coluna Data, são criados campos como ano, nome do mês, mês
abreviado, número do mês, trimestre, bimestre, semestre, semana e dia da
semana. Há também colunas para identificar o ano atual, o mês atual, datas
passadas e dias úteis. Isso reduz a necessidade de criar diversas colunas
calculadas em DAX.

Configure o modelo de dados

Depois de carregar a consulta, relacione a coluna Data da DCalendario com a
coluna de data da tabela principal. Normalmente, o relacionamento será de
um para muitos, com a dimensão no lado “um”.

Em seguida, selecione a DCalendario na exibição de modelo e utilize a opção
Marcar como tabela de datas, escolhendo a coluna Data.
Nos visuais e segmentações, prefira sempre os campos da dimensão
calendário, e não os campos de data da tabela fato.

Quando o modelo possui várias datas, como admissão e desligamento, podem
ser necessários relacionamentos adicionais ou dimensões com papéis
específicos. Essa decisão dependerá dos cálculos e das análises pretendidas.

Conclusão

A dimensão calendário torna o modelo mais organizado, reutilizável e
preparado para análises temporais. Ela padroniza filtros, evita períodos
ausentes e facilita a criação de medidas. Por isso, adicionar uma
DCalendario deve ser uma das primeiras etapas de praticamente qualquer
projeto profissional no Power BI.

Miguel Rodrigues
Últimos posts por Miguel Rodrigues (exibir todos)