Mostrando postagens com marcador DAX. Mostrar todas as postagens
Mostrando postagens com marcador DAX. Mostrar todas as postagens

segunda-feira, 13 de maio de 2019

SWITCH em DAX - Condição Única e Condição Múltipla

A função SWITCH pode ser útil para tratar múltiplas condições e regras de negócios que geram novas colunas calculadas.

Muitas vezes a função IF atende bem este cenário, mas a medida que muitas condições começam a ser aninhadas, a leitura fica prejudicada, deixando a fórmula extensa e suscetível a erros.

Exemplo usando IF para criara a regra de negócio que representa o tipo de cargo:

=IF([Salario]<=3000, “Junior”,
IF([Salario]>3000, “Pleno”,
IF([Salario]>5000, “Senior I”,
IF(AND([Salario]>8000,[Salario]<=10000), “Senior II”, "Outros"))))

Veja, que devemos respeitar o encadeamento.


Trabalhando com SWITCH

Existem basicamente duas formas de usar switch



1-Condição Única:


Estabelece uma expressão e avalia os possíveis resultados.

SWITCH(expression,
   value1, result1,
   value2, result2,
    :
    :
    else
   )

expression: retorna um valor escalar que são comparados nas constantes value1 com result1.

Exemplo:
=SWITCH([MonthNum],
    1,”January”,
    2,”February”,
    3,”March”,
    4,”April”,
    5,”May”,
    6,”June”,
    7,”July”,
    8,”August”,
    9,”September”,
    10,”October”,
    11,”November”,
    12,”December”,
    “Invalid Month Number”
   )

O problema desta implementação é que ficamos restritos a avaliação de igualdade de um único valor. Já na alternativa a seguir, vamos que podemos avaliar ranges de valores.


2-Condições Múltiplas

Estabelece o resultado da expressão como TRUE() e avalia as expressões em busca daquela que possui o valor verdadeiro.

SWITCH(TRUE(),
    booleanexpression1, result1,
    booleanexpression2, result2,
    :
    :
    else
   )


Retorna um valor para cada expressão que é avaliada como TRUE()

SWITCH(TRUE(),
             AND([salario]>=0, [salario]<=3000), “Junior”,
             AND([salario]>=3001, [salario]<=5000), “Pleno”,
             AND([salario]>=5001, [salario]<=8000), “Senior I”,
             AND([salario]>=8001, [salario]<=10000), “Senior II”,         
             “Outros”
           )

Desta maneira, cada resultado pode ter uma expressão complexa, que represente adequadamente a regra de negócio estabelecida.

Apesar de ser possível chegar ao mesmo resultado usando IF, a função SWITCH é bem mais fácil de ser construída e lida, sendo assim menos suscetível a erros e mais simples de ser debugada.

Fonte: https://powerpivotpro.com/2012/06/dax-making-the-case-for-switch/

segunda-feira, 6 de maio de 2019

Role-Play Dimensions em Modelos Tabulares

Em um modelo de dados, as dimensões dão significado às perspectivas pelas quais os dados serão filtrados e analisados, além disso elas facilitam a leitura e simplificam os modelos trazendo semântica e organização. Normalmente as dimensões são estruturas de dados que possuem um relacionamento de 1 para N com as tabelas de fatos, e se o modelo possui mais de uma tabela de fatos a mesma dimensão pode ser utilizada para ambas, criando assim uma visão compartilhada entre processos diferentes (representados pelas suas tabelas de fatos).

Alguns bons exemplos são dimensões de "Clientes" e "Datas": o cliente poderia estar relacionado com a tabela de fatos do processo de vendas e a tabela de fatos do processo de atendimentos de um SAC, e a dimensão de datas poderia estar relacionada com a data da venda e com a data do atendimento no SAC.

Dimensões que se relacionam com múltiplas tabelas de fatos são relativamente comuns em data warehouses maiores. Porém, existem situações nas quais uma dimensão têm mais de um relacionamento com a mesma tabela de fatos, como por exemplo as dimensões de datas. Uma tabela de vendas pode ter um fato com uma coluna para a data da venda, data do envio, data da entrega, etc. Um processo de atendimento no SAC pode ter data da ligação, data da solução do atendimento, data da resposta ao cliente. Em geral, são tabelas que possuem colunas que armazenam datas para cada fase de um processo.

