Melhores Práticas – Include

Fala pessoal! Tudo bom?

Voltando ao assunto de Melhores Práticas, quero falar sobre o Include!

Quando estamos em um cliente, ou em nossa empresa, em que o ambiente de QlikView seja pequeno não percebemos a importância do Include (Mas o que é isso? Calma! rsrs). Houve uma mudança na estrutura de diretórios do ambiente? Entro no QVW do meu projeto e altero a variável de caminho (Espero que você tenha esse costume de colocar variáveis com os caminhos dos arquivos 😀 !)

Como citei anteriormente, se o meu ambiente é pequeno, com poucos qvws, entro em cada um deles e altero, mas e se meu ambiente esta grande? Vou perder algumas belas horas para alterar tudo!

Continuar lendo

Anúncios

IntervalMatch Estendido na Prática

Fala pessoal, tudo bom?
 
Semana passada abordamos o tema de intervalos e descobrimos que o QlikView possui uma função própria para se tratar desses casos. Não viu? Clique aqui!

   

Definições do IntervalMatch

Também quero aproveitar para relembrar algumas definições do IntervalMatch:

  • Antes do comando intervalmatch, o campo que contém os pontos de dados discretos (“Nota” no exemplo do post anterior) já deve ter sido lido no QlikView. O próprio comando intervalmatch não lê esse campo a partir da tabela da base de dados.
  • A tabela lida no comando intervalmatch deve sempre conter exatamente dois campos (“Min” e “Max” no exemplo do post anterior). Para estabelecer um link com outros campos, é necessário ler os campos de intervalo com campos adicionais em um comando load ou select separado.
  • Os intervalos estão sempre fechados, isto é, sempre contêm pontos de extremidade.
  • Os limites não numéricos fazem com que o intervalo seja desconsiderado (indefinido)
  • Os limites nulos (NULL) estendem o intervalo indefinidamente (ilimitado).
  • Os intervalos podem estar sobrepostos, ou seja, posso ter dois intervalos que contenham valores repetidos, esses valores estarão vinculados a todos os intervalos correspondentes.

   

Caso a utilizar IntervalMatch Estendido

Essa semana iremos tratar de um intervalo que não depende simplesmente do intervalo de valores, mas também depende de um segundo campo que define a qual intervalo estamos tratando. Podemos chamar esse segundo intervalo de campo chave.

  

Resgatando o exemplo da semana passada em que tínhamos uma tabela com a classificação das notas e outra com as notas recebidas por cada aluno, vamos adicionar uma nova coluna com o nome da escola. Imagine que o nosso professor ministre aulas em duas escolas diferentes e cada uma dessas escolas possuem a sua própria classificação das notas.

  

Na escola Puríssimo a classificação é:

  • de 0 até 34 é Nota “E”
  • de 35 até 40 é Nota “D”
  • de 41 até 60 é Nota “C”
  • de 61 até 80 é Nota “B”
  • de 81 até 100 é Nota “A”

  

Na escola Sesi a classificação é:

  • de 0 até 15 é Nota “E”
  • de 16 até 40 é Nota “D”
  • de 41 até 60 é Nota “C”
  • de 61 até 70 é Nota “B”
  • de 71 até 100 é Nota “A”

  

Como temos classificações diferentes em duas escolas (CHAVE) diferente, então a nossa tabela de notas deve possuir a qual escola (CHAVE) aquela nota (do aluno) pertence.

   

Prática

Em primeiro lugar crie a nossa tabela com os intervalos.

  

Grade:
LOAD * INLINE [
Escola, Min, Max, Grade
Escola Puríssimo, 0, 34, E
Escola Puríssimo, 35, 40, D
Escola Puríssimo, 41, 60, C
Escola Puríssimo, 61, 80, B
Escola Puríssimo, 81, 100, A
Escola Sesi, 0, 15, E
Escola Sesi, 16, 40, D
Escola Sesi, 41, 60, C
Escola Sesi, 61, 70, B
Escola Sesi, 71, 100, A
];

  

Agora vamos criar a nossa tabela das notas por escola e aluno.

Notas:
LOAD * INLINE [
Escola, Nota, Aluno
Escola Puríssimo, 30, Yuri
Escola Puríssimo, 50, Edson
Escola Puríssimo, 99, Alan
Escola Puríssimo, 10, Geraldo
Escola Puríssimo, 93, Henrique
Escola Sesi, 27, Christian
Escola Sesi, 44, Michele
Escola Sesi, 80, Roberto
Escola Sesi, 76, Ivanir
Escola Sesi, 98, Zé
];

  

