Acumulado com Expressão

Fala pessoal! Tudo beleza?
 
Certamente vocês já fizeram algum relatório de Contabilidade e foi solicitado um indicador que possui os valores acumulados mês a mês, seja de Saldo, Lucro, etc.
 
Sabemos que a maioria dos gráficos possuem a função de acumular na aba de expressões, mas nem sempre esse acumulado vai atender a nossa demanda.
  
Gráficos que possuem a função de acumular: Barra, Linha, Combinado, Radar, Mekko, Dispersão, Grade e Table Simples.
 
Gráficos que não possuem a função de acumular: Mostrador, Tabela Dinâmica, Pizza, Funil e Blocos.
   
Imagine um cenário em que temos: um gráfico de tabela simples com o valor de REALIZADO e o valor de META. Precisamos agora criar mais três colunas: Realizado Acumulado, Meta Acumulada e % de Realizado em relação a meta.
 
Tranquilo! Gráfico de tabela simples possui a função de acumular a expressão por padrão.
  
Primeira expressão: Realizado Acumulado!
 
SUM(VALOR)
 
Marco Acumular, já era uma. 😀
  
Segunda expressão: Meta Acumulada!
 
SUM(META)
 
Marco Acumular, já era duas!
  
Terceira expressão: %!
 
Vou apenas reaproveitar as expressões…
  
[Realizado Acum.]/[Meta Acum.]
 
Pronto! Terminei!
   
Apenas verifico os valores só para ter certeza que não fiz nada errado
   
Jan/2015
Realizado Acum = 100
Meta Acum =  110
Percentual = 100/110 = 90,91%
Qlikview = 90,91% BOA!

   
Fev/2015
Realizado Acum = 220
Meta Acum =  240
Percentual = 220/240= 91,66%
Qlikview = 92,31% UÉ!
  
Bom, acho que preciso marcar o acumulado na expressão do percentual também!
 
Qlikview = 183,22%
 
NÃO É POSSÍVEL!
  
Deve ser algum erro de casa decimal (RSRSRS Eu sempre penso isso kkk!!!)
 
Refaço as contas e realmente não é erro de casa decimal.
 
Removo o acumulado das expressões: Realizado Acum e Meta Acum, e refaço o cálculo do percentual
  
Fev/2015
Realizado Acum = 120
Meta Acum =  130
Percentual = 120/130= 92,31%
  
Não acredito, o qlikview não consegue reutilizar a expressão com o acumulado. Afff! E agora?
  
Bom! Teremos então que investigar algumas funções que possam obter o mesmo resultado do acumulado do QlikView.
   

Funções

Hoje trabalharemos com as funções Funções Inter-Registro de Gráficos, são elas:
 
Above() = Acima – Retorna o valor da expressão avaliada com os valores de dimensão do gráfico da forma como aparecem na linha acima da atual em um segmento de coluna de uma tabela.
 
Below()Abaixo – Retorna o valor da expressão avaliado com os valores de dimensão do gráfico que aparecem na linha abaixo da atual dentro de um segmento de coluna em uma tabela.
 
Before() = Antes – Retorna o valor da expressão avaliada com os valores de dimensão de uma tabela dinâmica como aparecerem na coluna antes da atual.
 
After() = Depois – Retorna o valor da expressão avaliada com os valores de dimensão de uma tabela dinâmica como aparecerem na coluna depois da atual.
   

Características das funções

  • Na primeira coluna de um segmento de linha, um valor NULL será retornado, já que não há uma coluna
    antes dela.
  • Se a tabela for unidimensional ou se a expressão for precedida pelo qualificador total, o segmento de linha
    atual será sempre igual à linha inteira.
  • Especificar um deslocamento maior que 1 permite que você transfira a avaliação da expressão para essa outra coluna, por exemplo: Se usar para a função Before, então estará avaliando colunas a esquerda em relação a atual coluna.
  • Um número de deslocamento negativo tornará a função o seu inverso, por exemplo a função before ficará equivalente a função after.
  • A especificação de um deslocamento igual a 0 avaliará a expressão da coluna atual.
  • Ao especificar um terceiro parâmetro n maior que 1, a função retornará não um, mas uma série de valores n,
    um para cada n colunas da tabela. Dessa forma, a função pode ser usada como um argumento para qualquer uma das Funções de Intervalo de Gráfico especiais.

  
