Mudança de abas automaticamente (ideal para LCDs)

Algo que sempre gera dúvidas: Existe a possibilidade de montar um dashboard e este dashboard ficar trocando de abas, ou objetos, automaticamente no LCD da sala de minha empresa?

R: Sim, existe!

A forma em que irei demonstrar é fazer através do I.E. Plugin (Internet Explorer). Ahhh, mas quero fazer funcionar no AJAX, tem como?

R: Sim, mas deixarei para um próximo post (podem me cobrar), pois para funcionar no ajax teremos que alterar algumas dlls.

Sem mais enrolação, vamos ao código:

1) Crie uma nova aplicação.

2) Crie três variáveis:

  • vAba = Definirá a quantidade de abas que sua aplicação possui para fazer a rotação automática.
  • vDelay = Definirá o tempo, em segundos, em que cada aba deverá permanecer.
  • vMostra = Definirá qual a atual aba estará sendo visualizada.

Em nosso exemplo: teremos 4 abas e quero que cada aba fique visível por 15 segundos.

SET vAba = 4;
SET vDelay = 15;
SET vMostra = =ceil((frac(now())*86400/(vAba*vDelay)-floor(frac(now())*86400/(vAba*vDelay)))*(vAba));

3) Altere o modo de atualização da aplicação para “O servidor executa a atualização automaticamente sem a ação do cliente.”

Localização desta opção: Configuração -> Propriedades do Documento -> Aba “Servidor”.

Mudança automática de abas.

Mudança automática de abas.

OBS: Para que serve isso? Isso é essencial para que sua atualização atualize os dados automaticamente, caso esta opção não esteja marcada e a carga desta aplicação tenha acabado de executar, os dados da aplicação não serão atualizados até que o usuário vá e faça alguma ação nesta aplicação.

4) Nas propriedades de cada uma das abas, habilite a condicional para Mostrar a pasta e coloque a seguinte regra:

vMostra = 1 //para a aba 1

vMostra = 2 //para a aba 2

vMostra = 3 //para a aba 3

vMostra = 4 //para a aba 4

Condicional de pasta

5) Esconda as abas para ficar mais bonitinho 😀

Configuração -> Propriedades do Documento -> Aba Geral -> Habilite Ocultar Pasta

Prontinho, agora a cada 15 segundos sua aplicação vai trocar de aba.

Em anexo estou disponibilizando um exemplo de aplicação. Faça o download aqui.

Expressões considerando datas diferentes

É um caso aparentemente simples (que sempre é solicitado rsrs) em que um gráfico com dimensão temporal (dia ou mês ou ano) referencia duas expressões que se baseiam em datas diferentes, por exemplo: Quantidade de notas emitidas e quantidade de notas canceladas em que a quantidade de notas emitidas se baseia na coluna temporal DATA_EMISSAO e a quantidade de notas canceladas se baseia na coluna temporal DATA_CANCELAMENTO.

Pergunta: Qual a coluna de data que se deve utilizar na dimensão do gráfico? Se usarmos a data de emissão, a coluna de notas canceladas ficará incorreta, pois nem todas as notas canceladas foram canceladas na data (ou mês ou ano) da emissão.  Se usarmos a data de cancelamento, a coluna de notas emitidas ficará incorreta devido ao mesmo caso.

Com o problema em mãos, começamos a pensar sobre possíveis soluções, por exemplo:

  1. Criar uma tabela de calendário isolada da modelagem (sem nenhuma ligação) “a famosa ILHA” e fazer a referência dentro da expressão. Problema: A performance de sua aplicação vai despencar.
  2. Isolar os fatos em tabelas separadas: tabela de notas emitidas e tabela de notas canceladas. Problema: A performance é boa, porém iremos duplicar o volume de dados de nossa aplicação.

Confesso que estava partindo para a solução 2, porém me veio um “insight” na cabeça: Porque não criar uma linktable das datas? Isso me aumentaria um “IF” dentro do gráfico, porém continuaria com uma boa performance e não aumentaria, em muito, minha volumetria de dados.

Vamos a prática:

1) Criamos a nossa tabela Fato:

