CALCULATETABLE em DAX: o que faz e quando usar (com exemplos)
Entenda CALCULATETABLE DAX na prática: o que a função faz, a diferença para CALCULATE, o uso com FILTER, ALL e KEEPFILTERS e exemplos reais de tabela.
A hora em que você precisa de uma tabela filtrada, e não de um número
Você já sabe filtrar um valor com CALCULATE. Aí chega o dia em que a resposta não é um número: é um conjunto de linhas. Os clientes que compraram acima de um limite, as filiais ativas na região, as categorias que sobraram depois de tirar um filtro. Você tenta embrulhar isso num CALCULATE, o motor reclama que esperava um escalar, e a medida quebra. É exatamente nesse ponto que entra a CALCULATETABLE DAX, a irmã da CALCULATE que devolve tabela em vez de valor. Ela é uma das funções mais subutilizadas do Power BI, e quem aprende a usá-la escreve medidas mais limpas, mais rápidas e muito mais fáceis de manter.
Neste artigo eu explico o que a CALCULATETABLE realmente faz, por que ela é gêmea da CALCULATE mas serve para outra coisa, como ela conversa com FILTER, ALL e KEEPFILTERS, e onde ela brilha de verdade: como tabela intermediária, como variável de tabela e como base para outras medidas. Vou fechar com três exemplos de código que você pode adaptar direto no seu modelo. Se você quer o panorama maior antes de mergulhar, vale ler nosso guia de modelagem e boas práticas de DAX.
CALCULATETABLE avalia uma expressão de tabela num contexto de filtro modificado
A definição oficial é curta e vale decorar: CALCULATETABLE avalia uma expressão de tabela dentro de um contexto de filtro que você modificou. É a mesma ideia da CALCULATE, com uma diferença no primeiro argumento. Na CALCULATE, o primeiro argumento é uma expressão escalar, algo que resulta em um único valor, como SUM(Vendas[Valor]). Na CALCULATETABLE, o primeiro argumento é uma expressão de tabela, algo que resulta em linhas e colunas, como Vendas, VALUES(Cliente[Nome]) ou um FILTER.
A sintaxe segue o mesmo desenho da CALCULATE:
CALCULATETABLE( <expressão de tabela>, <filtro1>, <filtro2>, ... )
O primeiro argumento diz o que você quer trazer. Os argumentos seguintes dizem sob quais filtros. A mecânica de manipulação de contexto é rigorosamente a mesma dos dois lados: filtro na mesma coluna substitui o que vinha do contexto, filtro em coluna diferente cruza por interseção, e os modificadores como ALL e KEEPFILTERS se comportam de forma idêntica. Se você já domina a função CALCULATE, você já domina 90% da CALCULATETABLE. A única coisa que muda é a natureza do resultado.
Guarde esta frase: a CALCULATETABLE não filtra dados por conta própria, ela reescreve o contexto e devolve a tabela que sobrou dentro do recorte novo. Ela é uma tabela pronta para ser contada, somada, iterada ou usada como base de outra coisa.
A diferença para CALCULATE é o que sai, não o que entra
Essa é a confusão que mais atrapalha quem está começando. As duas funções aceitam os mesmos filtros, aplicam a mesma lógica de contexto e parecem intercambiáveis. Não são. O que separa uma da outra é o tipo de retorno, e isso decide onde cada uma pode ser usada.
| Aspecto | CALCULATE | CALCULATETABLE |
|---|---|---|
| Primeiro argumento | Expressão escalar (SUM, COUNT, uma medida) | Expressão de tabela (Vendas, VALUES, FILTER) |
| O que retorna | Um valor único (número ou texto) | Uma tabela (linhas e colunas) |
| Onde é usada | Medidas, colunas calculadas | Tabelas calculadas, variáveis de tabela, argumento de outras funções |
| Modificadores de filtro | ALL, KEEPFILTERS, USERELATIONSHIP e afins | Os mesmos ALL, KEEPFILTERS, USERELATIONSHIP e afins |
| Transição de contexto | Sim, dentro de iteradores | Sim, mesma regra |
Repare na última linha das duas primeiras colunas. A CALCULATE cabe onde o resultado esperado é um escalar: dentro de uma medida que vai virar número num cartão ou numa célula de matriz. A CALCULATETABLE cabe onde o resultado esperado é uma tabela: numa tabela calculada do modelo, numa variável declarada com VAR, ou como argumento de funções que consomem tabela, como COUNTROWS, SUMX, CONCATENATEX e TOPN. Colocar uma no lugar da outra gera erro de tipo na hora. Elas não competem, elas se complementam.
Onde a CALCULATETABLE ganha da CALCULATE no dia a dia
Existem três situações em que a CALCULATETABLE é a escolha natural, e reconhecê-las economiza muito código torto.
Tabelas intermediárias. Às vezes o cálculo tem duas etapas: primeiro você recorta um subconjunto, depois faz uma conta em cima dele. A CALCULATETABLE resolve a primeira etapa com clareza, entregando um subconjunto nomeado que a segunda etapa consome. Isso é muito mais legível do que empilhar filtros aninhados numa expressão só.
Variáveis de tabela. Quando você declara VAR base = CALCULATETABLE(...), você materializa um recorte uma vez e reaproveita em todo o restante da medida. Além de legível, isso evita recalcular a mesma filtragem várias vezes e ajuda o motor a otimizar.
Base para outras medidas e funções. Funções que iteram (SUMX, AVERAGEX, RANKX) precisam de uma tabela para percorrer. A CALCULATETABLE é a forma correta de entregar a tabela certa, já filtrada no contexto que você quer, em vez de deixar o iterador rodar sobre a tabela inteira e depois torcer para o filtro pegar.
Abaixo, o mapa de quando cada função é a resposta:
| Você quer... | Função | Padrão |
|---|---|---|
| Um valor filtrado para o visual | CALCULATE | CALCULATE( [Medida], Tabela[Col] = "x" ) |
| Uma tabela filtrada para reusar | CALCULATETABLE | CALCULATETABLE( Tabela, Tabela[Col] = "x" ) |
| Contar linhas de um recorte | CALCULATETABLE + COUNTROWS | COUNTROWS( CALCULATETABLE( ... ) ) |
| Iterar sobre um subconjunto | CALCULATETABLE + SUMX | SUMX( CALCULATETABLE( ... ), <expr> ) |
| Uma tabela física no modelo | CALCULATETABLE | Nova tabela calculada |
Exemplo 1: uma tabela filtrada como base, o caso mais simples
Vamos ao concreto. Imagine que você quer isolar todos os pedidos de 2025 com valor acima de mil reais, seja para inspecionar numa tabela calculada, seja para servir de base a outros cálculos. Aqui a CALCULATETABLE combina um filtro simples com um FILTER, exatamente como a CALCULATE faria, mas devolvendo linhas:
Pedidos Grandes 2025 =
CALCULATETABLE(
Pedidos,
Pedidos[Ano] = 2025,
FILTER( Pedidos, Pedidos[Valor] > 1000 )
)
O primeiro argumento, Pedidos, é a tabela que queremos de volta. O filtro simples Pedidos[Ano] = 2025 recorta o ano e é resolvido de forma eficiente. O FILTER cuida da condição que um filtro simples não expressa tão bem, o valor acima de mil. O resultado é a tabela Pedidos inteira, com suas colunas, porém contendo apenas as linhas que passam nos dois crivos. Se você criar isso como tabela calculada, ela vira um objeto físico no modelo, útil para conferência ou para relacionamentos auxiliares. Se usar dentro de uma medida, ela vira insumo de contagem ou soma.
Um detalhe de performance que vale desde já: FILTER(Pedidos, ...) percorre a fato linha a linha e, sobre tabelas grandes, custa caro. Quando a condição couber num filtro simples de dimensão, prefira o filtro simples.
Exemplo 2: CALCULATETABLE como variável de tabela dentro de uma medida
Aqui está o uso que mais aparece em projeto real. Você quer contar quantos clientes ativos compraram acima de um patamar, respeitando o contexto do visual (por região, por mês, pelo que o usuário selecionar). A CALCULATETABLE entra como variável de tabela e o COUNTROWS faz a conta em cima dela:
Clientes Ativos de Alto Valor =
VAR BaseClientes =
CALCULATETABLE(
VALUES( Cliente[ClienteID] ),
Cliente[Status] = "Ativo",
KEEPFILTERS( Vendas[Valor] > 5000 )
)
RETURN
COUNTROWS( BaseClientes )
Três coisas acontecem aqui e vale destrinchar cada uma. VALUES(Cliente[ClienteID]) pede a lista distinta de clientes, então a base já sai sem duplicidade. O filtro Cliente[Status] = "Ativo" recorta apenas os ativos. E o KEEPFILTERS(Vendas[Valor] > 5000) faz algo importante: em vez de substituir o filtro que possa existir no contexto sobre valor, ele cruza a condição com o que já estava lá. Sem o KEEPFILTERS, o filtro de valor substituiria qualquer recorte de valor vindo do visual. Com ele, a condição se soma à seleção do usuário por interseção. Esse é o mesmo comportamento do KEEPFILTERS na CALCULATE, e é a prova de que os modificadores funcionam igual nas duas funções.
Poderíamos ter feito parte disso com CALCULATE e uma contagem direta, mas separar a base numa variável de tabela deixa a intenção explícita. Daqui a seis meses, quem abrir a medida entende de imediato que existe um universo chamado "clientes ativos de alto valor" e que a resposta é apenas o tamanho dele. Essa clareza é o que a gente persegue em projetos de Power BI: medida que a próxima pessoa consegue ler.
Exemplo 3: ALL para remover filtro e iterar sobre o que sobrou
O último exemplo mostra a CALCULATETABLE trabalhando com o modificador ALL, servindo de base para um iterador. Suponha que você queira somar o faturamento das categorias, mas ignorando um filtro de subcategoria que esteja no visual, para calcular um total por categoria independente do detalhamento:
Faturamento por Categoria (sem subcategoria) =
VAR Categorias =
CALCULATETABLE(
VALUES( Produto[Categoria] ),
ALL( Produto[Subcategoria] )
)
RETURN
SUMX(
Categorias,
CALCULATE( [Total Vendas] )
)
O ALL(Produto[Subcategoria]) remove qualquer filtro de subcategoria do contexto, mantendo intactos os demais filtros, como ano ou região, porque são outras colunas. A CALCULATETABLE entrega então a lista de categorias visível depois dessa remoção. O SUMX percorre essa lista e, para cada categoria, o CALCULATE([Total Vendas]) dispara a transição de contexto, transformando a linha atual da iteração em filtro e trazendo o total daquela categoria. É o mesmo ALL da CALCULATE, aplicado exatamente com a mesma semântica, só que aqui ele molda uma tabela em vez de um número.
Esse padrão de montar a tabela certa e depois iterar é a espinha dorsal de muitos cálculos avançados, de rankings a alocações. Quando o número não fecha, quase sempre o problema está em qual tabela o iterador percorre, e a CALCULATETABLE resolve isso na origem. É o tipo de raciocínio que sustenta nossos trabalhos de analytics avançado.
Os cuidados que evitam retrabalho
A CALCULATETABLE herda os comportamentos da CALCULATE, inclusive os que pegam gente desprevenida. Três merecem destaque.
Filtro na mesma coluna substitui, não soma. Se o contexto já traz subcategoria "A" e você passa subcategoria "B", vence o seu: some a "A". Quando a intenção é cruzar em vez de substituir, use KEEPFILTERS. Confundir os dois é a causa mais comum de "esse número está trazendo linha a mais" ou "a menos".
A tabela retornada carrega o contexto, não só as colunas. A CALCULATETABLE devolve a estrutura da tabela pedida, mas o conjunto de linhas depende dos filtros ativos no momento da avaliação. A mesma medida devolve tabelas diferentes em células diferentes da matriz. Isso é o esperado, mas surpreende quem imagina uma tabela estática.
Cuidado com FILTER sobre a fato. Vale a mesma regra da CALCULATE: filtre a dimensão sempre que a condição permitir e reserve o FILTER sobre a fato para quando a lógica realmente exigir olhar linha a linha.
Perguntas frequentes
CALCULATETABLE e CALCULATE são a mesma função com nomes diferentes? Não, mas são irmãs. A lógica de modificar o contexto de filtro é idêntica nas duas, e elas aceitam os mesmos filtros e modificadores. A diferença é o retorno: CALCULATE devolve um valor escalar e CALCULATETABLE devolve uma tabela. Você escolhe pela natureza do resultado que precisa, um número para o visual ou uma tabela para reusar.
Posso usar CALCULATETABLE direto numa medida como se fosse o resultado?
Não diretamente, porque uma medida precisa entregar um escalar e a CALCULATETABLE entrega tabela. O caminho é usá-la dentro de uma função que reduza a tabela a um valor, como COUNTROWS, SUMX ou AVERAGEX, ou guardá-la numa variável de tabela e depois reduzir. Ela é insumo, não a resposta final da medida.
KEEPFILTERS e ALL funcionam igual na CALCULATETABLE e na CALCULATE? Sim, exatamente igual. ALL remove filtros do contexto, ALLEXCEPT remove quase todos preservando os que você indicar, e KEEPFILTERS faz a condição cruzar com o contexto em vez de substituí-lo. Esses modificadores agem sobre o contexto de filtro, que é comum às duas funções, então o comportamento não muda de uma para a outra.
Quando devo criar uma tabela calculada com CALCULATETABLE em vez de usá-la numa medida? Crie tabela calculada quando você precisa de um objeto físico e estável no modelo, por exemplo uma tabela auxiliar de dimensão filtrada ou uma base de conferência. Use dentro de medida, como variável de tabela, quando o recorte depende do contexto do visual e muda a cada célula. Tabela calculada é fixa no refresh, medida é dinâmica no consumo.
CALCULATETABLE é mais lenta que CALCULATE?
Não por natureza. O custo vem do que você pede, não da função. Uma CALCULATETABLE que devolve poucas linhas de uma dimensão é barata. O que pesa é retornar tabelas fato enormes ou usar FILTER sobre elas. A regra de ouro é a mesma da CALCULATE: filtre dimensões, evite varrer a fato e mantenha o resultado enxuto.
Vale a pena refatorar medidas antigas para usar CALCULATETABLE? Vale quando a medida atual empilha filtros aninhados difíceis de ler, ou quando um iterador está percorrendo uma tabela maior do que precisa. Extrair a base para uma CALCULATETABLE numa variável costuma deixar a medida mais clara e, muitas vezes, mais rápida. Se o seu ambiente tem muitas medidas assim, um trabalho de sustentação de BI organiza isso de forma consistente em vez de peça a peça.
Fechando
A CALCULATETABLE não é uma função exótica: é a peça que faltava toda vez que a resposta é uma tabela, e não um número. Ela pensa igual à CALCULATE, aceita os mesmos filtros e modificadores, e muda apenas o que devolve. Domine a ideia de que ela reescreve o contexto e entrega o recorte que sobrou, use-a como tabela intermediária, como variável de tabela e como base para iteradores, e suas medidas ficam mais limpas e fáceis de manter.
Se a sua equipe tem medidas que ninguém entende, relatórios lentos ou cálculos que não fecham, esse costuma ser sintoma de modelagem que pede ajuste. Fale com a gente e a gente coloca seu Power BI em ordem, do modelo à medida.
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