Essas dimensões são chamadas de "Role-playing Dimensons". Vamos ver como implementar em modelos tabulares no analysis services.

O primeiro passo é garantir que exista um relacionamento N:1 para cada coluna de data na tabela de fatos.

DimDate => OrderDate (ativa)
DimDate => DueDate (inativa)
DimDate => ShipDate (inativa)
















Uma questão importante é que os modelos tabulares permitem que apenas um relacionamento esteja ativo por vez, isso garante que as funções DAX funcionem sem ambiguidade sem que seja necessário definir o relacionamento padrão.

Sempre que a tabela de fatos for filtrada pela dimensão de datas as medidas irão aplicar os filtros na coluna de data que estiver com o relacionamento ativo, no exemplo abaixo, não é necessário instruir a função DAX em qual relacionamento se propagar para filtrar as vendas por data, pois OrderDate está com relacionamento ativo.

SalesByOrderDate := SUM ( FactInternetSales[SalesAmount] )


Para fazer com que uma medida considere os relacionamentos inativos temos que explicitar isso utilizando a função USERELANTIONSHIP 


SalesByDueDate :=
CALCULATE (
    SUM ( FactInternetSales[SalesAmount] ),
    USERELATIONSHIP (
        FactInternetSales[DueDateKey],
        DimDate[DateKey]
    )
)


SalesByShipDate :=
CALCULATE (
    SUM ( FactInternetSales[SalesAmount] ),
    USERELATIONSHIP (
        FactInternetSales[ShipDateKey],
        DimDate[DateKey]
    )
)


A função USERELATIONSHIP recebe como argumento as chaves envolvidas no relacionamento. Com isso as medidas irão filtrar corretamente o contexto de datas sem que o filtro de uma data afete o filtro das outras.











Usando relacionamentos inativos em colunas calculadas:

Nos exemplos acima, estou descrevendo como ativar relacionamentos em medidas que usam o contexto de coluna, nos casos em que o contexto é de linha, como em colunas calculadas que usam RELATED para buscar um valor a partir dos relacionamentos, a implementação é diferente.

Não podemos usar CALCULATE em funções de contexto de linha pois o DAX altera automaticamente para contexto de coluna, temos que usar LOOKUP.

A função LOOKUP faz uma relação entre as chaves de data sem que exista uma relação fisicamente criada. É uma espécie de relacionamento virtual.

* onde [DueDateKey]  foi igual a [DateKey] retorna o nome do dia da semana.

FactInternetSales[DayDue] =
LOOKUPVALUE (
    DimDate[EnglishDayNameOfWeek],
    DimDate[DateKey],
    FactInternetSales[DueDateKey]
)


Desta forma nós contornamos a necessidade de usar a função CALCULATE para ativar uma relação inativa e fazer o uso correto da função RELATED.


















Fontes:
https://www.sqlbi.com/articles/userelationship-in-calculated-columns/
https://www.youtube.com/watch?v=2BxaUXlx3K4

quinta-feira, 28 de março de 2019

Dimensão com Hierarquia Auto-referenciada - Parent-Child

Uma dimensão do tipo parent-child implementa o conceito auto-referenciamento de uma árvore desbalanceada, ou seja, possui ramos com tamanhos diferentes dependendo da profundidade de cada encadeamento.

Este tipo de dimensão pode aparecer em projetos que trabalham com listas de materiais que possuem subcomponentes, em sistemas corporativos que organizam os recursos humanos em estrutura organizacionais, em contas contábeis, etc..

Os projetos criados com o modelo tradicional do analysis services multidimensional (MDX) já possuem uma configuração nativa para tratar este tipo de dimensão, basta configurar corretamente as propriedades para que funcione.

Configuração das propriedades da dimensão





























Visualizando a dimensão
















Porém, com modelos tabulares criados com DAX esse suporte nativo não existe. Para obter uma hierarquia navegável no modelo de dados, você precisa decompor os níveis até um determinado ponto para obter uma hierarquia pai-filho.

Para isso o DAX fornece funções específicas para trabalhar com uma hierarquia pai-filho usando colunas calculadas.

Hierarquias Pai-Filho em DAX


A hierarquia é implementada utilizando as funções do grupo PATH.

PATH

PATHCONTAINS

PATHITEM

PATHITEMREVERSE

PATHLENGTH


