Relatórios no Maker – 2
26/08/2011 Deixe um comentário
Neste post darei continuidade ao post anterior sobre criação de relatórios no Maker. Abordarei aqui a criação de filtros e o uso de sub-relatórios. No RB10 o mecanismo de filtros é um pouco diferente do mecanismo de filtro do RB7, agora é possível criar filtros com mais liberdade, apesar de, às vezes, isso requerer mais trabalho por parte do desenvolvedor. Já a funcionalidade de sub-relatórios não mudou muito, de qualquer forma, irei mostrar como utilizá-la no RB10.
Criando Filtros no RB10
Criar um filtro para um relatório no Maker não é nada mais do que definir uma consulta SQL, se você possui uma query que roda corretamente no SGBD ou no Executor de Scripts do Maker, essa mesma query poderá ser criada no construtor de consultas. Cada campo no seu where que terá que ser informado pelo usuário deverá ser convertido em um parâmetro no construtor de consultas SQL do RB10.
Para definir um parâmetro na consulta SQL dentro do RB10 é utilizada a seguinte convenção: dois pontos + nome do parâmetro. Ex: ‘:codigoDoPedido’. Um parâmetro pode ser de três tipos: Caixa de Texto, Data e Lista Dinâmica. O Tipo de Caixa de Texto é utilizado quando o usuário irá digitar qualquer valor para realizar o filtro, letras ou número, o tipo Data exibe uma caixa de texto e um ícone para seleção visual da data em um calendário, e o tipo Lista Dinâmica define uma lista na qual o usuário irá buscar o registro que servirá de filtro para a geração do relatório. O parâmetro possui um Título, que será exibido para o usuário e um Valor Padrão. Além disso, cada parâmetro pode ser marcado como: 1) Requerido, o parâmetro não pode ser passado em branco; 2) Somente Leitura, o parâmetro não é modificado pelo usuário; 3) Oculto, o parâmetro não é exibido para o usuário. Se o parâmetro for Somente Leitura ou Oculto, ele deverá possuir valor padrão ou receber seu valor da tela ou do fluxo chamador, caso contrário permanecerá nulo. Nesta parte do post vou falar sobre os tipos de filtros mais comuns e como fazê-los utilizando os parâmetros citados.
Filtro Simples com um Campo
Este é o tipo de filtro mais comum, no exemplo da Figura 1, temos um cadastro de Pedido de Venda e queremos invocar o relatório em questão a partir do formulário do pedido, portanto precisamos filtrar o relatório pelo código do pedido.
Para isto definimos o parâmetro ‘:codigoDoPedido’ na coluna ‘Critério’ da consulta SQL. Feito isto, é possível definir como este parâmetro será apresentado ao usuário, clicando no botão Parâmetros, indicado na Figura 2-a. No caso do nosso exemplo, vamos definir um parâmetro do Tipo Lista dinâmica e preencher o título com: ‘Selecione o Pedido’, a consulta que irá popular esta lista dinâmica é apenas uma seleção da coluna código da tabela de pedidos, como mostra a Figura 2-b. Na figura 2-c, é possível visualizar a chamada ao relatório no menu do webrun e o resultado de sua visualização com o filtro efetuado.