A parte acima grifada é muito importante, pois como queremos trabalhar com valores acumulados, então teremos que pegar o valor da linha/coluna atual e somar com o de linha(s)/coluna(s) anterior(es) e isso nos obriga a utilizar essas funções de intervalo de gráfico especiais.
  
Essas funções são precedidas da palavra Range, então temos: RangeSum, RangeAvg, RangeCount, RangeMin, RangeMax…. por aí vai.
  
IMPORTANTE: Essas funções de Range servirão para somar os resultados das funções Inter-Registros. Lembre-se que essas funções Inter-Registros retornaram vários resultados e é por isso que teremos que utilizar as funções de Range. Se tentássemos utilizar somente um SUM, o Qlikview retornaria nulo.
   

Exemplo

No exemplo em que vou comentar, estarei utilizando um gráfico de tabela simples com a dimensão MêsAno e suas respectivas expressões.
 
Se estamos trabalhando com um gráfico de tabela simples, então utilizaremos a função Inter-Registro Above(), pois o resultado do mês anterior esta na linha acima, desde que o gráfico esteja ordenado de forma Crescente.
 
Lembrando: Queremos acumular desde o primeiro MêsAno disponível nos filtros.
  
Expressão de Realizado: RangeSum(Above(SUM(VALOR), 0, RowNo()))
 
Vamos entender os parâmetros do Above
 
Deslocamento é zero, ou seja, estou avaliando a expressão da linha atual
 
N = RowNo() [RowNo() retorna o número da linha do gráfico]
 
Se estamos na primeira linha do gráfico, então a expressão estará da seguinte forma: RangeSum(Above(SUM(VALOR), 0, 1)), ou seja, estamos analisando somente a linha atual. Para a expressão RangeSum estamos somando o intervalo da linha atual até a linha atual.
 
Se estamos na segunda linha do gráfico, então a expressão estará da seguinte forma: RangeSum(Above(SUM(VALOR), 0, 2)), ou seja, estamos analisando a linha atual  e a linha anterior. Para a expressão RangeSum estamos somando o intervalo da linha atual até a linha anterior.
 
Se estamos na terceira linha do gráfico, então a expressão estará da seguinte forma: RangeSum(Above(SUM(VALOR), 0, 3)), ou seja, estamos analisando a linha atual  e duas linhas anteriores. Para a expressão RangeSum estamos somando o intervalo da linha atual até duas linhas anteriores.
  
Expressão de Meta: RangeSum(Above(SUM(META), 0, RowNo()))
 
A regra se mantém a mesma para a meta.
 
Agora o percentual fica fácil:
 
RangeSum(Above(SUM(VALOR), 0, RowNo())) / RangeSum(Above(SUM(META), 0, RowNo()))
 
Agora teremos o seguinte resultado
  
Grafico01
  
Muito bom!
   

Fique Atento

Lembre-se de escolher corretamente a expressão Inter-Registro a ser utilizada, se estiver em uma tabela dinâmica, com o MêsAno pivoteado, então temos que pegar o resultado da COLUNA ANTERIOR, para isso devemos utilizar a função Before().
 
Abaixo disponibilizei uma aplicação com um exemplo na tabela dinâmica e como acumular somente alguns passos, por exemplo: Somente 1 mês anterior ou somente dois meses anteriores.
 
Para fazer download da aplicação de exemplo clique aqui!
   

Conclusão

Se o que você deseja fazer o QlikView oferece, então utilize! Sempre as funções prontas do QlikView oferecem melhor performance, mas nem tudo o QlikView nos oferece de “mão beijada”, desta forma é bom estarmos preparados para essas ocasiões.
 
Até a próxima semana!

Anúncios

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!

 

Função para Criar Calendário (Utilizando Data existente no modelo)

Fala pessoal, tudo beleza?

No último post aprendemos a utilizar uma função para criação de calendário passando uma data início e data fim, hoje aprenderemos como verificar esse range através de um campo existente em nosso modelo.

Para fazer isso utilizaremos três funções: FieldValue, FieldValueCount e While.

  • FieldValue para retornar um valor do campo de data do modelo. Lembrando que sempre será retornado apenas um valor, para o nosso caso resolve, pois utilizaremos essa função junto com as funções MAX e MIN.
  • FieldValueCount utilizaremos para percorrer todos os possíveis valores do campo de data do modelo. Lembrando que a função retorna o número de valores distintos do campo escolhido.
  • While para criar todos os registro no intervalo entre a maior e menor data do modelo.

