Tempo de leitura:
As funções INDEX, OFFSET e WINDOW representam uma evolução importante na forma como escrevemos cálculos analíticos em DAX. Estas funções permitem navegar em tabelas ordenadas, identificar linhas por posição, comparar a linha atual com linhas anteriores ou seguintes e criar cálculos baseados em intervalos de linhas.
Em termos simples, estas funções ajudam-nos a responder a perguntas como:
- Qual é o primeiro produto no ranking de vendas?
- Qual foi o valor do mês anterior?
- Qual é a diferença entre a linha atual e a linha anterior?
- Qual é o acumulado até à linha atual?
- Qual é a média móvel dos últimos três períodos?
Antes destas funções, muitos cálculos em DAX exigiam combinações mais complexas de funções como FILTER, TOPN, RANKX, CALCULATE, ALL, EARLIER ou outras técnicas avançadas.
Por exemplo, comparar o valor de vendas de um produto com o produto anterior num ranking exigia normalmente criar uma lógica de ranking e depois procurar manualmente a posição anterior.
Função INDEX
A função INDEX devolve uma linha numa posição específica dentro de uma tabela ordenada. Podemos considerar que a função responde à pergunta: “qual é a linha na posição X?”
A sintaxe simplificada da função é:
INDEX (
posição,
tabela,
ORDERBY(…)
)
A função inclui ainda outros argumentos opcionais, onde o mais utilizado é o PARTITIONBY que permite dividir a tabela em grupos independentes.
Os seus argumentos principais são:
position
Define a posição da linha a devolver.
- 1 devolve a primeira linha.
- 2 devolve a segunda linha.
- -1 devolve a última linha.
- -2 devolve a penúltima linha.
relation
É a tabela ou expressão de tabela sobre a qual a função vai trabalhar.
orderBy
Define a ordem das linhas.
partitionBy
Permite dividir a tabela em grupos independentes.
Exemplo de aplicação
Vamos ver um exemplo, imaginando uma determinada medida já implementada no modelo.
Total de Vendas =
SUMX(
‘Transações’;
‘Transações'[Quantidade] * RELATED(Produtos[P. Unit.])
)
Vamos aceder à vista DAX Query para podermos testar a visualização de uma tabela, que é o resultado da função INDEX (a função INDEX devolve uma linha ou tabela).

E vamos criar uma tabela que mostra o total de vendas por cada produto.
EVALUATE
VAR ProdutosComVendas =
ADDCOLUMNS (
ALL ( Produtos[Produto] ),
“@TotalVendas”, [Total de Vendas]
)
RETURN
ProdutosComVendas

Imaginamos agora que pretendemos obter apenas 1 linha, e essa linha mostra o produto com a maior venda.
EVALUATE
VAR ProdutosComVendas =
ADDCOLUMNS (
ALL ( Produtos[Produto] ),
“@TotalVendas”, [Total de Vendas]
)
RETURN
SELECTCOLUMNS(
INDEX(
1,
ProdutosComVendas,
ORDERBY( [@TotalVendas], DESC)
),
“@Produto”, Produtos[Produto]
)

A tabela a ser utilizada pela função INDEX pode ser qualquer uma, e no exemplo seguinte vamos usar uma das tabelas do modelo e devolver toda a linha.
EVALUATE
INDEX(
-1,
Produtos,
ORDERBY( Produtos[P. Unit.], DESC)
)

Vamos ver agora a expressão com a opção partitionby, que permite obter por exemplo o produto com o preço unitário mais alto, agrupado por categoria.

Função OFFSET
A função OFFSET devolve uma linha antes ou depois da linha atual. Em linguagem simples: a função OFFSET responde à pergunta: “qual é a linha anterior ou seguinte?”
Os seus argumentos diretos são:
OFFSET (
delta ,
relação,
ORDERBY(…)
)
delta
Define quantas linhas queremos andar para trás ou para a frente.
- -1 devolve a linha anterior.
- 1 devolve a linha seguinte.
- -2 devolve duas linhas antes.
- 2 devolve duas linhas depois.
relation
Define a tabela sobre a qual queremos navegar.
orderBy
Define a ordem lógica das linhas.
partitionBy
Permite aplicar o deslocamento dentro de cada grupo
Exemplo da expressão
No exemplo vamos devolver o preço unitário do produto da “linha anterior”.
No cenário precisamos de uma tabela, e adicionar uma coluna, por isso vamos usar a função ADDCOLUMNS. Precisamos também de especifica a função SELECTCOLUMNS, uma vez que a função OFFSET devolve uma linha, e não conseguimos colocar uma linha inteira dentro de uma coluna.
EVALUATE
ADDCOLUMNS (
Produtos,
“P. Unit Anterior”,
SELECTCOLUMNS(
OFFSET (
– 1,
Produtos,
ORDERBY(Produtos[ID Produto])
),
Produtos[P. Unit.]
)
)