Figura 2 – Relatório Pedido de Venda. a) Definição do parâmetro; b) Configuração do parâmetro; c) Resultado da geração do relatório.
Filtro do Formulário para o Relatório
Este filtro é útil quando se deseja que o usuário possa emitir um relatório ao navegar entre os registros de uma tela e que este relatório saia filtrado com o registro no qual a tela está posicionada. Esta é uma funcionalidade nativa do webrun, sempre um relatório é invocado a partir de um formulário e, este relatório possui parâmetros com os mesmos nomes de campos da consulta do formulário, a passagem de parâmetro automática é realizada, e quando a tela de pré-visualização do relatório é exibida, os parâmetros em questão nem são mais exibidos para o usuário. Na figura 3-a, o relatório do item anterior foi chamado a partir da tela correspondente, como era de se esperar, o filtro não foi preenchido automaticamente, pois o nome do parâmetro definido foi ‘:codigoDoPedido’, se mudarmos o nome deste parâmetro para ‘:COD_PEDIDO’, mesmo nome do campo na tela, podemos conferir que o parâmetro foi passado automaticamente, como mostra a Figura 3-b.
Filtro com Datas
Este é um tipo de filtro bastante comum, é utilizado quando se deseja que o usuário filtre os dados por um período de datas, a princípio este parece ser um filtro como o que foi explicado no item “Filtro Simples com um Campo” deste post, mas, vamos ver que temos que ter algumas preocupações na criação desse tipo de filtro. Vamos tomar como exemplo aqui um relatório de Resumo dos Pedidos, este relatório irá exibir os Pedidos de Venda sem os itens, listando apenas a data de emissão, total e quantidade de itens. Vamos supor que para este relatório foi pedido um filtro pela data de emissão. Este filtro ficaria como mostra a figura 4-a. Olhando o código SQL desta consulta pode-se ver que o que se deseja fazer aqui não é nada além de uma simples consulta SQL com where: select cod_pedido, {…} from exe_pedido_venda where ped_data_emissao >=:inicio and <=:fim. Este filtro funciona, porém, se o campo ‘ped_data_emissao’ for armazenado com data e hora alguns registros podem ficar de fora, por exemplo. Supondo que um registro tenha data de cadastro igual a 26/08/2011 15:54, e eu tenha emitido o relatório passando como filtro: Início=25/08/2011; Fim=26/08/2011, este registro não será listado, pois quando eu não preencho a hora no relatório, o componente data entende que o horário é 00:00:00, e como 26/08/2011 00:00:00 é anterior a 26/08/2011 15:54, este registro estaria fora do período definido pelo usuário e isto pode ser indesejável caso a hora da venda não seja relevante. Para resolver essa questão basta converter o campo data que será comparado para um formato sem hora, como mostra a figura 4-b, para o banco de dados SQL Server 2005.
O filtro com datas pode ainda ter outras características, por exemplo, pode ser desejável que, se o parâmetro fim for deixado em branco o relatório deve exibir todos os registros a partir do campo início. Neste cenário, o campo início deverá ser marcado como obrigatório e o campo fim como opcional. Além disso, na própria consulta deverá ser criado um mecanismo para atender esse requisito, neste caso o seguinte comando na coluna critério resolve o problema: >=:inicio and (<=:fim or :fim is null). Este comando realiza o filtro do parâmetro início obrigatoriamente, mas, o parâmetro fim só é checado se ele possuir valor, caso não possua, seu valor é ignorado, vide Figura 4-c. Esta forma de criar o filtro é útil para qualquer parâmetro que seja opcional, não só para datas. Utilizando esse mecanismo é possível criar um filtro entre datas ainda mais versátil, um filtro onde, se o início for preenchido e o fim estiver nulo, o filtro é efetuado a partir do início, se o fim estiver preenchido e o início estiver nulo, os registros são filtrados até o fim, e, se ambos estiverem nulos, todos os registros são exibidos. O seguinte trecho de código realiza este filtro: (>=:inicio or :inicio is null) and (<=:fim or :fim is null), como mostra a Figura 4-d.
Utilizando a funcionalidade Sub-Relatório
O uso de sub-relatórios é necessário quando um relatório precisa exibir um conjunto de registros dentro de uma única faixa do relatório principal. É possível criar sub-relatórios de forma aninhada, e utilizar tantos quantos forem necessários para chegar ao resultado desejado em tela. O que precisa ser observado quanto ao uso de sub-relatórios é a definição da consulta, cada sub-relatório deve ter uma fonte de dados associada, que por sua vez pode ter ligação com a fonte de dados principal. Para exemplificar o que foi dito vamos tomar como base o relatório Pedido de Venda citado anteriormente, vamos supor que para cada produto listado neste relatório seja necessário listar as informações nutricionais do mesmo. Para isto, vamos utilizar um sub-relatório. O primeiro passo é definir outra consulta que irá retornar os registros das informações nutricionais por produto, esta consulta deverá ter o código do produto para que a associação com o produto da consulta principal seja feita, como mostra a figura 5-a. Após definir a consulta, basta adicionar um componente sub-relatório, que uma nova guia irá aparecer no rodapé da página, como está indicado na figura 5-b. Ao clicar nessa guia, é possível definir o conteúdo do sub-relatório, a primeira ação a ser feita é definir a fonte de dados da consulta clicando em Relatório->Dados e escolher o condutor de dados. Caso não haja mudança no nome da consulta, o RB10 irá criar os nomes de forma seqüencial: consulta, consulta1, consulta2, etc. É possível alterar esse nome na aba consulta da tela da consulta SQL. Feito isto, é possível definir o conteúdo do sub-relatório, que é um relatório completamente novo, podendo conter grupos e outras sub-consultas. Na figura 5-c é possível visualizar o resultado do relatório com sub-relatório.
Perceba que na situação do relatório explicada acima é possível resolver o problema utilizando uma única consulta e a funcionalidade de Grupos (veja este post), pois, agrupando os dados por produto, é possível colocar na faixa detalhes os registros dos valores nutricionais. Porém, existem situações onde a utilização de sub-relatórios é a única solução, vamos supor que seja necessário adicionar ao sumário do relatório anterior as faturas geradas pelo pedido. Neste caso, somente um sub-relatório atende a este requisito, pois, se tentássemos utilizar grupos a consulta iria retornar dados incorretos, pois para cada fatura existente os itens seriam replicados. Portanto, para resolver este problema bastaria criar uma nova consulta e criar um sub-relatório na faixa sumário. Salvo os casos onde o uso de sub-relatório é obrigatório, cabe ao desenvolvedor avaliar quando utilizar grupos ou sub-relatórios, em consultas complexas, que necessite de 5 ou mais grupos, talvez seja interessante fragmentar a consulta utilizando um sub-relatório para facilitar a visualização e manutenção.
Conclusão
O uso de filtros e sub-relatórios, brevemente exemplificados neste post, juntamente com as funcionalidades de agrupamento citadas no post anterior consistem nas principais funcionalidades para a criação de relatórios no Maker utilizando o RB10. De posse destes conhecimentos e com um pouco de mão na massa, é possível criar relatórios com uma maior complexidade e, conseqüentemente, mais úteis.









