Note: A coluna “Escola” é a chave que define a nota e a classificação, sem ela não saberíamos informar a classificação da nota desse aluno, pois agora temos dois intervalos diferentes na mesma tabela.

  

Agora vamos para a utilização do IntervalMatch Estendido

A utilização do IntervalMatch Estendido deve-se partir da leitura da tabela de intervalos e o comando IntervalMatch deve-se relacionar com a coluna que deve ser checada dentro do intervalo e a coluna de chave:

Usando_IntervalMatch_Estendido:
IntervalMatch(Nota,Escola) //Comando IntervalMatch chamando a coluna a ser checada dentro do Intervalo e a chave para definir a qual intervalo o valor se refere.

Usando_IntervalMatch_Estendido:
IntervalMatch(Nota,Escola)  //Comando IntervalMatch chamando a coluna a ser checada dentro do Intervalo e a coluna de //chave das classificações
LOAD
Min, //Primeiro o menor valor do intervalo
Max, //depois o maior valor do intervalo
Escola //Por último a coluna chave.
RESIDENT Grade; //Tabela de Intervalos

  

Com o resultado agora teremos a tabela “Usando_IntervalMatch_Estendido” que possui as colunas: Min, Max, Nota e Escola. Essa tabela já fez a ligação entre as tabelas Nota e Grade, veja:

  

IntervalMatch Estendido 01

  

Agora é só fazer o JOIN necessário para remover essa chave sintética. Remova a parte do IntervalMatch e faça a alteração abaixo:

  

LEFT JOIN (Notas)

IntervalMatch(Nota,Escola) //Comando IntervalMatch chamando a coluna a ser checada dentro do Intervalo e a coluna de chave das classificações
LOAD
Min, //Primeiro o menor valor do intervalo
Max, //depois o maior valor do intervalo
Escola //Por último a coluna chave.
RESIDENT Grade; //Tabela de Intervalos

LEFT JOIN (Notas)

LOAD
*
RESIDENT Grade;

DROP TABLE Grade;
DROP Fields Min, Max;

   

Resultado final

IntervalMatch Estendido 02
Download da aplicação de exemplo!

   

Conclusão

Esse é um caso que mais ocorre em nosso dia a dia em relação ao caso do post anterior, pois dificilmente teremos apenas um intervalo de dados para checar.

E reforço o texto utilizado no post anterior: É uma boa prática conhecermos muitas das funções que o QlikView nos oferece, pois estas funções sempre irão nos poupar linhas e linhas de código.

  

Até a próxima semana pessoal!

IntervalMatch na prática

Fala galera, tudo bom?

Já se depararam com uma situação em que era necessário fazer um JOIN entre tabelas, porém esse JOIN não é o valor exato da segunda tabela e sim um valor que esta dentro de um intervalo dela?

Por exemplo:

Tenho uma tabela com os limites das notas de uma escolha

  • de 0 até 34 é Nota “E”
  • de 35 até 40 é Nota “D”
  • de 41 até 60 é Nota “C”
  • de 61 até 80 é Nota “B”
  • de 81 até 100 é Nota “A”

A nossa segunda tabela possui as notas dos alunos.

Nem sempre teremos uma nota com o valor dos limites do intervalo e isso impossibilita de resolvermos essa situação utilizando um comando de JOIN.

Podemos criar os registros que estão faltando no intervalo e depois é só fazer Join? Sim, para esse exemplo pode até funcionar, pois no total teremos 100 registros, mas e se a nossa tabela de “Range” possuir intervalos de milhares? milhões? Acho que para esses casos não seria uma boa solução, concordam?
   

IntervalMatch

O prefixo IntervalMatch é usado para criar uma tabela comparando valores numéricos discretos com um ou mais intervalos numéricos.
Ele deve ser colocado antes do Load ou declaração de Select (SQL) que carrega os intervalos. O campo que contém os pontos de dados discretos (Notas no exemplo abaixo) já deve ter sido carregado no QlikView antes do comando com o prefixo IntervalMatch. O prefixo não lê esse campo a partir da tabela da base de dados. O prefixo transforma a tabela carregada de intervalos em uma tabela que contém uma coluna adicional: os pontos de dados numéricos discretos Ele também expande o número de registros de forma que a nova tabela tenha um registro por combinação possível de ponto de dados discreto e intervalo.
Os intervalos podem estar sobrepostos e os valores discretos estarão vinculados a todos os intervalos
correspondentes.
   

Prática

Em primeiro lugar crie a nossa tabela com os intervalos.