Dados de Exemplo: Este exemplo será feito com base nesta tabela, onde o código da coluna gerente é o código pai.
















1-Identificar o caminho completo: 

Utiliza a coluna Gerente para referenciar todas as relações e retornar uma string com o caminho completo com todos os níveis superiores.



















Neste exemplo, existe uma coluna com a hierarquia já criada, em algumas fontes de dados isso pode existir, se esse for o caso, o primeiro passo pode ser substituído por esta função.


















2-Descobrindo o tamanho do caminho: 

Utilizar a função PATHLENGTH para identificar o tamanho. Esse valor será útil para identificar quantos níveis devem ser criados.


















3-Criando os níveis:

Nível 1: Utilizar PARENTITEM para localizar o código do nivel 1 e fornecer o parâmetro para LOOKUPVALUE localizar o nome do profissional.

























Nível 2: A partir do nível 2 é necessário fazer uma verificação no tamanho.






























O processo se repete para quantos níveis forem necessários.

O resultado final pode ser observado em um filtro ou em uma matrix.





Fonte:
https://docs.microsoft.com/en-us/dax/parent-and-child-functions- dax
https://www.daxpatterns.com/parent-child-hierarchies/
https://docs.microsoft.com/en-us/dax/understanding-functions- for-parent-child- hierarchies-in-dax
https://www.youtube.com/watch?v=QFKTr8tAQXE&list=PLWfPHxJoa7zthSaAMlt0JkJpFeVtdHzq6&index=42



quarta-feira, 20 de março de 2019

Datas Relativas Usando Power BI Filter Visual, DAX e JavaScript

Um requisito frequente em painéis criados com Power BI é a definição de um filtro padrão para a data atual ou ano atual. Quando um painel é renderizado, ele apresenta os filtros que foram salvos por último e estes são sempre estáticos (não são alterados de forma relativa).

Para que não seja necessário re-filtrar o painel sempre que ele é carregado e para que a data seja atualizada sem intervenção manual, temos algumas alternativas para implementar um filtro padrão com datas relativas.

1-Utilizando a configuração do visual de filtros do Power BI

Quando um campo do tipo data é utilizado como filtro o Power BI, a configuração abaixo é apresentada como opção para definir datas relativas (relativas a data atual).

Clique no menu e selecione a opção relative.


















Será apresentada uma lista de opções para configuração do tipo de intervalo que será usado.

Para selecionar o ano atual escolha a opção "This". Irá por padrão manter o filtro do ano atual com base na data de hoje. No dia 01/01/2020 o filtro será alterado para o ano novo, sem que tenha que ser atualizado manualmente.
















Existe diferentes combinações de datas relativas, para períodos maiores é possível usar a opção "Last". Neste exemplo serão filtrados como padrão os últimos 5 anos com base na data de hoje 20/03/2019.






















2-Criando uma nova coluna no modelo de dados


Outra alternativa interessante é a de criar uma nova coluna utilizando DAX para identificar o ano atual. Este método é interessante pois permite que o filtro seja utilizando de forma implícita, sem que tenha que obrigatoriamente criar um visual do tipo filtro na tela do painel.

Último Ano = IF('Calendar'[Year]= MAX('Calendar'[Year]);"Último Ano";FORMAT('Calendar'[Date]; "YYYY"))

Na função acima, se o ano da linha atual for igual ao maior ano, ou seja, o ano mais recente, então defina como "Último Ano", senão, apresenta a data em um formato de ano.

Agora basta manter o filtro "Ultimo Ano" selecionado. Seja no próprio painel com um filtro ou seja internamente como filtro de pagina.



3-Usando JavaScript


Usando um custom visual chamado Power Slicer https://appsource.microsoft.com/en-us/product/power-bi-visuals/WA104382000 é possivel implementar também com funções javascript.

Este custom visual permite um maior controle sob as customizações do visual de um slice. Além disso possui recurso configuração valores padrão utilizando funções JavaScritp.

Crie um filtro com o Ano e informe na propriedade "Default Value" a função: (new Date().getFullYear()-5)

Essa função irá retornar o ano de 2019 e será decrementado por 5, resultando no ano de 2014.

Sempre que o painel for carregado, será filtrado de acordo como resultado da função javascript.













