====== Tutorial Report Manager ====== O Report Manager é um gerador de relatórios open source e será o novo gerador de relatórios oficial da KS Sistemas. Este tutorial tem o objetivo de fazer uma introdução aos conceitos e recursos utilizados na construção de relatórios utilizando esta poderosa ferramenta. Esse guia irá te auxiliar a montar um relatório no Report Manager com exercícios práticos. A documentação oficial do Report Manager pode ser encontrada em: http://reportman.sourceforge.net/doc/ ===== Tela ===== {{:report_manager_img01.png|}} - Menu: Contém todas as funcionalidades do Report Manager - Atalhos: Atalhos para as principais funcionalidades. - Régua: Determina o tamanho horizontal e vertical do seu relatório - Relatório: É onde é montado o relatório. Os objetos são inseridos nessa parte. - Estrutura / Dados: É onde é configurada a estrutura e os dados do relatório. - Propriedades: São as propriedades do objeto selecionado em Estrutura / Dados. ===== Conexão com o Banco de Dados ===== O Report Manager pode estabelecer conexão com praticamente todos os bancos de dados existentes, permitindo inclusive estabelecer conexões simultâneas com bancos diferentes através de algumas configurações que serão apresentadas a seguir: Para iniciar, um novo relatório, acesse em **Arquivo → Novo** Todas as configurações de acesso a dados devem ser feitas no menu **Relatório** → **Configuração de acesso a Dados**. {{:report_manager_img02.png|}} Para criar uma nova conexão, siga os seguintes passos. * Selecione o **Tipo de Conexão**. * {{:report_manager_img03.png|}} * Clique em Add New Connection * {{:report_manager_img04.png|}} * Nesse momento uma lista com os **Alias disponíveis** para esse tipo de conexão será apresentada. Basta escolher o **Alias** e a conexão esta estabelecida. ==== BDE ==== Para estabelecer uma conexão com bancos utilizando a tecnologia **BDE** é necessário utilizar a opção **Borland Database Engine**. ==== ODBC ==== As conexões via **ODBC**, utilizam o driver **Microsoft DAO** e a conexão pode ser estabelecida baseada em um conection string. ===== Criação de DataSets ===== É possível criar inúmeros datasets por relatório e criar relacionamentos entre eles. Todos os dados apresentados em um relatório desenvolvido no Report Manager provem de um **DataSet**, ou seja, um **DataSet é o quem providencia dados para o relatório**. Os **DataSets** são criados na aba **Tabelas do Relatório**, na mesma tela de criação de conexão. {{:report_manager_img05.png|}} Para criar um novo **DataSet** siga os seguintes passos * Clique em Nova Tabela * {{:report_manager_img06.png|}} * Depois de criar o **DataSet**, especifique a query na área branca demonstrada na figura a seguir * {{:report_manager_img07.png|}} * uma forma de testar a query é clicando no botão **Exibe Dados** * {{:report_manager_img08.png|}} * Após construir seus **DataSets** basta clicar no botão **OK**. Os **DataSets** ficam disponíveis na Aba **Data** da janela principal * Feito isso, os campos já estão disponíveis para o uso no relatório. ===== Montando um Relatório ===== Após a criação dos **DataSets** é hora de montar a apresentação do Relatório. ==== Criando um Cabeçalho ==== Para criar cabeçalhos de relatórios é necessário criar uma //Subseção// no //Sub-relatório// criado. Para isso, vá na aba **Structure** na janela principal. {{:report_manager_img09.png|}} Clique na opção //Adiciona uma seção no sub-relatório selecionado// e depois clique no tipo //cabeçalho de pagina// {{:report_manager_img10.png|}} ==== Atribuir DataSet a um Sub-relatório ==== Para que os dados dos DataSets sejam apresentados é necessário especificar no //sub-relatório// qual é o seu DataSet através da propriedade //Tabela Principal//, que é apresentada na tela quando um //Sub-relatório// é selecionado. {{:report_manager_img11.png|}} ==== Criando Textos, Legendas e Expressões ==== É possível criar textos independentes dos valores contidos nos datasets afim de criar legendas para campos, títulos de relatórios, áreas de assinaturas, etc., ou também, condicionar estes textos a determinados valores contidos nos DataSet. === Labels === Para criar um Label basta clicar no botão '//Insere um texto estático//' na barra de ferramentas superior. {{:report_manager_img12.png|}} Feito isso, o cursor irá assumir modo de inserção de objetos na tela, bastando clicar e arrastar o mouse para criar o label. Após o Label ter sido criado suas propriedades podem ser modificadas nas abas de propriedades que ficam na lateral esquerda da tela. {{:report_manager_img13.png|}} === Desenhos === Geralmente é necessário incluir linhas verticais / horizontais, círculos, etc. a um documento, no caso do //Report Manager// temos o objeto **Shape**, que na verdade é um objeto que lhe permite determinar sua forma, se vai ser um circulo, uma linha, um quadrado, etc. A ferramenta de desenhos pode ser acessada através do botão //Insere um desenho simples//, na barra de ferramentas superior. {{:report_manager_img14.png|}} Após você determinar a área que a ser ocupada por esse desenho você pode acessar a propriedade //Forma// que fica na aba //Shape// e alterar o desenho. === Expressões === Expressões são utilizadas para concatenar textos, exibir mensagens de acordo com valores dos datasets, apresentar resultado de cálculos, etc. O Processo para criar a expressão é o mesmo da criação do label, bastando clicar no botão '//Insere uma expressão//' {{:report_manager_img15.png|}} Para determinar a expressão, basta clicar na opção //Expressão// da aba //Expression// das abas de opções da lateral esquerda. Ao clicar nessa opção, a seguinte tela será apresentada {{:report_manager_img16.png|}} Existe uma série de variáveis e funções prontas do próprio Report Manager, como por exemplo, o número da página, total de páginas, remoção de espaços desnecessários, converter caracteres para maiúsculo ou minúsculo, operações matemáticas, etc. === Campos dos DataSets === Como já demonstrado anteriormente, todos os campos dos datasets ficam disponíveis na aba Data no menu esquerdo, sempre separados pelo nome do DataSet. {{:report_manager_img17.png|}} Para adicionar os campos no relatório basta selecionar o campo desejado e arrastar o mesmo para a tela, feito isso você pode editar a formatação do objeto resultante da maneira que bem desejar. ===== Exercício ===== Criar um relatório que liste uma relação de funcionários (//baseados na tabela paradox apresentada a seguir//) com o título **Listagem de Funcionários Ativos**, com uma legenda superior para cada campo inserido no relatório, data e hora da geração e número de página corrente. * Tabela **tbl_funcionarios**: * //create table tbl_funcionarios(Id autoinc, Nome varchar(35), Salario float, primary key(id));// * povoar a tabela como achar melhor. * Criar um DataSet com o nome de Tbl_Funcionarios. * Query * //Select * from tbl_funcionarios// * Atribuir a //Tabela principal// do sub-relatório o dataset tbl_funcionarios. * Cabeçalho * **Título:** Listagem de Funcionários Ativos * **Legenda de Campos:** ID, Nome, Salário * Data / Hora * Uma linha horizontal * Incluir todos os campos na área de detalhe. * {{:report_manager_img18.png|}} * //A data/hora foi recuperada através da variável **now**// ---- ---- Dando continuidade ao exercício proposto, agora iremos formatar a apresentação do campo Salário na tela, para que fica //'R$XXX,XX'// Toda variável que provem de um dataSet, na verdade é uma expressão, e que, também pode ser alterada. Vamos alterar a expressão do campo de Salario. * Primeiro vamos adicionar o Prefixo **R$** como uma string comum * 'R$' * Depois vamos formatar o valor do DataSet para que ele retorne como texto e com a formatação predefinida. Para isso utilizaremos da função **FORMATNUM** * //FORMATNUM('####0.00',TBL_FUNCIONARIOS.salario)// * Feito isso, basta concatenar as duas strings. * {{:report_manager_img19.png|}} * //A maioria das funções possuem uma sintaxe que é apresentada quando a função é selecionada// * Outra forma (talvez mais simples) de fazer essa formatação é preencher na propriedade "//Formato de exibição//" da expressão o valor **R$ ####.00**, o resultado será exatamente o mesmo. Feitas essas alterações, o valor do salário dos funcionários já será apresentado com o R$ como prefixo e com 2 casas decimais fixas. {{:report_manager_img20.png|}} Agora iremos utilizar uma condicional para dizer se o salário do funcionário esta acima ou abaixo de R$300,00. Faremos de duas formar diferentes, começando pela mais simples, utilizando IF em expressão. Primeiro adicione um objeto do tipo expressão na areá de detalhes do relatório, depois em sua expressão utilize o comando: * // IIF(TBL_FUNCIONARIOS.salario < 300, 'Abaixo', 'Acima') // Onde o primeiro parâmetro corresponde a comparação, o segundo corresponde a resposta em caso de resultado afirmativo e o terceiro e último corresponde a resposta em caso de resultado negativo. {{:report_manager_img21.png|}} Outra forma de fazer permitiria formatações diferentes para cada condição. Essa forma consiste na utilização da propriedade //Condição de impressão//. Basicamente serão adicionados dois Labels exatamente no mesmo lugar, um com o texto 'Acima' e a fonte Azul, e o outro com o texto 'Abaixo' e a fonte vermelha, a condição de apresentação de um vai ser o inverso do outro. Adicione um Label e preencha as seguintes propriedades com os valores aqui especificados * **Texto** * Acima * **Cor da fonte** * Azul Marinho * **Condição de impressão** * //TBL_FUNCIONARIOS.salario >= 300// Repita o processo (inclusive deixando um label sobre o outro), * **Texto** * Abaixo * **Cor da fonte** * Vermelho * **Condição de impressão** * //TBL_FUNCIONARIOS.salario < 300// {{:report_manager_img22.png|}} Caso seja necessário alterar a query por algum motivo (ex: gerar o dataSet ordenado por ordem alfabética) e os campos não sejam alterados, não é necessário alterar nenhuma condicional nem a disposição dos campos na tela. {{:report_manager_img23.png|}} ===== Trabalhando com mais de um DataSet ===== Ainda seguindo com a tabela de funcionários, criaremos mais duas tabelas, uma para armazenar dados da empresa que esta trabalhando com o sistema e outra para setores de funcionários. Vamos acrescentar pequenas modificações no relatório de funcionários ativos. * Primeiro crie a seguinte tabela. * //Create table tbl_sistema (Cnpj varchar(14), Razao varchar(35), fantasia varchar(35))// * povoar a tabela da maneira que desejar porem, gerando um único registro. * Depois crie o DataSet tbl_sistema com a seguinte query * //select * from tbl_sistema// * Feito isso adicione os campos desse DataSet no cabeçalho do relatório. {{:report_manager_img24.png|}} Note que, não foi necessário criar outro sub-relatório nem especificar esse novo dataSet como tabela principal de um sub-relatório, isso porque, quando você se referencia a um dataSet dentro de um sub-relatório sem especificar que esse dataSet é sua tabela principal, o sub-relatório só carrega o primeiro registro do dataSet. ==== Mestre / Detalhe ===== Para o exemplo de relatório //mestre / detalhe// iremos criar um relatório novo, porém baseado no primeiro. * Primeiro crie a seguinte tabela //tbl_setores// * //create table tbl_setores (id autoinc, nome varchar(35), primary key(id))// * povoar a tabela como desejar * Alterar a tabela tbl_funcionarios com a seguinte Query * //alter table tbl_funcionarios add setor integer// * atualizar os registro como desejar, referenciando a tabela de setores * Crie o dataSet tbl_setores com a seguinte query * //select id as id_setor, nome from tbl_setores// * Atualize a query do dataSet //tbl_funcionarios// para * //select * from tbl_funcionarios where setor = :id_setor order by nome// * Altere a propriedade Tabela Mestra do dataSet tbl_funcionarios para tbl_setores * {{:report_manager_img25.png|}} Utilizando a variável //:id_setor// e indicando que a tabela mestra é a //tbl_setores//, esta é a configuração principal do nosso //mestre / detalhe//. Com isso estamos dizendo que a cada registro do dataSet //tbl_setores// iremos recarregar o dataSet //tbl_funcionarios//, trazendo somente os funcionários que tenham o valor do campo //setor// igual ao campo //id// do registro carregado do dataSet //tbl_setores//. Após todos os dataSets terem sido criados, é o momento de criar a parte visual do relatório. * Crie mais um Sub-relatório * No Sub-relatório 0 * crie um //Cabeçalho// e um //Rodapé// de pagina caso não tenha um(não é //“Grupo cabeçalho e rodapé da página”//) * Associe a tabela principal ao dataSet tbl_setores * Na área de //Detalhe// altere a propriedade //Sub-Relatório Filho// para **Sub-Relatório 1** (sub-relatório que vamos colocar os detalhes) * Preencha o cabeçalho com o título e os dados da empresa. * Preencha o detalhe somente com o nome do setor * Preencha o rodapé com a data / hora (variável now) e com o número da página (variável m.page) * No rodapé marque as opções //Escopo globo// e //Forçar impressão// como true. * No Sub-relatório 1 * Crie um //Grupo Cabeçalho e Rodapé de Página// (esse cabeçalho e rodapé só se aplicam aquela área de //detalhe// que estão vinculados ) * Associe a tabela principal ao dataSet //tbl_funcionarios// * Preencha a área de detalhe com os campos do dataSet //tbl_funcionarios//. {{:report_manager_img26.png|}} O rodapé não foi apresentado, porém foi impresso normal. ===== Parâmetros ===== Para chamadas externas e atualização dinâmica do relatório, são utilizados //Parâmetros//. Esses parâmetros geralmente são vinculados aos valores do //Where// das querys. A criação de parâmetros é através da tela de conexão e criação de dataSets {{:report_manager_img27.png|}} Na criação do parâmetro basta você informar seu nome, valor inicial e tabela associada. Crie um parâmetro com as seguintes propriedades: * **Nome :** Media * **Tipo :** Decimal * **Valor :** 400 * **Tabelas associadas :** Tbl_funcionarios. {{:report_manager_img28.png|}} Feito isso, já é possível utilizar o parâmetro recém criado nas querys. Altere a query do dataSet //tbl_funcionarios// para: * //select * from tbl_funcionarios where setor = :id_setor and salario > :media order by nome// Dessa forma serão somente apresentados os funcionários com o Salario maior do que R$400,00. {{:report_manager_img29.png|}} Esse valor default do parâmetro pode ser alterado. Como já dito anteriormente em tempo de execução do relatório, o valor dos parâmetros podem ser modificados, fazendo com que o relatório seja carregado novamente porém de forma mais rápida. Para alterar um parâmetro ou mais com o relatório já carregado, basta pressionar a tecla **F12**, ou clicar no botão //Exibir uma janela de parâmetros do usuário//. {{:report_manager_img30.png|}} Todos os parâmetros serão apresentados, possibilitando a alteração. {{:report_manager_img31.png|}} ===== Dicas ===== ==== Fazendo um campo total ==== É comum nos relatórios querermos fazer um campo que calcule um determinado campo. Para isso, as Expressões possuem uma propriedade chamada Agregar. Nela você pode agregar expressões ao sub-relatório inteiro, à página ou à um grupo. Feito isso, ainda existe uma propriedade chamada “Ag. Tipo” (Tipo de Agregação). Nela existem as expressões Soma (para a soma dos campos), Min (o valor mínimo daquela seqüência de registros), Max (maior valor daquela seqüência de registros), Média (a média daquela seqüência de registros) e Std. Desv. (Desvio padrão estatístico daquela sequência de registros). === Exemplo prático === Caso: Queremos calcular o total do salário de todos os funcionários. * Criamos um “Grupo cabeçalho e rodapé de página” no sub-relatório mestre (sub-relatório 0) * Criamos um DataSet com o nome Total_Setor * **Query:** //select sum(salario) as total from tbl_funcionarios where setor = :id_setor and salario > :media// * **Tabela mestre:** tbl_setores * Colocamos o parâmetro MEDIA para esse DataSet também, para manter o filtro * No rodapé do grupo criado adicionemos um label com o texto “Total” e o campo total do DataSet TOTAL_SETOR * Na expressão que colocamos alteramos a propriedade “Agregar” para “Geral” * Alteramos também a propriedade “Ag. Tipo” para “Soma” * Altere a propriedade Ag.I.Valor para 0 Com isso o valor daquela expressão será agregado à cada novo registro exibido no seu sub-relatório. No nosso caso ele irá incrementar o valor da soma de todos os salários de cada setor sempre que cada novo registro de setor for exibido, mantendo o filtro. {{:report_manager_img32.png|}} ==== Definindo a formatação de um campo (expressão) ==== Existe algumas forma de definir a formatação de um campo, porem a mais prática e recomendada é através da propriedade //Formato de Exibição//, está propriedade pode ser utilizada como a propriedade //Edit Mask// de um //MaskEdit// no Delphi, pois, nesta propriedade é definida a mascara de exibição do campo. === Exemplo === Para definir um formato de exibição para campos que deveram apresentar valores monetários, a propriedade devera ser preenchida com **R$ 0.00** por exemplo. Note que o caracter utilizado para separação decimal é o //ponto//. ==== Utilizando Identificadores de campos como variáveis ==== É comum surgir a necessidade de se referenciar ao resultado de uma //expressão// criada, em uma outra expressão qualquer, como por exemplo, montar um calculo de diferença em um totalizador. Para que isso seja possível, existe a propriedade //Identificador// nas expressões, o uso desta propriedade faz com que seja criada uma variável com o nome definido na propriedade e que passa a ter o acesso liberado em todo relatório. Valor desta variável é sempre o resultado da expressão que contem o identificador. ==== Trabalhando desvio horizontal ==== Os detalhes possuem a propriedade **Desp. Horz.**. Essa propriedade determina se o detalhe irá aparecer do lado de outro detalhe se sobrar espaço. Isso pode ser útil para, por exemplo, imprimir etiquetas. === Exemplo === Neste exemplo temos uma tabela de produtos, com vários registros. O nome do DataSet dessa tabela é PRODUTO * Crie um relatório novo; * Deixe o único detalhe com as dimensões Altura = 3 e Largura = 8; * Atribua o DataSet PRODUTO ao único sub-relatório existente, para que o detalhe seja impresso a cada registro; * No detalhes, deixe a propriedade **Desp. Horz.** como true; * Visualize o relatório. Deverá ter aparecido algo assim ^ ^ ^ | Item 1 | Item 2 | | Item 3 | Item 4 |