Fato:
LOAD * INLINE [
NUM_NOTA, VALOR, DATA_EMISSAO, DATA_CANCELAMENTO
00001, 10, 01/01/2014, 10/02/2014
00002, 2, 05/01/2014,
00003, 1, 05/01/2014
00004, 5, 05/01/2014, 10/01/2014
00005, 11, 06/01/2014, 10/01/2014
00006, 8, 06/01/2014,
00007, 12, 06/01/2014,
00008, 4, 01/02/2014, 05/02/2014
00009, 8, 01/02/2014, 10/02/2014
00010, 4, 01/02/2014, 18/02/2014
00011, 3, 05/02/2014,
00012, 5, 05/02/2014,
00013, 10, 10/02/2014, 01/03/2014
00014, 2, 01/03/2014, 10/03/2014
];

2) Criamos uma tabela de Link entre o fato e o nosso calendário oficial, para criar esse link devemos dividir a tabela fato em duas: a primeira com as datas de emissão e a segunda com as datas de cancelamento. Após a divisão devemos concatena-las utilizando o mesmo nome do campo de data, mas lembre-se de criar uma coluna com o identificador da origem da data.

IMPORTANTE: Alem do campo de data e identificador, também devemos decidir qual será o campo chave entre a tabela de Link e a tabela Fato.

LinkData:
LOAD
NUM_NOTA,
DATA_EMISSAO as Data,
‘DataEmissao’ as Tipo
RESIDENT Fato;

LOAD
NUM_NOTA,
DATA_CANCELAMENTO as Data,
‘DataCancelamento’ as Tipo
RESIDENT Fato
WHERE
LEN(TRIM(DATA_CANCELAMENTO))>0; //Garantia para concatenar somente datas de cancelamento válidas.

3) Criar a tabela de calendário e fazer a ligação entre a tabela calendário com a tabela de Link.

Realizado os passos, no gráfico, utilize a dimensão de Mês e Ano da tabela de calendário e nas expressões faça a referência com a coluna de identificação da origem da data, conforme exemplo abaixo:

Expressão para quantidade de notas fiscais emitidas

COUNT( {$<Tipo={“DataEmissao”}>} NUM_NOTA)

Expressão para quantidade de notas fiscais canceladas

COUNT( {$<Tipo={“DataCancelamento”}>} NUM_NOTA)

Pronto, agora podemos referenciar as datas no mesmo gráfico, garantir uma alta performance e não aumentar muito a volumetria de dados em nossa aplicação.

PS: Isso vale para datas em tabelas diferentes, o processo será o mesmo.

Estou anexando uma aplicação de exemplo para vocês. Faça o download aqui.

É isso! Abraço a todos!!

Verbatim

Hoje estava penando em um projeto em que precisava inserir valores que começassem em branco (em outras palavras: começassem com espaço) e em alguns casos terminassem em branco também, por exemplo: ” Yuri Nicolett ” ou ” Yuri Nicolett” ou “Yuri Nicolett “.
Tentei algumas formas e não estava conseguindo resolver esse caso até que procurei no manual e encontrei (se você não encontrar no manual não existe) uma variável de sistema chamada Verbatim.

Essa variável de sistema é responsável por habilitar, ou não, que campos iniciem ou terminem em branco (com espaço rsrs).

Segue a descrição da mesma conforme o manual:
Em geral, são removidos de todos os valores de campo os caracteres em branco (ASCII 32) precedentes ou subseqüentes, antes de serem carregados na base de dados do QlikView.

Caso você queira que textos iniciem ou terminem em branco, basta adicionar ou alterar o valor dessa variável para “1”, desta forma:

SET Verbatim = 1;

Simples e fácil, o problema sempre é desconhecer as funções!

Melhores Práticas – QVD Optimized

Pessoal, estarei postando diversos passos de melhores práticas em QlikView e gostaria que todos participassem. Acho que vai ficar bem legal!

Vamos lá!

Cargas QVD otimizadas são até 100 vezes mais rápidas do que as não otimizadas. Isso faz muita diferença no tempo de recarga e ainda mais diferença para o desempenho do seu servidor.

