Qlik Sense Arquitetura de Dados - Apostila 2018-04
Qlik Sense Arquitetura de Dados - Apostila 2018-04
Qlik Sense Arquitetura de Dados - Apostila 2018-04
Portal da Qlik
http://www.qlik.com
Este portal possui várias informações sobre os produtos e a Qlik. O que queremos destacar a
você é a seção Community, que é a comunidade de Usuários e Desenvolvedores dos produtos
da Qlik. Lá há grupos de usuários, fóruns, blogs, projetos para download e artigos técnicos
(PDF). Para ter acesso aos recursos da Community, você deve fazer um cadastro no portal.
Qualquer usuário pode solicitar seu cadastro.
Help Online (ou Ajuda Online)
Este portal, disponível em vários idiomas, inclusive o português, é bem completo. Diferencia-se
por possuir exemplos para a maioria das funções.
Agenda
Durante o Curso Desenvolvedor I, abordaremos os seguintes temas:
• Estrutura de Arquivos
• Instalação do Qlik Sense Desktop
• Plano de Projeto
• Estrutura dos dados e AQL
• Script e Carga
• Preparação de Dados
• Load Residente, Chave Sintética e Função Exists()
• Campos Chave
• Load Inline, Autogenerate e Mapping
• Tratamento de dados não padronizados
• Arquivos QVD e QVW
• Variáveis
• Concatenação
• Depuração
Questões a desenvolver durante o curso
Vamos ver agora algumas questões que serão desenvolvidas em nosso curso.
• Como interpretar um plano de projeto?
• Como acessar dados e integrá-los com dados de outras fontes?
• Quais são algumas das técnicas para desenvolver modelos de dados?
• Que recursos estão disponíveis para visualizar a estrutura de dados em várias
fontes?
• Como e por que criar através do editor de carga e o gerenciador de dados?
• Quais os padrões a adotar para tornar minha aplicação eficiente, compreensível e
de manutenção simples?
• Como tornar uma aplicação segura?
• O que fazer quando tenho um problema?
Estrutura de Arquivos
Para este treinamento, usaremos instaladores e fontes de dados que estão dentro das pastas
conforme o modelo a seguir:
A instalação é simples como qualquer outro software que já tenha instalado em seu
computador.
Se desejar, pode executar a instalação do Qlik ODBC Connector Package x64, um excelente
recurso, disponibilizados pela Qlik, para obter drives de diferentes fontes de dados.
Plano de Projeto
Veja agora as seções do Plano de Projeto QWT.
Medidas
Aqui encontraremos algumas das expressões que serão necessárias na aplicação.
Alguns desses cálculos serão usados no arquivo de carga, outros serão usados nos objetos
(gráficos, texto, filtros, tabelas) que compõem a interface com o usuário.
Dimensões
Esta seção inclui a lista de algumas das dimensões chave a serem utilizadas durante o
desenvolvimento dessa aplicação.
Tendências
Disponibiliza uma importante lista das dimensões que trabalham com campos “tempo” que
serão necessários para uma análise histórica dos dados.
Filtros de Seleção
Inclui uma lista de campos necessários para executar seleções e filtros sobre os dados
carregados na aplicação.
Segurança
Contém as necessidades referentes à segurança de acesso a uma aplicação.
Nesta lição você aprendeu o que é um plano de projeto e qual a importância de fazer um
planejamento antes de começar a desenvolver o projeto. O que você achou? Está fácil,
concorda? Vamos dar andamento aos nossos estudos!
Vamos praticar um pouco? Exercite o que você aprendeu aqui!
( ) Esta seção inclui a lista de algumas das dimensões chave a serem utilizadas
durante o desenvolvimento dessa aplicação.
( ) Alguns desses cálculos serão usados no arquivo de carga, outros serão usados nos
objetos (gráficos, texto, filtros, tabelas) que compõem a interface com o usuário.
( ) Disponibiliza uma importante lista das dimensões que trabalham com campos
“tempo” que serão necessários para uma análise histórica dos dados.
( ) Inclui uma lista de campos necessários para executar seleções e filtros sobre os
dados carregados na aplicação.
( ) Disponibiliza localização e descrição dos campos para cada fonte de dados.
( ) Contém as necessidades referentes à segurança de acesso a uma aplicação.
( ) Esta seção inclui Indicadores Chave de Performance que podem ser mostrados
através de objetos na aplicação.
Lição 2 - Estrutura dos Dados e AQL
Objetivo da Lição
Nesta lição, você vai aprender a:
• Conhecer as Estruturas de Dados que podem ser fontes de dados para aplicação.
• Conhecer a maneira de como trazer esses dados para os projetos.
Estruturas de Dados
Existem várias classificações técnicas para Dados, como SGBD, Bancos Transacionais, Sistemas
de Arquivos, entre outros. Para um fácil entendimento para este curso, podemos classificar os
dados (fontes para projetos) em dois grupos:
• Bases de dados relacionais
o Microsoft SQL Server, Microsoft Access, Oracle, DB2, Sybase, Informix,
Teradata, entre outros.
• Arquivos delimitados, fixos ou padronizados
o Estrutura de dados comum para alimentar aplicações são arquivos de texto
(csv, skv), planilhas no formato Excel e padrões XML, HTML, KML.
Uma vez que os dados foram carregados para o projeto, temos as seguintes definições:
• Cada coluna de uma tabela, que é carregada, torna-se um campo na base de dados
associativa (também referenciada como base de dados AQL).
• Campos que aparecem em mais de uma tabela e tenham mesma identificação
serão automaticamente associados.
• Cada campo pode ser apresentado na forma de filtros na aplicação.
• Quando uma seleção é feita em um campo ou gráfico, a pesquisa é feita através de
toda a base de dados associativa por conexões lógicas. Como resultado desta
pesquisa, os valores associados com sua seleção serão identificados.
Exemplos de Select:
SQL SELECT * FROM CLIENTES;
Load
RecNo() as A,
rand() as B
Autogenerate(10000);
Load
A,
B,
A*B+D as E
Resident tab1;
Load *
Inline [
CatID, Category
0, Regular
1,Occasional
2,Permanent];
// QVD
STORE Categorias$
INTO [lib://Dados/Categorias.qvd] (qvd);
// QVX
STORE Categorias$
INTO [lib://Dados/Categorias.qvx] (qvx);
// CSV (Com ponto e vírgula)
STORE Categorias$
INTO [lib://Dados/Categorias.csv]
(txt, delimiter is ';');
// TAB
STORE Categorias$
INTO [lib://Dados/Categorias.tab]
(txt, delimiter is '\t');
Exemplos de Comentários
// Transforma em comentário
// tudo que estiverem na mesma linha.
/*
Transforma em comentário tudo que estiver entre estes símbolos.
*/
Exemplos de Condicional
FOR x = 1 TO NOOFROWS('Tabela')
LET vCampo = FIELDVALUE('Campo',$(x));
TRACE $(vCampo);
NEXT
SET a = 1;
DO WHILE a<10
TRACE $(a);
LET a = a+1;
LOOP
Nesta segunda lição, você conheceu as estruturas de Dados que podem ser fontes de dados
para Projetos, aprendeu sobre a origem e os comandos de Dados para Carga, viu as Fontes de
Dados Você conseguiu compreender todo o conteúdo estudado até aqui? Vamos prosseguir!
Vamos praticar? Exercite o que você aprendeu aqui!
Fontes de Dados
Veja que a imagem a seguir nos mostra que não importa de onde vieram os dados depois da
leitura. Dados são dados e são trata-os sem distinção.
Carregar as Tabelas
Agora vamos ver os passos para carregar as primeiras tabelas na aplicação.
• Selecione todos os campos nas tabelas DetalhesPedidos e Pedidos, marcando-as
cada uma conforme abaixo.
• Pode-se visualizar os dados de cada tabela ao clicar no nome correspondente ao
lado esquerdo.
• Clique em Adicionar dados.
Analisador de dados
Vamos agora analisar as duas tabelas
Ao clicar sobre a tabela de Pedidos, aparece uma recomendação de associação com a tabela
DetalhesPedidos na cor verde, isso quer dizer que é altamente recomendável fazer essa
associação, para isso, arraste a bolha de Pedidos para cima da bolha de DetalhesPedidos e
solte.
No exemplo abaixo, selecionamos a tabela de Pedidos e clicamos no ícone editar.
Ao arrastar a tabela de categorias para realizar associação com DetalhesPedidos, aparece uma
realce em vermelho que quer dizer associação não recomendada.
Após realizar todas as associações o modelo de dados deve ficar nesse modelo
Nesse momento que os dados estão sendo incorporado ao Qlik Sense
Nesta lição você aprendeu carregar as tabelas que serão utilizadas no treinamento e a fazer o
tratamento inicial dos dados. Ainda restou alguma dúvida? Lembre-se de prosseguir somente
se tudo estiver muito claro para você!
Exercite o que você aprendeu aqui!
O campo chave nessa tabela é FuncID, que permitirá associar essa informação aos demais
dados já carregados.
Carregue os dados e observe que ocorre a mensagem alertando para a Referência Circular.
Uma referência circular é um sinal de um modelo de dados incorreto, no qual dois campos
semelhantes, que têm interpretações ligeiramente diferentes, são tratados como um só.
Quando o indexador descobre a referência circular durante a execução do script, as tabelas
são parcialmente desconectadas.
Sempre que ocorrer uma referência circular, você deve se perguntar: - Eu consigo resolver isso
renomeando campos? Se sua resposta for sim, significa que os nomes dos campos iguais que
causaram a referência circular referem-se a dados que não deveriam estar associados, ou seja,
refletem informações distintas, apesar de ter o mesmo nome.
Entretanto, se realmente existir a necessidade de os dados estarem associados, você não
poderá renomear os campos. A solução será trabalhar de modo diferente a modelagem dos
dados, implementando um modelo estrela, utilizando uma tabela de ligação, por exemplo. No
entanto, essa técnica para implementar um modelo estrela utilizando uma tabela de ligação
será visto em outro curso.
Qualificando Campos
Outra forma de resolver Referência Circular, você não deve mudar o nome dos campos
manualmente, utilize a técnica de Qualificar os campos da tabela lida. Qualificar campos
significa identificar os campos acrescentando o nome da tabela antes do nome dos campos.
Insira as linhas de código abaixo, antes do comando de carregamento da tabela Fornecedores.
*;
Qualify
Unqualify FornecedorID;
Como o campo FornecedorID é usado para associar a outra tabela, não deverá utilizar o
qualificador da tabela.
Isso é especificado usando o comando.
Unqualify FornecedorID;
Após a tabela Fornecedores ter sido carregada, temos de adicionar o seguinte comando para
que os outros campos carregados posteriormente não utilizem o qualificador de tabela:
Unqualify *;
A figura a seguir mostra como ficará o bloco inteiro de leitura da tabela Fornecedores. Veja:
Qualify *;
Unqualify FornecedorID;
Fornecedores:
LOAD FornecedorID,
NomeEmpresa,
NomeContato,
Endereco,
Cidade,
CodigoPostal,
Pais,
Fone,
Fax
FROM [lib://Fonte de Dados/Fornecedores.xml]
(XmlSimple, table is [Records/Record/Row]);
Unqualify *;
Após todos os ajustes o modelo de dados deve ficar como na figura abaixo:
Nesta lição você aprendeu a carregar dados de outras fontes e a simular problemas no script
que podem ocorrer durante o trabalho no dia a dia, bem como opções para a solução desses
problemas. Vamos adiante!
Exercite o que você aprendeu aqui!
Laboratório 04 - Preparação de Dados
1. Aplique o comando Qualify para todos os campos da tabela Categorias. Tome o
cuidado, no entanto, para manter a associação de Categorias com Produtos, depois
remova esse comando para darmos seguimento ao curso.
2. O que significa qualificar campos?
Load Resident
Agora você vai aprender a criar uma tabela usando como base uma tabela previamente
carregada (Resident).
Vai aprender também a segmentar o script de carga em diferentes seções, para facilitar a
leitura e a manutenção.
Siga os passos:
• Abra o Editor de carga de dados.
• Adicione uma nova seção clicando no ícone Criar nova seção. Use Vendedores
como nome dessa nova aba.
• Adicione um comando de carga para uma nova tabela, mas, dessa vez, em vez de
usar o Assistente para criar o código, digite o código abaixo:
/* Tabela Vendedores */
Vendedores:
LOAD FuncionarioID,
Sobrenome,
[Primeiro Nome],
Titulo as TituloVendedor
Resident Funcionarios$;
Agora queremos limitar a carga dos registros dos empregados para somente aqueles que
podemos identificar como pessoal de vendas.
• Para isso, você precisa fazer outra alteração no código do script:
• Primeiro, remova o ponto e vírgula (;) localizado após Resident Funcionarios$.
Depois, adicione a condição Where após o comando Resident, como a seguir:
Left(Titulo,3) = 'Sal'
Where
or Titulo = 'President';
Chave Sintética
É indesejável que tenhamos várias chaves comuns através das tabelas da estrutura de dados.
Essa situação pode levar o indexador a usar chaves complexas (chaves sintéticas) ao gerar a
estrutura de dados.
Chaves sintéticas é um tipo de recurso pesado, e geralmente o uso desse tipo de recurso pode
tornar lento o processo de cálculo e, em casos extremos, sobrecarregar uma aplicação.
Também tornam um documento difícil de entender e manter.
Quando você criou a tabela que gera o campo TituloVendedor, inadvertidamente foi criada
uma chave sintética entre as tabelas Funcionários e Vendedores.
A chave sintética é gerada em uma nova tabela, que pode ser identificada no Visualizador do
modelo de dados.
Como podemos ver, existe uma tabela para chave sintética composta pelos campos Primeiro
Nome, Sobrenome e FuncionarioID.
Neste caso, não existe razão para que você utilize os campos nome como uma chave adicional
entre essas tabelas, já que o campo FuncionarioID já serve para esse propósito.
Para corrigir essa situação, você utilizará a técnica de mudar os nomes dos campos
novamente.
Mude o nome dos campos que não necessite como campos chave.
Na leitura da tabela Vendedores, vamos renomear os campos conforme abaixo:
/* Tabela Vendedores */
Vendedores:
LOAD FuncionarioID,
[Primeiro Nome] & ' ' & Sobrenome as Vendedor,
Titulo as TituloVendedor
Resident Funcionarios$
Where Left(Titulo,3) = 'Sal'
or Titulo = 'President';
Após carregar os dados, você poderá confirmar que a chave sintética não mais existe. Você
pode confirmar isso usando o visualizador de tabelas novamente (Visualizador do modelo de
dados).
Função Exists
Você utilizou um método simples que permitiu identificar os Vendedores em um conjunto de
Funcionários. Para este caso específico, foi adequado, mas podemos chegar ao mesmo
resultado usando uma solução mais interessante e mais confiável.
Agora, você definirá que os vendedores são aqueles que estão incluídos nos nossos dados de
vendas. Serão considerados vendedores aqueles que forem identificados no campo
FuncionarioID na tabela Pedidos.
Para começar, vamos criar um campo com o nome FuncionarioVendedor para identificar os
vendedores com segurança.
Utilize a linha de comando abaixo para a tabela Pedidos, imediatamente após o campo
FuncionarioID.
FuncionarioID,
FuncionarioID as FuncionarioVendedor,
/* Tabela Vendedores */
Vendedores:
LOAD FuncionarioID,
[Primeiro Nome] & ' ' & Sobrenome as Vendedor,
Título as TituloVendedor
Resident Funcionarios$
Where Exists(FuncionarioVendedor,FuncionarioID);
A condição na cláusula Where verifica se existem dados carregados que sejam equivalentes
aos valores do campo FuncionarioVendedor .
Como o nome indica, a função Exists() pode ser utilizada para verificar se um valor específico
existe em um dado campo dos dados carregados até esse momento.
Lembre-se de cuidar com a ordem com que você define a sequência de comandos, já que os
campos de referência devem ser alimentados antes da verificação de valores.
Neste exemplo, a tabela Pedidos tem de ser carregada antes da tabela Vendedores para que
essa condição funcione de forma apropriada. Após completar essas modificações, carregue os
dados para ser verificada a funcionalidade.
Nesta lição, você aprendeu a criar uma tabela de dados diretamente no editor de carga de
dados através do Load Resident, entendeu o que são e como podemos evitar o uso de chaves
sintéticas e viu a Função Exists, que serve para condicionar o preenchimento de tabelas.
Lembre-se: em caso de dúvida, retorne ao conteúdo e faça uma revisão dos pontos que achar
necessário.
Exercite o que você aprendeu aqui!
Laboratório 05 - Load Resident, Chave Sintética e Função
Exists()
1. Faça uma nova aplicação utilizado os dados desse curso e crie uma seção no editor de
carga de dados com o nome “Produtos Vendidos”. Crie uma tabela com os seguintes
campos:
• ProdutoID,
o PedidoID (Renomear para Pedido) e
o PrecoUnitario (Renomear para ValorUnitario)
Use as Funções Resident e Exists para criar essa nova tabela.
2. Complete a frase a seguir:
A frequência de um campo está associada ao __________, ou seja, é o número de
vezes que um valor aparece no conjunto de __________.
a. dado; campos
b. valor; obras
c. valor; dados
d. número; dados
Campos Chave
Campos chave são aqueles que são comuns em duas ou mais tabelas (campos associados).
Frequência
A frequência de um campo está associada ao valor, ou seja, é o número de vezes que um valor
aparece no conjunto de dados.
O problema de calcular a frequência em um campo chave é que o indexador não saberá qual
tabela utilizar para contar a incidência dos dados.
Supondo que temos uma tabela chamada Pedidos com 1.000 diferentes números de
pedidos (PedidoID).
Temos também uma tabela com nome PedidosExternos, que contém 200 números de
pedidos.
Esses números também são encontrados na tabela Pedidos.
As duas tabelas são associadas através do campo em comum PedidoID.
O problema está quando queremos saber exatamente o número de pedidos únicos.
O correto é 1.000, 200 ou 1.200?
Com base nas informações que temos, sabemos que é correto responder que existem 1.000
pedidos únicos, mas isso não é tão claro assim no modelo associativo.
Se olhássemos as propriedades do campo no modelo, seria exibido 1.200 valores não nulos e
1.000 valores totais distintos.
Também é importante saber que será impossível usar, nos gráficos e itens mestres, funções
para calcular frequência de campos associados.
Qualificador Distinct
Para calcular corretamente a frequência de um campo chave, o uso do Distinct garante que
contaremos somente uma vez a incidência de cada valor possível do campo. Por exemplo: se
queremos saber quantos Pedidos únicos existem:
Em vez de utilizarmos a expressão: Count(PedidoID), adicionamos o Distinct da seguinte
maneira: Count(DISTINCT PedidoID).
Adicionando Contadores
Uma solução relativamente simples para o problema dos campos chave e o cálculo de
frequência de dados é carregar o campo que queremos calcular a frequência uma vez mais
com outro nome.
Esse problema pode ser resolvido da seguinte forma:
/* Exemplo */
[Pedidos]:
LOAD [PedidoID],
[PedidoID] as CodigoPedido,
...
Em geral, é boa prática evitar o uso de campos chave em listas e expressões. Campos chave
devem ser usados para ligar tabelas, e não para mostrar dados em uma aplicação.
Agora o novo campo (não associado) pode ser utilizado em um filtro, que mostrará a
frequência ou o gráfico com funções para calcular frequência.
O novo nome de campo pode facilmente ser tratado ao atribuirmos uma outra identificação
por forma a não confundir os usuários.
Observe a tabela abaixo e os resultados apresentados:
Cálculos no Script
É possível usar diversos operadores e funções no script para efetuar os mais variados cálculos,
tanto diretamente no Load quanto para definições de variáveis.
Vamos criar a medida Venda Líquida na memória, com dados da tabela Detalhes Pedidos
fazendo os cálculos conforme script abaixo.
[DetalhesPedidos]:
LOAD [Desconto],
[PedidoID],
[PrecoUnitario],
[ProdutoID],
[Quantidade],
[PrecoUnitario]*[Quantidade]*(1-[Desconto]) as VendaLiquida;
SQL SELECT `Desconto`,
`PedidoID`,
`PrecoUnitario`,
`ProdutoID`,
`Quantidade`
FROM `DetalhesPedidos`;
Comando Include
É possível fazer a inclusão de partes de script usando a função include, isso é particularmente
útil para reaproveitamento de código, para versionamento e fácil migração de aplicações entre
ambientes de teste, homologação e produção.
Vamos incluir, após a carga das planilhas, o pedaço de script que está no arquivo Email.txt a
nossa aplicação.
$(Include=[lib://Fonte de Dados/Email.txt]);
Dimensões de Tempo
Existem dimensões de tempo previstas no Plano de Projeto, precisamos criar Ano, Mês, Dia,
Trimestre e Mês Ano.
Para criar Ano, Mês, Dia e Mês Ano, vamos usar um novo recurso chamado Campos
Derivados, que possibilita criar campo e definições de grupo.
O Trimestre, vamos usar uma tabela Inline, depois iremos recriar a mesma tabela usando o
Autogenerate.
Derivação de Campos
Declare
É usado para criar campo e definições de grupo, em que você pode definir as relações entre
campos ou funções. Um conjunto de definições de campo pode ser usado para gerar campos
derivados automaticamente, o que pode ser usado como dimensões. Você pode usar o
comando Declare para definir uma nova definição de campo ou criar uma definição de campo
com base em uma definição já existente.
Sintaxe:
definition_name:
Declare [Field[s]] Definition [Tagged tag_list ]
[Parameters parameter_list ]
Fields field_list;
Derive
É usado para gerar campos derivados com base em uma definição de campo criada com um
comando Declare. Você pode especificar a partir de quais campos de dados derivar os campos
ou derivá-los explicitamente ou implicitamente com base em tags de campos.
Sintaxe:
Derive [Field[s]] From [Field[s]] field_list Using definition;
Derive [Field[s]] From Explicit [Tag[s]] tag_list Using definition;
Derive [Field[s]] From Implicit [Tag[s]] Using definition;
• Criação de Calendários
• Criação de Campo de valores com base em um parâmetro.
• Utilização de medidas de calendários com YTD (year to date), MTD (month to date)
• Uso do Eixo contínuo num gráfico de análise temporal
Load Inline
Em alguns casos, pode ser interessante inserir dados diretamente através do script.
Geralmente fazemos isso para criar tabelas de Tipos, Status ou para resolver questões onde na
tabela aparecem códigos como:
1 = Significa Ativo
2 = Significa Inativo
Se sabemos que o usuário não conhece o significado desses códigos, podemos criar uma tabela
associada com a descrição desses códigos. Isso é feito com a ajuda do comando Load Inline.
Inclua o script abaixo logo após a declaração do Derive que fizemos anteriormente.
Trimestres:
Load * Inline [
Mês, Trimestre
1, T1
2, T1
3, T1
4, T2
5, T2
6, T2
7, T3
8, T3
9, T3
10, T4
11, T4
12, T4
];
Observe que o comando Load Inline contém os nomes dos campos e dados entre colchetes.
Observe também que os nomes dos campos estão localizados na primeira linha, e que os
valores estão separados por vírgulas.
A tabela assim inserida associa números dos meses ao trimestre correspondente. Quando o
script é executado, o novo campo Trimestre é gerado.
Mapping
A tabela Trimestres é útil, já que executa a ligação do mês ao respectivo trimestre. Entretanto,
o campo se torna um campo chave quando associado e isso provavelmente causará problemas
mais tarde. Existem algumas soluções para isso, como você verá a seguir.
O objetivo agora é trazer o campo Trimestre para dentro da tabela Pedidos. Para isso, você vai
usar o recurso Mapping Table (Tabelas Mapeadas).
O prefixo Mapping é utilizado em um comando Load ou Select para criar uma Mapping Table.
Tabelas lidas através de Mapping Load ou Mapping Select serão armazenadas em área de
memória separada e usada somente como Mapping Table durante a execução do script.
Após a execução do script, elas serão automaticamente eliminadas.
Mapping Table tem duas colunas:
• A primeira contém valor de comparação;
• A segunda, o resultado da comparação.
As duas colunas têm de receber nomes, mas os nomes são irrelevantes no modelo de dados.
Os nomes dessas colunas não definem ligação com nomes de campos em tabelas “normais”,
ou seja, pode ter o mesmo nome que outros campos em outras tabelas na memória ou que
serão carregadas.
Quando tabelas mapeadas são usadas para mapear um valor de campo ou expressão, aquele
valor será comparado com um valor na primeira coluna.
Se encontrado, o valor original será substituído por um valor correspondente na segunda
coluna da tabela Mapping. Caso contrário, não haverá substituição.
Sintaxe: Mapping ( load statement | select statement )
Agora, modifique o comando Load da tabela Trimestres em um comando de carregamento
Mapping, como a seguir:
Trimestres:
Mapping Load * Inline [
Mês, Trimestre
1, T1
2, T1
3, T1
4, T2
5, T2
6, T2
7, T3
8, T3
9, T3
10, T4
11, T4
12, T4
];
Ao realizar a carga novamente, poderá observar que a tabela Trimestres e seus campos não se
encontram mais disponíveis, já que tabelas Mapping só existem durante o processo de carga.
Entretanto, podemos usar a tabela Trimestres no nosso script, mas lembre- se: desde que seja
utilizado após essa definição no script. Para isso, utilizaremos a função ApplyMap().
Sintaxe: ApplyMap(‘mapname’,expr, [,defaultexpr])
Essa função identifica qualquer definição em uma tabela Mapping, previamente carregada.
Mapname é o nome do mapa previamente carregada por um comando Mapping Load ou
Mapping Select. Observe que o nome obrigatoriamente deve estar entre aspas simples.
Expr é a expressão ou somente o campo que o resultado deve ser mapeado.
Defaultexpr é uma definição opcional, que será usada como valor padrão, caso não exista
valor associado a expr. Se um valor padrão não é indicado, o valor de expr retorna tal como ele
é.
Vamos adicionar uma função ApplyMap() para a tabela Pedidos, com base no valor numérico
do campo Mês. Essa função refere-se à tabela Trimestres.
A função deverá ficar como a seguir:
[Pedidos]:
LOAD [ClienteID],
[DataPedido],
ApplyMap('Trimestres', Month([DataPedido])) as Trimestre,
[Frete],
[FuncionarioID],
[FuncionarioID] as FuncionarioVendedor,
[PedidoID],
[PedidoID] as CodigoPedido,
[TransportadorID];
SQL SELECT `ClienteID`,
`DataPedido`,
`Frete`,
`FuncionarioID`,
`PedidoID`,
`TransportadorID`
FROM `Pedidos`;
Carregue os dados e veja o resultado.
Autogenerate
Outra forma de gerar dados é utilizar o comando Autogenerate no script de carga.
Quando você especifica Autogenerate no script de carga, isso automaticamente irá gerar um
determinado número de registros.
Somente constantes e funções sem parâmetros são permitidas na utilização do Autogenerate.
Frequentemente, as funções RecNo() ou RowNo() são utilizadas para gerar um identificador
(número único) para cada linha.
Faça alteração no script conforme abaixo.
Trimestres:
Mapping Load RowNo() as Mês,
'T' & Ceil(RowNo()/3) as Trimestre
Autogenerate(12);
O Autogenerate(12) especifica que será criada uma tabela com 12 linhas.
A função RowNo() irá retornar o número da linha que está sendo criada na tabela lógica,
iniciando com 1.
A função Ceil() vai arredondar o número indicado para o próximo inteiro superior.
O caractere & é usado para concatenação.
Ficou fácil? Lembre-se: qualquer dificuldade que sinta, você deve retornar ao conteúdo, para
depois seguir adiante!
Vamos exercitar! Realize as atividades referentes à Lição 7.
Etapa de Transformação
Você pode observar que todos os dados que foram carregados até aqui estavam
razoavelmente estruturados e puderam ser carregados através dos comandos Select ou Load.
Entretanto, nem todos os dados estão tão formatados para serem carregados.
Nesta parte do curso, vamos explorar algumas opções disponíveis para carregar dados em
formatos não padronizados.
Um arquivo Excel (Orcamento.xls) contendo dados financeiros pode ser encontrado no
diretório Fonte de Dados.
Esse arquivo contém dados em duas planilhas:
• Os dados existentes na primeira planilha podem ser facilmente carregados sem
qualquer manipulação.
• Na segunda planilha, entretanto, os dados são apresentados em um formato
frequentemente encontrado nas organizações.
Abra o arquivo Orcamento.xls que se encontra no diretório Fonte de Dados e veja a planilha
Orcamento.
Esse formato de dados apresenta alguns desafios, mas pelo menos já podemos verificar que
uma carga irá gerar campos para cada ano, em vez de valores anuais em cada campo Ano,
como seria desejável em nossa aplicação.
Agora que você conheceu os desafios para alcançar dados padronizados, siga os passos:
Arraste o arquivo Orçamento.xls para a aplicação e mude o tamanho do cabeçalho para 1.
• Observe os campos Escritório e Linhas de Totais, teremos que tratar isso
diretamente no script, clique em Adicionar dados
• Selecione a opção tabela no gerenciador
• Clique em Aplicar não giro e depois renomear os campos para Ano Orçamento e
Montante
• Carregue os dados
Temos uma nova seção que foi gerada automaticamente, desbloqueie e altere o script
conforme abaixo, depois, carregue os dados.
[Orcamento$]:
CROSSTABLE ([Ano Orçamento],[Montante],2)
LOAD [Escritorio],
[Metrica],
[2007],
[2008],
[2009],
[2010]
FROM [lib://Fonte de Dados/Orcamento.xls]
(biff, embedded labels, header is 1 lines, table is Orcamento$
,filters( Replace(1, top, StrCnd(null))));
Importante:
Replace: Preenche a célula com o valor superior (top) se estiver vazia (null).
Observe que o campo Escritorio, agora está preenchido corretamente, porém, ao final, existem
duas linhas que não deveriam estar lá, vamos elimina-las.
[Orcamento$]:
CROSSTABLE ([Ano Orçamento],[Montante],2)
LOAD [Escritorio],
[Metrica],
[2007],
[2008],
[2009],
[2010]
FROM [lib://Fonte de Dados/Orcamento.xls]
(biff, embedded labels, header is 1 lines, table is Orcamento$
,filters( Replace(1, top, StrCnd(null))))
where IsNum(Escritorio);
Crosstable
Agora você está pronto para trabalhar com os campos qualificadores.
Um campo qualificador é simplesmente um campo normal, com dados em uma coluna.
Um campo qualificador será mantido como está em uma carga de tabela cruzada.
• Neste caso, os campos Escritorio e Metrica são campos qualificadores. Informe
então que serão dois campos qualificadores.
Na carga de tabela cruzada, todos os campos qualificadores, obrigatoriamente, devem estar
posicionados antes dos atributos e dos dados.
• Vamos usar o nome Ano Orçamento para identificar o campo de Atributo e o
nome Montante para identificar o campo de Dados.
Observe no modelo de dados, que o campo Montante contém todos os valores para
Orçamento e Real, mas preferimos ter esses valores em campos diferentes.
Para isso, necessitamos implementar um outro tipo de carregamento.
Generic Load
O prefixo Generic é usado para a descompactação e o carregamento de uma base de dados
genérica.
As tabelas carregadas por um comando Generic não são concatenadas automaticamente.
Observe que a coluna Montante contém todos os valores, na metrica contém a associação de
cada valor, porém, pode ser necessário ter cada Métrica em uma coluna separada
Logo abaixo da carga do Orçamento$ com o comando CrossTable que você fez a pouco, inclua
o script abaixo.
[Orcamento/Real]:
Generic Load
Escritorio &'|'& [Ano Orçamento] as %Key,
Metrica,
Montante
Resident [Orcamento$];
DROP TABLE [Orcamento$];
Importante:
Metrica e Montante.
Obrigatoriamente o penúltimo campo deve conter a informação genérica e o último campo o
valor propriamente.
O resultado no modelo será conforme a imagem abaixo:
Como as tabelas carregadas através do comando Generic Load, vamos utilizar o script abaixo
para ter apenas uma no final do script com todos os campos.
Nesta lição, você aprendeu a ler dados de arquivos não padronizados, contendo cabeçalho,
rodapé, linhas vazias, linhas de totais e células mescladas. Ficou tudo claro até aqui? Ótimo,
vamos prosseguir!
Vamos praticar? Realize as atividades referentes à Lição 8.
Formato
O arquivo QVD é uma tentativa de selar o compromisso do desempenho ideal dos produtos
Qlik na leitura e gravação de arquivos e da representação compacta.
Um arquivo QVD contém exatamente uma tabela. Em termos conceituais, é muito semelhante
a qualquer arquivo de tipo csv, dif, biff ou fix, e consiste em três partes:
• Um cabeçalho XML composto de modo apropriado (com o conjunto de caracteres
UTF-8), que descreve os campos da tabela, o layout das informações subsequentes
e alguns outros metadados.
• Tabelas de símbolos em um formato com bytes.
• Dados da tabela em um formato com bits.
Uso
Veja agora para que são usados arquivos QVD.
Carga Incremental
Em muitos casos comuns, a funcionalidade QVD pode ser usada para a carga incremental, para
carregar apenas novos registros de um banco de dados crescente.
Criação de QVD
Os arquivos QVD podem ser criados:
• Manual a partir do script.
• Buffer, criação automática a partir do script.
Em seguida, você poderá ver uma descrição melhor cada uma das técnicas de criação de QVD.
Store Clientes
into [lib://Fonte de Dados/Clientes.qvd] (qvd);
Store Produtos
into [lib://Fonte de Dados/Produtos.csv] (txt, delimiter is ',');
Ao incluir um comando Store, nenhuma alteração pode ser notada na sua aplicação e também
que nenhuma nova tabela ou campo passou a existir.
O comando adicionado ao script não tem um efeito além de executar mais um comando.
Uma vez que esse script é executado, um novo arquivo de dados pode ser lido para a nossa
aplicação ou mesmo qualquer outra aplicação com acesso à pasta onde está armazenado o
arquivo.
Para fazer a carga de um arquivo QVD, basta arrastar ele para a aplicação ou qualquer outra
forma válida de carga de arquivos de dados na aplicação.
Criação Automática a partir do Script
Os arquivos QVD podem ser criados e mantidos automaticamente usando o prefixo buffer.
Esse prefixo pode ser usado com a maioria dos comandos Load e/ou Select no script. Ele indica
se um arquivo QVD será usado para armazenar em cache/buffer o resultado do comando.
O nome atribuído ao arquivo QVD é calculado e normalmente armazenado em:
C:\ProgramData\Qlik\Sense\Engine\Buffers
(Instalação do servidor)
ou
C:\Users\%username%\Documents\Qlik\Sense\Buffers
(Qlik Sense Desktop)
Sintaxe:
Buffer [(option [ , option])] ( loadstatement | selectstatement )
option::= incremental | stale [after] amount [(days | hours)]
Vamos agora revisar o comando de carga da tabela Clientes para usar o método automático de
geração de arquivo QVD.
Sabemos pelo nosso plano de projeto que os dados da tabela Clientes é atualizada
semanalmente, então temos necessidade de ler e atualizar os dados a cada sete dias.
Vamos modificar então o nosso script de carga para adicionar o prefixo buffer ao nosso
comando original de carga para Clientes.
Agora adicione o prefixo Buffer (Stale After 7 Days) ao comando de carga para Clientes similar
ao exemplo a cima.
Nesta lição você aprendeu a utilizar Arquivos QVD e QVW, que é um poderoso recurso dos
produtos da Qlik. Você entendeu também os benefícios e as diferentes técnicas de trabalhar
com QVD.
Vamos exercitar! Realize as atividades referentes à Lição 9.
Lição 10 - Variáveis
Objetivo da Lição
Nesta lição, você vai aprender a:
• Conhecer os benefícios do uso de variáveis nas aplicações Qlik.
Uso de Variáveis
É importante conceber seus scripts de carga para que sejam flexíveis e simples de manter.
Uma das formas de se alcançar esse objetivo é o uso de variáveis.
Podem ser atribuídas com uma constante (número ou texto), ou pode ser atribuído um valor
através de uma expressão.
Utilize o comando Set para atribuir um valor diretamente, e o comando Let para atribuir um
valor através de uma expressão.
A utilização de nomes de variáveis únicas e que permitam uma fácil identificação também é
considerada uma boa prática.
Variáveis definidas no script de carga estão disponíveis na interface para o usuário. Neste caso,
vamos atribuir um valor ao ano.
Siga os passos:
• Na primeira seção do script, geralmente com o nome de Main, inclua o código
abaixo, preferencialmente na última linha dessa seção (É uma boa prática usar
essa seção apenas para definições de variáveis).
SET vAnoCarga = 2007;
Será alimentado o valor de vAnoCarga quando for executado. Neste caso, o valor
será 2007.
• Não deverá haver modificações nos valores dos campos após essa nova versão do
script ser executada.
Em vez de exigir uma alteração todos os anos para manter esse script, você pode definir um
valor para a variável usando a data de sistema para alimentar esse valor.
Já que essa atribuição irá requerer uma expressão, devemos modificar o nosso comando Set
por um comando Let.
• Modifique o comando que define a variável vAnoCarga para o comando Let
conforme abaixo.
LET vAnoCarga = Year(Today())-4;
Nesta lição você conheceu e aprendeu a aplicar o uso de variáveis. Lembre-se, em caso de
dúvidas retome o conteúdo, para depois seguir seu estudo com tranquilidade.
Lição 11 - Concatenação
Objetivo da Lição
Nesta lição, você vai aprender a:
• Conhecer esse poderoso recurso de união de dados, verificando os casos onde a
concatenação se dará automaticamente.
• Forçar ou prevenir (evitar) a concatenação.
Concatenação Automática
Se os nomes e o número de campos das duas tabelas são exatamente iguais,
automaticamente, será concatenado o resultado dos diferentes comandos Load ou Select em
uma tabela.
Exemplos:
LOAD a, b, c from table1.csv;
LOAD a, c, b from table2.csv;
LOAD c, b, a from table3.csv;
A tabela lógica resultante terá os campos a, b e c.
O número de registros é a somatória do número de registros da tabela 1, tabela 2 e tabela 3.
Tabela resultante
A B C
A1 B1 C1
A2 B2 C2
A3 B3 C3
A10 B10 C10
A11 B11 C11
Observe que o rótulo da tabela resultante será o mesmo da primeira tabela lida.
Importante:
• A quantidade e os nomes dos campos devem ser exatamente os mesmos.
• Independente da ordem dos dois comandos e dos campos, o resultado será o
mesmo.
Concatenação Forçada
Mesmo se duas ou mais tabelas não tenham exatamente o mesmo conjunto de campos, ainda
será possível forçar a concatenação das duas tabelas. Isso é feito usando o prefixo concatenate
no script, que concatena uma tabela a outra nomeada ou à última tabela lógica criada
anteriormente.
Exemplo 1:
LOAD a, b, c from table1.csv;
Concatenate LOAD a, c from table2.csv;
Concatenate LOAD b, a from table3.csv;
A tabela lógica resultante tem os campos a, b e c.
O número de registros na tabela resultante é a soma do número de registros na tabela 1,
tabela 2 e na tabela 3.
O valor do campo b nos registros vindos da tabela 2 e o do campo c na tabela 3 é NULL.
Tabela resultante
A B C
A1 B1 C1
A2 B2 C2
A3 B3 C3
A10 - C10
A11 - C11
Importante:
• A quantidade e os nomes dos campos podem ser diferentes.
• A menos que o nome de uma tabela carregada anteriormente seja especificado no
comando concatenate, o prefixo concatenate utilizará a última tabela criada
anteriormente.
• Dessa forma, a ordem dos dois comandos é muito importante.
Prevenir Concatenação
Se duas tabelas têm o mesmo conjunto de campos, isso levaria a que elas fossem
automaticamente concatenadas.
Podemos prevenir essa situação com o prefixo Noconcatenate.
A utilização desse recurso previne a concatenação de qualquer tabela lógica com o mesmo
conjunto de campos:
Sintaxe:
NoConcatenate( loadstatement | selectstatement )
Exemplo:
LOAD a, b, c from table1.csv;
NoConcatenate LOAD a, c, b from table2.csv;
NoConcatenate LOAD c, b, a from table3.csv;
Será gerada três tabelas interna resultante com os campos a, b e c.
O número de registros será correspondente a origem em cada tabela.
Será gerada uma chave sintética entre as três tabelas, ou seja, haverá quatro tabelas no
modelo de dados
Importante:
• A quantidade e os nomes dos campos devem ser exatamente os mesmos, se
forem diferentes não há o que ser evitado, logo o NoConcatenate não deve ser
usado.
• A concatenação será evitada independentemente de onde a definição da tabela
carregada anteriormente esteja.
• Dessa forma, a ordem dos dois comandos é muito importante.
Concatenação na prática
Nos nossos dados, temos disponível um conjunto adicional de colaboradores que não existiam
no arquivo FuncionariosEscritorios.xls.
Para inserir esses dados, vamos modificar nosso script de carga. Siga os passos:
• Localize o script de carga onde fizemos a carga da planilha Funcionários do arquivo
do Excel FuncionariosEscritorios.xls.
• Modifique a cláusula From conforme abaixo.
[Funcionarios$]:
LOAD [FuncID] AS [FuncionarioID],
[Sobrenome],
[Primeiro Nome],
[Titulo],
[Data Admissao],
[Escritorio],
[Ramal],
[Reporta a],
[Salario Anual]
FROM [lib://Fonte de Dados/Funcionarios*.xls]
(biff, embedded labels, table is Funcionarios$);
• Carregue os dados e observe no visualizador de tabelas, que como os dados
tinham exatamente a mesma estrutura, as duas tabelas foram automaticamente
concatenadas, mesmo estando em pastas de trabalho diferentes.
Nesta lição você conheceu a concatenação e verificou os casos onde ela se dará
automaticamente. Aprendeu também a forçar ou prevenir (evitar) a concatenação. Está tudo
certo até aqui? Vamos prosseguir.
Vamos praticar? Realize as atividades referentes à Lição 11.
Laboratório 11 - Concatenação
1. Crie uma nova aplicação e dê o nome de Concatenação.
a. Abra o Excel, LibreOffice ou Google Docs, como preferir, e crie um arquivo
Produtos1.xls com os seguintes dados:
Código Nome Categoria Valor
1 Arroz Alimento 4
2 Feijão Alimento 5
3 Camisa Vestuário 20
b. Altere os dados conforme abaixo e salve como Produtos2.xls.
Código Nome Categoria Valor
4 Bermuda Vestuário 10
5 Macarrão Alimento 3
6 Sapato Calçados 30
c. Altere os dados conforme abaixo e salve como Produtos3.xls.
Código Nome Valor
7 Refrigerante 4
8 Cerveja 200
9 Picanha 5
* Observe que este último arquivo está sem a coluna Categoria.
Depuração
Você pode usar os utilitários de depuração no editor de script de carga para percorrer a
execução do seu script usando pontos de interrupção, podendo assim inspecionar os valores,
variáveis e a saída da execução do script.
É possível selecionar se você deseja ver uma ou todas as Saídas, Variáveis e Pontos de
interrupção.
Importante:
Você não pode criar conexões, editar conexões, selecionar dados, salvar o script ou
carregar dados enquanto estiver executando no modo de depuração, isto é, desde
quando começou a execução da depuração até que o script seja executado ou a
execução termine.
Para entrar no modo de depuração, basta clicar no ícone que está ao lado direito, Mostrar
Painel de Depuração.
3 1 2
5 6 7
A imagem mostra ao centro o script (1).
A posição da execução é marcada por uma linha laranja (2).
É possível definir pontos de interrupção clicando no número da linha, à esquerda de um
comando (3).
Após clicar no número da linha, o ponto de interrupção é marcado por um o ícone laranja (3).
Um quadrado sobre o script (4) mostra o comando que está prestes a ser executado no modo
incremento ou que está sendo executado no modo executar.
A aba Saída (5) mostra o status e possíveis mensagens de erro, basicamente as mesmas
informações que no diálogo de progresso do script.
A aba Variáveis (6) mostra todas as variáveis e respectivos valores, as variáveis alteradas são
mostradas em ordem de alteração da mais recente a mais antiga mudança.
A aba Pontos de Interrupção (7) mostra todas as pausas incluídas no script, suas respectivas
seções e opções de desativar ou excluir os pontos.
A depuração pode ser executada de forma incremental, direta ou interrompida a qualquer
momento.
Nesta lição, você conheceu os recursos do Depurador de Script, para saber utilizá-lo para
localizar problemas no script.
Hora de atividade! Realize as atividades referentes à Lição 13.
Laboratório 13 - Depurar
1. Usando a imagem a cima, que mostra a tela de depuração, preencha corretamente
as opções abaixo com os números possíveis.
) Exibe todas as variáveis e respectivos valores.
) Ao clicar no número da linha, é criado um ponto de interrupção.
) Script de carga de dados.
) Exibe o status e possíveis mensagens de erros.
) Exibe todos os pontos de interrupção com opções de desativar ou
remover o ponto.
Gabarito dos Laboratórios
Lição 1 - Plano de Projeto
2. Um plano de projeto é um documento guia com a finalidade de orientar o caminho a ser seguido
durante o curso para alcançar um objetivo.
3. C, A, D, E, G, D, B.
Lição 11 - Concatenação
2. Concatenação forçada.
Lição 12 - Depuração
1. 6; 3; 1; 5; 7.