Grade_Notas:
LOAD * INLINE [
Min, Max, Grade
0, 34, E
35, 40, D
41, 60, C
61, 80, B
81, 100, A
];

Agora vamos criar a nossa tabela das notas por aluno

Notas:
LOAD * INLINE [
Nota, Aluno
30, Yuri
50, Edson
99, Alan
10, Geraldo
93, Henrique
];

Agora vamos para a utilização do IntervalMatch

A utilização do IntervalMatch deve-se partir da leitura da tabela de intervalos e o comando IntervalMatch deve-se relacionar com a coluna que deve ser checada dentro do intervalo:

Usando_IntervalMatch:
IntervalMatch(Nota) //Comando IntervalMatch chamando a coluna a ser checada dentro do Intervalo
LOAD
Min, //Primeiro o menor valor do intervalo
Max //depois o maior valor do intervalo
RESIDENT Grade; //Tabela de Intervalos

Como resultado agora teremos a tabela “Usando_IntervalMatch” que possui as colunas: Min, Max e Nota. Essa tabela já fez a ligação entre as tabelas Nota e Grade, veja:

IntervalMatch 01

Agora é só fazer o JOIN necessário para remover essa chave sintética. Remova a parte do IntervalMatch e faça a alteração abaixo:

LEFT JOIN (Notas)

IntervalMatch(Nota) //Comando IntervalMatch chamando a coluna a ser checada dentro do Intervalo
LOAD
Min, //Primeiro o menor valor do intervalo
Max //depois o maior valor do intervalo
RESIDENT Grade; //Tabela de Intervalos

LEFT JOIN (Notas)

LOAD
*
RESIDENT Grade;

DROP TABLE Grade;
DROP Fields Min, Max;
   

Resultado final

IntervalMatch 02
A aplicação de exemplo pode ser baixada aqui!
   

Conclusão

É uma boa prática conhecermos muitas das funções que o QlikView nos oferece, pois estas funções sempre irão nos poupar linhas e linhas de código. A utilização do IntervalMatch também é o melhor recurso para essa situação, garantindo o resultado esperando com uma ótima performance na recarga do script.

Na próxima semana irei demonstrar como utilizar o IntervalMatch Estendido 😀

Até a próxima semana!

Relatório AD-HOC

Fala pessoal, tudo beleza?

Na semana passada não foi possível fazer um post devido ao feriado de pascoa, mas voltamos agora com tudo 🙂

   

Afinal, o que é e como construir um relatório ad-hoc?

 

Em primeiro lugar precisamos entender o termo ad-hoc.
 
Sempre que utilizamos o termo ad-hoc, estamos se referindo a algo temporário e que se destina para um fim específico.
 
Neste tipo de relatório, geralmente, construímos um tabelão em que o usuário seleciona as dimensões e expressões que necessitam visualizar. Engraçado é a palavra temporário, pois se tratando de uma ferramenta super poderosa um simples tabelão não pode ser vinculado ao BI de uma grande corporação.
 
Opinião: Sabemos que isso não é verdade. O layout é importante? Muito, mas o objetivo principal é conseguir atender as necessidades do cliente da melhor maneira possível. Se para atender essa necessidade eu preciso desenvolver apenas tabelas, então bora :D!

  

Como falado anteriormente, podemos desenvolver o relatório ad-hoc apenas dentro de um tabelão ou então fazer o próprio usuário escolher o tipo de gráfico. Para esse primeiro post do assunto, irei demonstrar apenas a funcionalidade do usuário selecionar as dimensões e expressões que pretende visualizar dentro de um tabelão.

  

Em primeiro lugar precisamos criar um campo com as possíveis dimensões e outro com as expressões.

IMPORTANTE: A nomenclatura desse campo deve respeitar o prefixo utilizado na função HidePrefix, pois estes campos não deverão estar disponíveis para nossos usuários desenvolvedores (com licença named).

   

Vamos para o script!

  

1° Passo) Crie uma aba chamada AD-HOC e crie os campos (no meu exemplo vou utilizar INLINE, mas você pode ficar livre para colocar esses campos em planilha ou dentro de uma tabela em seu BD).

OBS: O conteúdo dentro do campo de dimensão e/ou expressão não necessariamente precisam possuir o mesmo nome da dimensão que será utilizada na tabela.

 

SET HidePrefix = ‘_’;

 

//Tabela com os campos de dimensões

Dimensões:
LOAD * INLINE [
_dimensao
Dimensão1
Dimensão2
Dimensão3
Dimensão4
Dimensão5
Dimensão6
Dimensão7
Dimensão8
];

 