A razão para a grande diferença está relacionada ao algoritmo de compressão que o QlikView usa quando armazenamos dados para análise em memória. Arquivos QVD são armazenados em um formato que espelha a compressão utilizada na memória (que é por isso que os arquivos QVD são tão pequenas no disco) e durante uma carga otimizada os dados são enviados diretamente do disco para a memória no mesmo formato comprimido. Quando uma carga não-otimizada é realizada isso não acontece.

Então porque não fazer todas as cargas do QVD otimizado? O simples fato é que algumas operações requerem que os dados sejam descompactados, modificados e em seguida re-embalados. Apenas uma alteração nos dados fará com que uma carga não seja otimizada.

Alguns exemplos que farão com que a carga não seja otimizada:

– Adição de novos campos para a tabela

– Derivando novos valores a partir de um campo na QVD

– Recuperando um campo duas vezes

– Mais condições WHERE

– JOIN em uma tabela de memória

– Carregando dados em uma tabela de mapeamento (mapping load)

Alguns exemplos que farão com que a carga seja otimizada:

– Renomear campos

– LOAD DISTINCT

– Omitir Campos (Omit)

– Where Exists Simples

Quando criamos QVDs incrementais com quebra por mês, ou seja, um qvd por mês (Faturamento_201401.qvd, Faturamento_201402.qvd), na maioria das vezes, quando o cliente deseja restringir a quantidade de meses na aplicação, criamos uma variável e restringimos através de um WHERE MESANO >= $(v_MesAno_Limite), mas a dica aqui é utilizar o EXISTS Simples, ou seja, com um campo só. Vamos para um exemplo:

Quero exibir somente os dados de 2013 e 2014, desta forma realizamos a seguinte lógica:

1) Criar uma tabela (INLINE) com o mesmo nome da coluna da tabela que sofrerá redução dos anos e colocar os valores 2013 e 2014.

OBS: Isso vale para MêsAno, Datas, Produtos ou combinações de colunas.

Restrição:

LOAD * INLINE [

Faturamento.ANO

2014

2013

];

2) Quando realizar a leitura da tabela em que deseja fazer a restrição dos valores, basta realizar a leitura normalmente e adicionar um WHERE Exists para retornar somente os dados de 2014 e 2013.

Faturamento:

LOAD

    Faturamento.ANO,

    Faturamento.MES,

    Faturamento.DATA,

    Faturamento.EMPRESA,

    Faturamento.VALOR

FROM Faturamento_*.qvd (qvd)

WHERE

EXISTS(Faturamento.ANO);

DROP TABLE Restrição;

Repare que a leitura dos qvds manterá o QVD Optimized!

Fontes:

Manual QlikView

Optimized QVD Loads in Qlikview

Qlikview Notes: QVD Questions and Answers

Google Maps: Método antigo desativado

Em 12 de Março de 2013 a api do google maps para maps estatisticos foi desativada (v2) e agora passa a ser utilizada somente a nova versão (v3). Mesmo a v2 sendo uma versão mais antiga, esta era muito utilizada por diversos desenvolvedores.

A nova versão exige uma API_KEY, esta chave pode ser obtida através do tutorial: https://developers.google.com/maps/documentation/javascript/tutorial#api_key

Bom, vamos para as outras mudanças:

A url de busca passou de


maps.google.com/staticmap?

para

maps.googleapis.com/maps/api/staticmap?

desta forma nosso código na imagem dinâmica ficou:

=

http://maps.google.com/maps/api/staticmap?center=’
&
num(var_mid_lat, ‘##############’, ‘.’, ‘,’ )
&
‘,’
&
num(var_mid_long, ‘##############’, ‘.’, ‘,’ )
&
‘&zoom=$(var_zoom)’
&
‘&maptype=’&var_maptype
&
‘&size=’&map_size_x&’x’&map_size_y
&
‘&key=’&gmap_key & ‘&sensor=false’

 

*em negrito estão as alterações.

 

Com essas alterações seu mapa volta a funcionar!

 

Qualquer dúvida e/ou problema estou a disposição galera!