Neste exemplo, a função offset com a opção -1 devolve o produto imediatamente anterior, especificamente o preço unitário.
Devemos usar então a função OFFSET quando precisamos de obter uma linha numa posição relativa em vez de absoluta -> INDEX por exemplo para comparar a linha atual com uma linha anterior, ou próxima linha.
Exemplos:
- Vendas do mês anterior.
- Diferença face ao produto anterior no ranking.
- Valor do cliente seguinte.
- Crescimento face ao período anterior.
- Comparação linha a linha
Função WINDOW
A função WINDOW devolve várias linhas dentro de um intervalo definido, respondendo à pergunta: “qual é o conjunto de linhas entre o ponto A e o ponto B?”
A sua sintaxe simplificada é:
WINDOW (
início, tipo_início,
fim, tipo_fim,
tabela,
ORDERBY(…)
)
from
Define onde começa a janela.
from_type
Define se o início é absoluto ou relativo:
- ABS significa posição absoluta.
- REL significa posição relativa à linha atual.
to
Define onde acaba a janela.
to_type
Define se o fim é absoluto ou relativo.
Exemplo da expressão
No exemplo vamos ver como obter uma “janela” de linhas do inicio da tabela até à 5ª linha, ambas absolutas.
EVALUATE
WINDOW(
0, ABS,
5, ABS,
Produtos,
ORDERBY(Produtos[ID Produto])
)

O resultado devolve as 5 primeiras linhas da tabela Produtos.
Modificando o 2 argumento para relativo, obtemos uma “janela” de registos desde o início até 5 linhas “antes” da linha atual no contexto a ser avaliado.
Na query o contexto é a tabela inteira de produtos, por isso, em termos práticos estamos a dizer que estamos a obter todas as linhas, menos as 5 últimas…
EVALUATE
WINDOW(
0, ABS,
– 5, REL,
Produtos,
ORDERBY(Produtos[ID Produto])
)

Num cenário mais específico, vamos imaginar que pretendemos uma nova coluna na tabela, que mostra os últimos 5 produtos em relação à linha atual. Esta expressão vai usar várias funções:
- ADDCOLUMNS, para adicionar uma nova coluna na tabela.
- CONCATENATEX, para juntar texto.
- WINDOW, para mostrar uma “janela” de produtos.

No exemplo conseguimos analisar o produto da linha atual (0) e os últimos 5 produtos (-5) em relação à linha atual.
Exemplo prático de aplicação
Vamos agora ver um exemplo prático de aplicação.
Quando estamos a comparar períodos temporais, para criar acumulados, ou mesmo homólogos, usamos funções TIMEINTELLIGENCE. Mas estas funções são específicas para períodos temporais com datas.
Vamos imaginar que queremos criar um acumulado de vendas baseado em produtos. Mais especificamente criar um visual, que mostra um gráfico de “pareto”.
No exemplo temos o nosso modelo, com a medida [Total de Vendas] apresentada num gráfico e numa tabela. Os dados estão ordenados por vendas, do maior para o menor, para podermos verificar melhor a tendência dos valores e apresentar o formato “pareto”.

Pretendemos então criar uma medida que calcula o valor da venda atual, com a próxima, acumulando os valores.
No final iremos ter os valore em % para apresentarmos o “gráfico de pareto” com o crescimento.
Acumulado Pareto =
VAR MaiorVendaProduto =
WINDOW(
1; ABS;
0; REL;
ALL(Produtos);
ORDERBY([Total de Vendas]; DESC)
)
RETURN
CALCULATE(
[Total de Vendas];
MaiorVendaProduto
)

O resultado apresentado na tabela é o seguinte:
Agora para definirmos a linha do gráfico, criamos uma medida que junta a informação toda.
Linha Pareto =
VAR VendasAcumuladas =
CALCULATE(
[Total de Vendas];
WINDOW(
1; ABS;
0; REL;
ALL(Produtos);
ORDERBY([Total de Vendas]; DESC)
)
)
VAR TodasAsVendas =
CALCULATE(
[Total de Vendas];
ALL(Produtos)
)
VAR PctPareto =
DIVIDE(VendasAcumuladas; TodasAsVendas)
RETURN
PctPareto
Aplicando esta medida no gráfico, obtemos a linha acumulada em %, onde podemos também consultar os valores na tabela.

As funções INDEX, OFFSET e WINDOW tornam o código DAX mais expressivo e mais próximo da forma como muitos analistas pensam os seus cálculos: por posição, por linha anterior ou por intervalo.
Estas funções são especialmente úteis em cenários de ranking, comparação sequencial, análises temporais, médias móveis e acumulados como Pareto.
Embora muitas destas análises já fossem possíveis em DAX com combinações mais complexas de funções, INDEX, OFFSET e WINDOW permitem escrever fórmulas mais claras, mais legíveis e, muitas vezes, mais fáceis de manter.
Para quem trabalha com Power BI em contextos analíticos avançados, dominar estas três funções é um passo importante para criar medidas mais elegantes, comparações mais robustas e análises mais dinâmicas.
Próximo artigo:
Artigo Anterior:
Artigos por Categoria
- Microsoft Excel (47)
- Power Apps (16)
- Power Automate (3)
- Power BI (14)
- Power Query (15)
- Python (3)
- VBA (7)
Últimos Artigos
- Quando usar Folder.Files e Folder.Contents no Power Query
- Funções DAX para Análise Avançada: INDEX, OFFSET e WINDOW
- Funções REDUCE e SCAN no Excel: Entenda a Diferença
- Como Usar Parâmetros no Power BI para Relatórios Interativos
- Como usar o Copilot no Excel para criar fórmulas, resumos, gráficos e preparar impressão

Leave a Reply