ERROS E BLANK – COMO TRATAR EM DAX
Ainda que DAX seja uma linguagem de análise de dados específica e pontual em produtos Microsoft, seguindo o padrão, ela possui formas de lidar com possíveis erros de execução de código em seu conjunto de funções.
Diferente da linguagem SQL, DAX possui maneiras mais intuitivas para o tratamento de erros dentro das expressões.
A maioria dos erros em DAX são baseadas em três situações distintas, mas que podem variar. São elas:
- Conversion errors.
- Arithmetic operation errors.
- Empty or missing values.
Então, no post de hoje, vamos avaliar como esses erros são gerenciados e como capturá-los para evitar falhas em cálculos de colunas e medidas.
ERROS EM CONVERSÃO DE VALORES
É o tipo de erro mais comum e acontece muito pelos usuários contarem com a conversão automática da linguagem.
Ainda que a conversão funcione bem e na grande maioria faça uma conversão correta, não é sempre que será confiável e isso pode levar a resultados errados.
O primeiro tipo de erro que veremos, seguindo a ordem acima, e que sua maior causa é pelo uso do conversor automático do PBI.
Em situações distintas o conversor pode funcionar perfeitamente, o que acaba gerando confiança e indução ao erro, por isso, é sempre bom prestar atenção ou converter explicitamente.
A princípio, utilizaremos três variáveis para testes.
Realizando uma operação básica de soma, podemos entender a ação do conversor automático. Veja que a variável num2 está num formato textual e ainda assim, realiza a soma resultando no valor correto.
Invertendo as ‘prioridades’ o engine interno do PBI também realiza o caminho inverso, quando operamos uma concatenação. Veja a imagem abaixo e adiantando: estas são as duas formas disponíveis para concatenar valores. Fórmula e o símbolo ” & “.
O caso abaixo envolvendo o que seria uma data, não é bem um erro, mas ocorre quando não especificamos de forma correta um determinado data type. Por exemplo, a variável DT está no formato texto, e quando executo uma operação de soma, volta como inteiro.
Veja que na mesma imagem, utilizei uma função para conversão explícita e o próprio PBI somou a variável (var1) ao dia da variável (DT), mudando para o dia 2 sem utilizar funções de adição de data.
E podemos dizer que o mesmo se aplica para concatenação com a variável convertida.
Esses são alguns cenários possíveis para erros de conversão que possam ocorrer quando deixamos a conversão automática agir. Tenha cuidado e sempre que possível, utilize funções de conversão ou os tipos que o PBI disponibiliza.
ERROS EM OPERAÇÕES ARITMÉTICAS
Os erros de operação aritmética ocorrem muito quando há uma tentativa de divisão por 0 ou por algum data type inválido, como vimos acima. Uma situação interessante é que na divisão por zero no PBI não há um erro em si, ele retorna duas categorias de valores: infinity ou NaN (not a number).
Na imagem podemos ver os dois comportamentos do PBI quando esse tipo de operação ocorre.
Um fato interessante ocorre nessa expressão, veja o resultado.
Essa situação ocorre pois o resultado que seria “infinity” OU “NAN” não são erros dentro do PBI, eles são valores especiais que a ferramenta assume, sendo assim, como essa expressão ao final dividiu 1/NaN, resultou em 0.
Para que o PBI retorne de fato um erro com operações aritméticas, ele precisa considerar algum parâmetro incorreto. Veja este exemplo.
Como o PBI não trabalha com números complexos, não temos solução para raiz quadrada de números negativos dentro da ferramenta.
Até o momento vimos alguns erros de conversão e cálculo e formas de evitar esse tipo de situação. Mas e quando temos um resultado inesperado, fruto de um cálculo, que retorna um resultado vazio? Como podemos gerenciar ou evitar esse tipo de situação?
Pensando nesse tipo de resultado, veremos como utilizar a função ISBLANK para valores vazios.
CAMPOS VAZIOS OU VALORES PERDIDOS
Diferente do que ocorre quando estamos trabalhando com SQL, que substitui valores inesperados por null, em DAX esse tipo de situação quando ocorre o campo simplesmente fica vazio.
DAX lida de uma forma mais genérica quando se trata de situações assim, colocando um ‘blank‘ naquele campo. Podemos utilizar a função blank para identificar ou substituir um valor por este.
No exemplo abaixo, ao contrário do esperado, que seria retornar ‘infinity‘ o PBI irá retornar como true o blank. Por mais que pareça estranho, o resultado da divisão por zero é considerado true!
O blank em si não possui a menor utilidade, apenas para expressões que não podem retornar erro ou qualquer outro valor indesejável.
Se quiser checar se uma expressão resultará em blank ou não, utilize a função isblank.
Nos exemplos abaixo temos dois testes para isblank, forçando uma variável retornar blank para teste; reparem que o primeiro teste corrobora com a divisão por zero.
Nem todas as operações com blank serão vazias ou falsas. Uso da condição lógica ” OU “, de soma e subtração, igualar a zero ou igualar a blank, o resultado costuma ser verdadeiro. Sempre teste antes para entender e confirmar o comportamento.
CAPTURANDO ERROS EM DAX
Agora que temos ciência de como os erros podem ocorrer quando estamos criando expressões dentro do PBI, temos de entender como podemos capturar esses erros e tratá-los de forma adequada.
Em algumas situações, como ocorre em SQL por exemplo, é possível criar mensagens definidas dentro de uma expressão para caso tenha um resultado inesperado.
Utilizando funções como IFERROR, ISERROR e até o próprio IF, é possível criar um tratamento adequado para o modelo.
No primeiro exemplo irei mostrar o comportamento de IFERROR, que funciona basicamente como um IF, porém voltado para soluções de problemas nos resultados.
Poderíamos colocar o 0 no lugar do blank, mas como o blank é o mais recomendado e considerado uma boa prática, decidi adotar este modelo.
“Tá ok, mas e se quiséssemos utilizar uma mensagem textual customizada?” Simples e possível, mas existem uns pequenos detalhes. Primeiro quero mostrar uma situação.
Quando utilizamos o IFERROR e uma expressão numérica qualquer, ele captura esse data type e não permite a utilização de uma mensagem de texto. Para solucionar essa situação, precisamos converter de forma explícita e contar com o conversor interno para realizar a operação numérica. Veja.
Agora, se estiver utilizando o IF, essa abordagem acima não irá funcionar. A conversão como feito acima não é possível.
Outra alternativa para mensagens de erro com a função IF é utilizando alguma função de erro em conjunto, como no novo exemplo onde utilizei ISERROR.
Neste exemplo forcei uma situação lógica falsa que conduzisse a função para a mensagem quando o resultado é falso.
E quando escolher entre utilizar IFERROR (ISERROR) ou IF.
A regra geral para o IFERROR é quando queremos resultados mais genéricos e constantes, não há interesse em, por exemplo, ter um novo cálculo caso uma determinada expressão falhe. E utilizamos IF quando queremos uma situação exatamente oposta ao IFERROR.
Independente de qual seja sua intenção, é preciso deixar claro que DAX não é otimizado para ter as funções IFERROR e ISERROR em cálculos complexos. O uso desse tipo de função pode apresentar uma queda significativa.
O mais indicado é utilizar o IF, que possui melhor performance. O problema é que a linguagem DAX não consegue criar bons planos de execução quando se depara com essas funções e piora ainda mais com funções aninhadas.
“Ok. Mas se utilizando IF não é possível utilizar mensagens de erro, como podemos contornar essa situação?”
Calma, não é que não seja possível, só não acontece pelo mesmo caminho feito com a função IFERROR. Para solucionar essa situação utilizando IF, precisamos da função ERROR.
Novamente forçando um teste lógico falso com BLANK para retornar a mensagem.
A única diferença é que a mensagem criada não é escrita na tabela, como no IFERROR. Pelo menos temos nossa mensagem de erro! 😉
CONCLUSÃO
Este foi um post que tentei abordar as nuances e particularidades da linguagem com conversão e possíveis erros em códigos!
Em alguns momentos faço um paralelo com SQL apenas para solidificar o aprendizado em questão.
Tenha cuidado com o conversor automático do PBI pois nem sempre ele age de forma correta e pode acabar convertendo de forma errada, como aconteceu com o formato data.
Sempre que possível, utilize IF e BLANK no seu código para capturar qualquer mensagem de erro, além de ser uma boa prática, há ganhos de desempenho do que utilizar uma função direta. Claro, isso varia da complexidade e do contexto que o código está sendo aplicaco!
Espero que gostem, saúde!