Olá pessoal, como estão?

No post de hoje gostaria de apresentar para vocês como a função calculate é executada dentro do PBI e qual a ordem de prioridade quando o engine tem que processar.

INÍCIO

Todas as funções em DAX são processadas da mais interna para a mais externa.

Se há uma função filtrando uma operação de sumx por exemplo, o filtro será processado primeiro.

Veja esta medida criada de exemplo:


Comparando com outra medida que calcula a mesma situação, porém sem filtrar valores, vemos um resultado diferente.

Essa ordem de “filtro primeiro” não tem valia quando trabalhamos com calculate.

A função ‘quebra’ esse paradigma, primeiro ela executa seu filtro para depois executar a expressão, seja medida ou uma expressão qualquer.

Além desta mudança, cada filtro dentro da calculate é executado de forma independente e a ordem dos filtros não são levadas em consideração.

Veja no exemplo das duas medidas que mesmo alterando a ordem dos filtros, o resultado continua igual.

Outro conceito importante que é aplicado aqui, diz respeito onde os filtros são executados. Bem sabemos que a calculate tem o ‘poder’ de manipular um filter context, assim sendo, todos os filtros que houverem dentro da função, serão processados externamente a ela, ou seja, pelo contexto e não pela execução interna da função.

No exemplo acima, a cor e a marca são ‘pesquisados’ após a conclusão da execução da função e são lançados para o contexto.

Um ponto que deve-se manter fixado é que o filtro mais externo da calculate será avaliado primeiro, em relação ao interno, porém, como o filtro interno é o último, ele quem prevalece no resultado final da função.

Esta situação é muito típica quando lidamos com expressões aninhadas. Veja abaixo que criarei uma medida com dois filtros de cores, mas repare no resultado.

Utilizando a medida anterior para comparar os resultados, removendo apenas o filtro da marca Contoso, perceba que a nova medida mostrou o mesmo resultado. Isso aconteceu pois, o filtro enquadrado em preto, por ser o mais interno, sobrepõe o externo, enquadrado em rosa.

NOTA: quanto mais interno for um filtro dentro de uma calculate, maior será sua prioridade no resultado.

Desse modo, tenham cuidado para não confundir, aqui vai um checklist do funcionamento:

  1. O filtro mais externo à função é avaliado primeiro e aplica seu filtro ao contexto;
  2. Após, o interno é avaliado, aplica o seu filtro e o sobrepõe, prevalecendo o seu parâmetro.
  3. Por fim, DAX executa a expressão desejada, retornando o resultado do último filtro.

Uma maneira de resolver essa situação, caso queira avaliar o resultado dos dois filtros seria desta forma.

Ainda sobre este exemplo, poderíamos utilizar o KEEP FILTERS na expressão, mas para isso, ele deve vir dentro do filtro mais interno. Outra situação que gostaria de mostrar é sobre a interseção dos filtros, veja:

O primeiro passo para entender essa expressão é que a função keep filters, quando em uma calculate aninhada, deve vir no filtro mais interno, visto que ele é o que sobrepõe os outros.

Como nossa medida está escrita para manter os filtros, há uma interseção entre os parâmetros, desse modo, é como se a medida filtrasse pelas cores: Vermelho, Verde e Preto. Porém, não é assim que o engine age.

Quando ele se depara com essa situação, o que é feito é uma interseção, mantendo no resultado final, apenas aquele parâmetro que aparece tanto no filtro externo quanto no interno; até adicionei uma medida filtrando apenas pela cor verde para provar o valor.

Agora, se voltar ao gráfico e à medida mrRedGreenSell, verá que há uma soma dos valores das duas cores, retornando aquele total no gráfico. Como ela não possui keepfilters, simplesmente houve a sobrescrita do filtro.

Nada o impede de adicionar mais filtros em suas calculates, desde que entenda sobre a ordem de execução e como manter ou sobrescrever um filtro. Veja abaixo que adicionei mais um filtro, desta vez, por categoria, apenas para mostrar o funcionamento.

Perceba que o filtro mais interno continua com keepfilters. Deste modo, no mais externo posso adicionar quais e quantos filtros quiser pois serão exibidos.

Uma última observação a respeito do uso de KEEPFILTERS vai para a quantidade de parâmetros de filtros. Se tanto o filtro externo quanto o interno possuírem apenas um valor de parâmetro, não há exibição de valor para esta medida; salvo se forem iguais

Veja no exemplo abaixo.

Por não ter interseção de filtros, como nos exemplos acima, não há valor para exibir. Além disso, como o filtro interno é o último a ser avaliado e é quem “define” o valor final na medida, temos o blank como resultado.

ORDEM DE AVALIAÇÃO: CALCULATE & ALL

Vimos na primeira sessão que ao aninharmos calculates o filtro interno irá ditar o resultado final no filter context, porém, isso nem sempre pode ser verdade; principalmente quando estamos trabalhando com a função ALL.

Veja esta medida que irá filtrar produtos pela cor “Preta” dentro de uma calculate. 

Até aqui, nada novo, apenas mostrando o resultado da medida. 


Criando uma nova medida e adicionando a função ALL, compare os resultados.

Vamos entender o que aconteceu:

  1. As funções calculates são analisadas.
  2. A função ALL é identificada e por ter prioridade no engine do PBI, é executada primeiro.
  3. Como ela remove todos os contextos de filtros existentes, nesta medida, ela removeu os contextos de cor. 
  4. Como na medida há outro contexto com a coluna Category filtrando pelo “AUDIO”, este permanece no contexto.
  5. Quando o PBI avalia o filtro interno, ele aplica a cor “PRETA” ao contexto.

O que este resultado final quer dizer é: “Total de vendas dos produtos da cor Preta que estão na categoria Audio”.

Tanto que ao compararmos as duas medidas, olhando o resultado, vemos que o que foi retornado na segunda medida foi apenas essa ‘pesquisa’.

Sabendo que a função ALL remove todo o contexto de filtro existente, a sua ordem em uma expressão fará toda a diferença no resultado final e mais, ela sempre será executada primeiro.

Nesta medida, a situação mudou um pouco em comparação ao que vimos no exemplo anterior.


A função ALL por ter prioridade na execução, eliminou o filtro pela cor, mantendo apenas a Categoria no contexto.

Adicionei a medida de vendas totais mrCalcSAmount apenas para corroborar que a toda a expressão para mrALLFirstEv teve seu resultado calculado apenas para a categoria “AUDIO”.

CONCLUSÃO

Neste post quis mostrar a ordem de execução da função calculate e quando temos um aninhamento destas.

Também abordei sobre a ordem de prioridade que cada filtro possui quando executado e quais soluções podemos utilizar quando lidamos com diversos filtros em uma medida.

Se formos conceituar o post em tópicos importantes, podemos entender que:

  1. O filtro interno da calculate será o filtro válido para a medida quando aplicada ao contexto.
  2. A função Keepfilters deve vir junto do filtro mais INTERNO, do contrário, perde a valia.
  3. Sempre que houver mais de um parâmetro de filtro, apenas aqueles que forem iguais, isto é, forem capazes de gerar uma interseção entre o externo e o interno, terão seus valores exibidos.
  4. Se todos os parâmetros forem diferentes, o resultado é blank.
  5. Independente da posição, a função ALL possui prioridade de execução; Cuidado.
  6. ALL irá eliminar quaisquer contextos que existam, impondo o dela.

Qualquer dúvida com a função ALL, veja estes posts(aqui, aqui, aqui) e nestes dois, seu funcionamento com keepfilters (aqui, aqui).

Espero que gostem do post, saúde.

Deus os abençoe!