Definir filtro padrão baseado em uma data relativa, nos garante que os painéis não irão carregar dados desnecessários nos casos onde as análises são feitas predominantemente com base no ano atual. Estes métodos de se obter períodos relativos podem ser aplicadas dependendo da necessidade de cada cenário.


Vídeo:


terça-feira, 19 de março de 2019

Calcular Corretamente Idade em DAX

A princípio uma forma intuitiva para se fazer um cálculo de idade seria utilizar a função DateDiff para verificar a diferença entre a data atual e data de nascimento e fazer a divisão por 365.

Idade = DIVIDE(DATEDIFF(TODAY();Planilha1[Data];DAY);365)














Porém o resultado desta função é incorreto, neste exemplo a data de aniversário para completar 34 anos ainda não ocorreu e a função está marcando 34.

A forma correta de obter estes resultados, utiliza a função YEARFRAC.

 YEARFRAC  = Calcula a fração do ano representada pelo número de dias inteiros entre duas datas.

INT faz o arredondamento.









Funções para cálculo de idade que levam em consideração a fração do ano:

Idade Fracionada = YEARFRAC (Planilha1[Data]; Planilha1[Hoje] )

Idade Arredondada = INT(YEARFRAC (Planilha1[Data]; Planilha1[Hoje] ) )


Fonte:
https://www.sqlbi.com/blog/marco/2018/06/24/correct-calculate-of-age-in-dax-from-birthday/
https://docs.microsoft.com/en-us/dax/yearfrac-function-dax


quarta-feira, 13 de março de 2019

Curva ABC Segmentação Dinâmica com Power BI - DAX

A segmentação ABC apresentada no post anterior cria uma coluna calculada para representar o resultado da classe, o que permite a utilização dessa coluna como filtro ou como campo para apresentar em elementos gráficos. Esse é o lado bom, mas, uma coluna calculada precisa ser "calculada" em tempo de processamento do modelo e não em tempo de execução, a medida que o painel é filtrado. O problema relacionado a este padrão de implementação é o fato dele ser estático e não atualizar conforme os painéis são manipulados. Para desenvolver uma métrica dinâmica que respeite os filtros, necessariamente temos que criar medidas.

Vamos a um exemplo de como implementar a classificação ABC através de medidas.

1-Criar uma medida de RANK

Essa medida será usada para identificar os produtos que possuem valores maiores do que o produto atual.









2-Criar o acumulado das vendas até o Rank do produto atual

* para cada produto, a engine do dax cria uma tabela temporária em memória com todos os produtos com melhor rank e faz a agregação.


















3-Total geral dos produtos selecionados

Para identificar a proporção do percentual do total do valor agregado e obter a métrica para gerar a classificação ABC.










É importante dizer que a função ALLSELECT() garante que o filtro do contexto explicito do painel é considerado e a medida irá ser calculada considerando os filtros realizados pelo usuário.


4-Dividir o acumulado atual com o total geral de produtos para obter o percentual do total







5-Definir a classe com base no percentual




















Também é possível obter o mesmo resultado utilizando a função TOPN para obter o acumulado e extrair a classificação dele.












Essa medida cria uma tabela temporário com os produtos TOPN até o Rank atual do produto. Exemplo: se o rank do produto é 10 a função irá retornar uma tabela com os 10 primeiros que será usada pela CALCULATE para fazer a agregação.



Como o resultado das Classes é obtido por uma medida, podemos usar em uma matrix como no exemplo abaixo..



































Mas a princípio não é possível usar a medida em um gráfico. Uma alternativa interessante para apresentar um quantitativo agregado seria usar cards.

Para apresentar em cards temos que criar 3 novas medidas, uma para cada classe



Resultado Final






Vídeo:




Curva ABC Segmentação Estática com Power BI - DAX

Análise de curva ABC é um tipo de padrão de segmentação que leva em consideração a classificação de um item (produto, cliente, etc) por categorias (A, B, C) com base no acumulado dos totais dos maiores valores para os menores.

É uma forma de identificar o princípio de Pareto, que considera que os itens com maiores resultados são poucos, mas impactam significativamente no resultado.

Os itens da classe A teoricamente são os mais importantes para o negócio. O valor deles deve ser avaliado com mais frequência, enquanto os itens da classe C são menos importantes e os itens da classe B são opcionais.


Cenários de utilização