//Tabela com expressões

Expressões:
LOAD * INLINE [
_expressao
Expressão1
Expressão2
];

  

2° Passo) Agora precisamos criar um gráfico do tipo Tabela Simples ou Tabela Dinâmica.

  

3° Passo) Após selecionar o tipo de gráfico, adicione a seguinte condição de cálculo, conforme imagem:

01 - Condição de Cálculo

Condição a ser preenchida: GetSelectedCount(_dimensao) > 0 and GetSelectedCount(_expressao) > 0

Traduzindo a expressão: Serão exibidos os dados do gráfico somente se houver, pelo menos, uma dimensão e uma expressão.

  

4° Passo) Agora precisamos adicionar as dimensões do gráfico. Note que essas dimensões não são as criadas na tabela Dimensões no primeiro passo.

Após adicionar cada uma dessas dimensões, devemos habilitar a condição “Permitir Condicional” e colocar a condição conforme a imagem abaixo:

 

02 - Condição da Dimensão

Condição a ser preenchida: SubStringCount(CONCAT(‘|’&_dimensao,’|’) & ‘|’, ‘|Dimensão1|’)

Traduzindo a expressão: Estou concatenando todos os possíveis valores do campo _dimensao e estou procurando pela string |Dimensão1|, ou seja, se o usuário selecionou o valor Dimensão1, então este campo será exibido em nosso relatório. Por que estou utilizando o pipe “|” para concatenar e para buscar a string? Pois se houver um campo Dimensão1 e um Dimensão11, então o delimitador pipe irá diferencia-lo na busca.
  

5° Passo) É necessário fazer essa ação para cada dimensão que o usuário pode selecionar.

  

6° Passo) Para as expressões deve-se habilitar o checkbox “Condicional” e fazer o mesmo, porém agora utilizando o campo _expressao na condicional, conforme imagem:

03 - Condição da Expressão

Condição a ser preenchida: SubStringCount(CONCAT(‘|’&_expressao,’|’) & ‘|’, ‘|Expressão1|’)

  

7° Passo) Disponibilizar para seleção os campos _dimensao e _expressao.

  

8° Passo) Perfumarias! 😀

  

Para fazer o download da aplicação de exemplo clique aqui.

   

Conclusão: Eu gosto muito de colocar um relatório desse tipo nos projetos, pois o usuário fica com a liberdade de criar um gráfico de acordo com o seu desejo (dentro das dimensões e expressões pré-estabelecidas).

O cuidado que precisamos ter é limitar a quantidade de dados a serem exibidos se possibilitarmos a visualização de informações de baixo nível.

  

É isso pessoal!

Na próxima semana tem mais 🙂

Melhores Práticas – ApplyMap

Fala pessoal, tudo bom?

 

Quero continuar comentando sobre melhores práticas para QlikView e neste capítulo vou falar um pouco sobre a função Applymap.

 

A função Applymap é nada mais, nada menos do que um De-Para, ou seja, substitui um valor por outro através de uma tabela de mapeamento.

Por que um de-para pode ser considerado uma melhor prática de desenvolvimento? Pois essa função, na maioria dos casos, pode ser utilizada para substituir a função JOIN com uma performance MUITO MAIOR. Lembrando que estamos falando no desempenho da execução de carga.
 
 
 

Explicação para utilização

  • Deve-se declarar uma tabela de mapeamento através da função Mapping;
  • A tabela de mapeamento deve conter apenas duas colunas;
  • A primeira coluna é sempre o De e segunda coluna sempre o Para;
  • A utilização deve ocorrer somente no método 1:1 (um para um);
  • Os nomes das colunas na tabela de mapeamento não são relevantes;
  • Por se tratar de uma tabela de mapeamento, ela existirá somente durante o carregamento (load);
  • Nenhuma associação (ligação) será feita nesta tabela;
  • Nenhum erro é gerado se você usar um nome de tabela de mapeamento que não existe

 
 
 

A função

A função ApplyMap possui três parâmetros, sendo:

  • Nome da tabela de mapeamento (deve ser usado entre apóstrofes) – Obrigatório
  • Nome do campo que sofrerá o De-para – Obrigatório
  • Retorno caso não seja encontrado nenhuma valor na tabela de mapeamento – Opcional – Caso não seja preenchido, será retornado o próprio valor do campo que não foi encontrado.

 
 
 

Exemplo simples de utilização

//Criando a tabela de mapeamento

MapaEstado:

Mapping LOAD

UF,

DESC_UF

From Estado.qvd (qvd);

 

//Utilizando a função

