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.
ÍNDICE:
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:
- O filtro mais externo à função é avaliado primeiro e aplica seu filtro ao contexto;
- Após, o interno é avaliado, aplica o seu filtro e o sobrepõe, prevalecendo o seu parâmetro.
- 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:
- As funções calculates são analisadas.
- A função ALL é identificada e por ter prioridade no engine do PBI, é executada primeiro.
- Como ela remove todos os contextos de filtros existentes, nesta medida, ela removeu os contextos de cor.
- Como na medida há outro contexto com a coluna Category filtrando pelo “AUDIO”, este permanece no contexto.
- 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:
- O filtro interno da calculate será o filtro válido para a medida quando aplicada ao contexto.
- A função Keepfilters deve vir junto do filtro mais INTERNO, do contrário, perde a valia.
- 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.
- Se todos os parâmetros forem diferentes, o resultado é blank.
- Independente da posição, a função ALL possui prioridade de execução; Cuidado.
- 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!