Segmentação de clientes: separar os clientes por categorias para auxiliar a alocação de recursos de marketing.

Gerenciamento de ativos: gerenciar os estoques, aumentar a disponibilidade de estoque e negociar preços melhores para produtos na classe A, reduzindo o tempo e os recursos para itens nas classes B.

Este padrão de implementação é estático, isso significa que a classificação ABC é definida para um item em tempo de processamento do modelo e não em tempo de execução, como ocorre com as medidas. Isso ocorre porque a implementação é feita com colunas calculadas, e colunas calculadas são previamente armazenadas no modelo.

Etapas para implementação.


1-Criar uma coluna calculada na tabela de produtos com as vendas acumuladas por produto.

Essa primeira coluna faz a agregação do acumulado dos totais de vendas de produto, levando em consideração apenas os valores superiores ao valor da linha atual.































As vendas são acumuladas do maior para o menor valor.




2-Criar uma coluna calculada na tabela produto, com a venda total geral











É necessário usar a função ALL() para garantir que não haverá a transição de contexto e o total retornado irá ignorar o filtro de produto.



3- Gerar o percentual do acumulado.



















Essa métrica será usada como parâmetro para definir a classe.




4-Definindo a classificação ABC

































Opções de visualização:

Os produtos estão ordenados pelos totais de vendas e as classes estão respeitando o acumulado de até 80% para classe A até 90% para classe B.






Outra forma de apresentar os resultados, pode ser o gráfico de linhas e colunas, que configurado de forma decrescente do acumulado evidencia a suavização da curva.





















Vídeo:



Fontes:
Power BI & DAX Avançado - Guia Completo: https://www.udemy.com/share/1002h2B0QfeF1QRw==/

https://www.daxpatterns.com/abc-classification/

https://exceleratorbi.com.au/cumulative-running-total-based-on- highest-value/

https://community.powerbi.com/t5/Quick-Measures- Gallery/Dynamic-ABC- Classification/m-p/479146#M180

Formatação condicional baseada em expressões DAX

Na época que o report server era a principal ferramenta de relatórios/painéis da Microsoft, uma das características que eu mais gostava era a possibilidade de criar expressões em quase tudo que era renderizado na tela. Isso dava uma grande flexibilidade e permitia usar a criatividade para os mais diversos requisitos dos clientes. Com o surgimento do Power BI alguns visuais passaram a ficar bem mais "engessados". Mas em releases recentes vem surgindo opções interessantes de formatações condicionais que trazem de volta certo grau de customização nos visuais. 

A partir da evolução dos recursos de formatação condicional em visuais de tabelas do Power BI tornou-se possível fazer formatações condicionais utilizando os resultados obtidos por expressões implementadas por medidas.

Vamos a um exemplo de aplicação destes recursos: Criar uma formatação condicional em colunas de uma tabela com base na lógica de uma medida. 

Formatar apenas os maiores e menores resultados. 

 1-Dados de exemplo: Lista de clientes e valores de receita. Bem simples para facilitar a visualização.




2-Criar uma medida de RANK para usar na lógica da formatação condicional. Essa será a medida que será avaliada.










3-Criar nova medida para definir a cor que será usada para a formatação condicional. 

A função SWITCH avalia as condições na sequência.










Neste momento você pode ser implementar a lógica da formatação condicional específica para sua necessidade de acordo com a medida que será monitorada. Neste exemplo é o rank, mas poderia ser qualquer outra medida. 

* o resultado precisa ser o nome de uma cor. 

Com a medida pronta, acesse as propriedades da tabela.














4-Configurar com base na medida. 

Selecionar a opção "Field Value" e a medida criada. 



















O resultado, 


































* Esse processo pode ser repetido para definir a formatação condicional também da fonte do texto da célula, de forma que contraste melhor com as cores do background. 


5-Formatar TOPN
Uma variação do nosso exemplo poderia ser destacar o TOP3 clientes.

Este exemplo está destacando apenas o 3 primeiros e os 3 últimos. 










































Mas ainda assim estamos fixando o valor dos últimos clientes. Caso a lista de cliente aumente essa medida não ira atender nosso requisito. 

Para resolver isso podemos usar uma variável e alterar a nossa medida.

















































Fonte: http://radacad.com/dax-and-conditional-formatting-better-together-find-the-biggest-and-smallest-numbers-in-the-column


Video