Vamos ao código:

SUB CriaCalendario(vCampoData,vNomeCalendario,vPrefixoCalendario,vCampoChave)

LET vNomeCalendario = If(Len(‘$(vNomeCalendario)’)=0,’Calendario’,’$(vNomeCalendario)’);
LET vPrefixoCalendario = If(Len(‘$(vPrefixoCalendario)’)=0,”,’$(vPrefixoCalendario)’);
LET vCampoChave = PurgeChar(vCampoChave,'”[]’);

[$(vNomeCalendario)]:
LOAD
Distinct
Data_ as [$(vCampoChave)],
Date(Data_, ‘$(DateFormat)’ ) as [$(vPrefixoCalendario)Data],
Year(Data_) as [$(vPrefixoCalendario)Ano],
Month(Data_) as [$(vPrefixoCalendario)Mes],
Day(Data_) as [$(vPrefixoCalendario)Dia],
Date(MonthStart(Data_), ‘MMM/YYYY’) as [$(vPrefixoCalendario)MesAno];
LOAD
Date(_DataInicio+(Iterno()-1),’$(DateFormat)’ ) as Data_
WHILE (_DataInicio+(Iterno()-1)<=_DataFim); //Regra para gerar todos os registro do intervalo
LOAD
Floor(Min(Fieldvalue(‘$(vCampoData)’,RecNo()))) as _DataInicio, //Função utilizada para buscar valor do campo data do modelo.
Floor(Max(Fieldvalue(‘$(vCampoData)’,RecNo()))) as _DataFim
AUTOGENERATE FieldValueCount(‘$(vCampoData)’); //Função necessária para passar por todos os registros possíveis do campo data do modelo.

ENDSUB;

 
 
OBSERVAÇÃO: É necessário utilizar o FieldValueCount no AutoGenerate, pois precisamos passar por todos os possíveis valores do campo da data. Caso você não utilize, pode ser que o Min e o Max sejam alterados.

 

Pronto, agora basta utilizar a função Call e passar os parâmetros para que o calendário seja criado, conforme exemplo abaixo:

Call CriaCalendario(‘DATA’,’Calendario’,”,’%ChaveData’);

Neste exemplo o calendário será criado com o intervalo entre o intervalo de datas do campo DATA (esse campo esta localizado na tabela Tabela_Fato do exemplo), o nome da tabela será “Calendario”, nenhum prefixo de campos será utilizado e o campo de chave com a minha modelagem é “%ChaveData”.

Para fazer o download da aplicação de exemplo, basta clicar aqui!

 

Por enquanto é isso pessoal!

Semana que vem abordaremos outro assunto!

Função para Criar Calendário (Passando datas)

Fala pessoal!

 

Na maioria dos projetos em que iremos trabalhar é preciso criar um calendário para poder trabalhar com as datas de forma organizada (ainda não vou falar sobre um calendário principal, esse assunto vai ficar para um próximo post). Na maioria dos casos sempre opto por criar uma tabela de Calendário e trabalhar as datas nessa tabela, pois sempre tento organizar todas as datas necessárias para o projeto em uma única tabela (quando possível rsrs).

 

Hoje quero repassar para vocês uma função que utilizo para criar um calendário de uma forma com alta performance. Função? Sim, eu crio uma classe de função de script e depois utilizo uma linha passando os parâmetros necessários para criar o calendário.

 

Vamos entender um pouco mais sobre essas funções de script através do manual do QlikView:

O comando de controle sub e end sub define uma sub-rotina que pode ser chamada a partir de um comando call.

A sintaxe é:
sub nome [ ( listadeparâmetros )] comandos end sub

Onde:

  • name é o nome da sub-rotina.
  • listadeparâmetros é uma lista, separada por vírgulas, de nomes de variáveis para os parâmetros formais da subrotina. Eles podem ser usados como qualquer variável dentro da sub-rotina.
  • comandos são qualquer grupo de um ou mais comandos de script do QlikView.

 

Os argumentos são copiados na sub-rotina e, se os parâmetros reais correspondentes no comando call for o nome de uma variável, serão copiados novamente após a saída da sub-rotina.
Se uma sub-rotina tiver mais parâmetros formais que os parâmetros reais transmitidos por um comando call, os parâmetros extra serão inicializados como NULL e poderão ser utilizados como variáveis locais na subrotina.
Como o comando sub é um comando de controle e, por isso, termina com um ponto-e-vírgula ou com um fim de linha, cada uma de suas duas cláusulas (sub e end sub) não deve cruzar um limite de linha.

 

Agora vamos ao exemplo prático! No final do post existe um link para download de uma aplicação de exemplo 🙂

 
———————————————————————————————————–
 
 

Em primeiro lugar, cria um aba em seu script chamada Sub CriaCalendario nesta aba criaremos a função para criar o calendário. Segue agora o script:

 

/* Nome da função é CriaCalendario e esta recebe cinco parâmetros, são eles:

vDataInicio = Data de Início do seu relatório. O formato a ser passado pode seguir o modelo da formatação de data local, por exemplo DD/MM/YYYY.

vDataFim = Data de término do seu relatório. O formato a ser passado pode seguir o modelo da formatação de data local, por exemplo DD/MM/YYYY.

vNomeCalendario = Nome que receberá a tabela do seu calendário, caso nenhum seja digitado, então o nome Calendario será utilizado.

vPrefixoCalendario = Conjunto de caracteres que precederá todos os nomes de campos da tabela de calendário. Exemplo: “Calendario.”, então todos os campos possuirão o “Calendario.” antes do nome do campo da tabela. Caso nada seja utilizado, então nenhum prefixo será utilizado.

vCampoChave = Nome do campo que será chave entre a tabela de calendário e o seu modelo. Note que esse campo deve ser uma data completa, com dia, mês e ano.

*/

SUB CriaCalendario(vDataInicio,vDataFim,vNomeCalendario,vPrefixoCalendario,vCampoChave)

/* Algumas tratativas com os valores recebidos – Lembre-se que esses valores sempre serão tratados como variáveis. */
LET vNomeCalendario = If(Len(‘$(vNomeCalendario)’)=0,’Calendario’,’$(vNomeCalendario)’);
LET vPrefixoCalendario = If(Len(‘$(vPrefixoCalendario)’)=0,”,’$(vPrefixoCalendario)’);
LET vCampoChave = PurgeChar(vCampoChave,'”[]’);
/* Criação do calendário */
[“$(vNomeCalendario)”]:
LOAD
Distinct
Data_ as [$(vCampoChave)],
Date(Data_, ‘$(DateFormat)’ ) as [$(vPrefixoCalendario)Data],
Year(Data_) as [$(vPrefixoCalendario)Ano],
Month(Data_) as [$(vPrefixoCalendario)Mes],
Day(Data_) as [$(vPrefixoCalendario)Dia],
Date(MonthStart(Data_), ‘MMM/YYYY’) as [$(vPrefixoCalendario)MesAno];

LOAD
Date(‘$(vDataInicio)’+(Iterno()-1),’$(DateFormat)’ ) as Data_
AutoGenerate 1 While (Num(‘$(vDataInicio)’)+(Iterno()-1)<= Num(‘$(vDataFim)’));

/* Finalizando a função */
ENDSUB;

 

Pronto, agora basta utilizar a função Call e passar os parâmetros para que o calendário seja criado, conforme exemplo abaixo:

Call CriaCalendario(’01/01/2015′,’08/03/2015′,’Calendario’,”,’%ChaveData’);

 

Neste exemplo o calendário será criado com o intervalo entre 01/01/2015 e 08/03/2015, o nome da tabela será “Calendario”, nenhum prefixo de campos será utilizado e o campo de chave com a minha modelagem é “%ChaveData”.

 

IMPORTANTE: É necessário passar um valor para cada argumento criado na função, por esta razão passei um vazio para o argumento de número quatro que é o prefixo dos campos, caso contrário a função não executará corretamente.

 

Fiquem a vontade para editar e modelar da forma que preferirem para encaixar em seu modelo.

Para a próxima semana vou demonstrar como criar um calendário utilizando um intervalo de datas através de um campo de uma tabela.

 

Deixo aqui uma aplicação de exemplo para download.

 

Até a próxima semana!