ApplyMap(‘MapaEstado’, UF, ‘Não Encontrei’) as DESCRICAO_ESTADO

 
 
 

Orientações

É muito importante utilizarmos o terceiro parâmetro da função com uma string que identifique que nenhum valor foi encontrado, pois dessa forma é possível identificar casos em que a regra utilizada não obteve valor.

Sempre utilize o terceiro parâmetro da função, para retornar algum valor nos casos em que não foi encontrado nenhum mapeamento.

 
 
 

Benefícios

O principal benefício da função é o desempenho na realização do De/Para. É sempre recomendado a utilização do ApplyMap ao invés de JOIN quando se trata da ligação entre duas tabelas grandes. Não acredita? Existem diversos cenários testados que comprovam, procure na comunidade :D!

Outro benefício é que, como dito anteriormente, o ApplyMap funciona apenas em casos de 1:1 (um para um), ou seja, um determinado registro possui apenas um valor a ser mapeado. Caso a função seja utilizada em casos N:1, então será retornado o primeiro registro (De N) do mapeamento para aquele caso e não será gerado nenhum produto cartesiano dos dados.

No exemplo abaixo, o vendedor Yuri possui dois apelidos, ‘Nicolett’ e ‘Yure’. Se fosse realizado um JOIN para interligar essas tabelas, os valores de vendas do vendedor Yuri seria duplicado devido as duas possibilidades de apelido, porém com ApplyMap, somente o primeiro valor encontrado no mapeamento seria retornado (‘Nicolett’) e os valores de vendas permaneceriam inalterados.

 
 

MapaApelido:
Mapping LOAD * INLINE [
NOME, APELIDO
Yuri, Nicolett
Yuri, Yure
Paula, Paulinha
];

 
Fato:
LOAD
ID,
NOME_VEND,
VALOR,
ApplyMap(‘MapaApelido’, NOME_VEND, ‘Achei não!’) as APELIDO
INLINE [
ID, NOME_VEND, VALOR
1, Yuri, 2
2, Yuri, 4
3, Paula, 5
];

 
 

Por último, e não menos importante, é possível se utilizar desse mapeamento para outra tratativa sem a necessidade de um pré-load ou resident, pois ao fazer o mapeamento o novo valor fica disponível para utilização naquele momento.

No exemplo abaixo é calculada o valor de comissão do vendedor em apenas 1 passo:

 

MapaComissao:

Mapping LOAD

VENDEDOR,

PERC_COMISSAO

FROM Comissao.qvd (qvd);

 

Fato:

LOAD

QTD_VENDA * ApplyMap(‘MapaComissao’, VEND, 0) as VALOR_COMISSAO

RESIDENT ….

 
 
 

Casos extremos

Mas Yuri, e se precisar recuperar 4 campos de outra tabela? Valeria a pena criar 4 mapeamentos ou fazer um único join?

Para identificar qual a melhor opção nessa caso eu precisaria de mais um detalhe: O volume de registros das duas tabelas é grande? Passa de 1 milhão de linhas? Vai variar muito daqui N tempo? Se o volume de dados é grande, então não tenho receio algum de te recomentar a utilização de 4 tabelas de mapeamentos e 4 applymaps, caso contrário utilize JOIN.

 
 
 

E mais alguns detalhes

Com o ApplyMap

O terceiro parâmetro da função ApplyMap é muito poderoso, pois você pode utilizar funções ou combinações de campos, por exemplo:

 

1) Retorne um conjunto de campos

ApplyMap(‘Mapeamento’, CAMPO, CAMPO2& ‘-‘ &CAMPO3)

 

2) Caso um mapeamento não funcione, tente outro.

ApplyMap(‘Mapeamento’, CAMPO, ApplyMap(‘MapeamentoDois’, CAMPO2))

/* Sinceramente esse caso é muito interessante, já presenciaram modelagens que a ligação entre duas tabelas pode ser realizada através de duas chaves diferentes? Dependendo da situação através de uma chave ou através de outra? Esse caso pode salvar sua vida rsrs */

 

3) Funções – Verifico condição

ApplyMap(‘Mapeamento’, CAMPO, if( CAMPO2 > CAMPO3, ‘É Maior’, ‘É Menor’))

 
 
 

Conclusão

É sempre bom se utilizarmos desse manual das melhores práticas e o ApplyMap é uma das principais funções para conseguirmos obter o melhor desempenho (de carga) dentro do script das nossas aplicações. Sempre analise seu atual ambiente e em caso de dúvidas faça o teste entre JOIN e ApplyMap.

 

 

 

Até a próxima semana!