Olá, pessoal! Continuando nosso artigo sobre o reporting services (veja a primeira parte aqui), começaremos a analisar o que chamamos de relatórios local mode.
Local mode
Também conhecidos como client-side, os relatórios ditos locais seguem o modelo de desenvolvimento e deploy dos relatórios desenvolvidos como o Microsoft Access e Crystal Reports, onde os relatórios são parte integrante da aplicação.
Arquitetura
Nesse modelo de relatório, todo processamento é realizado no cliente. A aplicação é responsável por obter os dados provenientes de qualquer fonte de dados, e o controle ReportViewer apresenta os relatórios. A figura abaixo apresenta a arquitetura dos relatórios Local Mode:

Caracteristicas
Os relatórios “local mode” caracterizam-se especialmente por:
- A segurança é herdada da aplicação que o hospeda;
- Filtros, ordenação, agrupamento e funções de agregação estão disponíveis;
- Possui formatação rica e inteligente, com imagens, fontes e cores;
- Interatividade com bookmarks e DocumentMap;
- Liberdade para interatividade com o usuário final;
- Integração com o controle ReportViewer;
- DataSet como estrutura de dados;
- Arquivos .RDLC (nenhuma instrução de acesso e/ou conexão à base de dados).
E seus elementos fundamentais correlacionam-se conforme a figura abaixo:

Processo de criação
A partir dessa sessão, começaremos a implementar alguns relatórios exemplo. Para isso utilizaremos um banco de dados que controla pedidos de uma loja de departamentos. O diagrama abaixo apresenta as tabelas e seus respectivos relacionamentos.

Retornando ao processo de criação, para qualquer relatório implementado temos que seguir basicamente os seguintes passos:
- Modelagem do repositório de dados local
DataSet – estrutura de dados com integridade relacional:
- Elaboração do layout e “inteligência” do relatório
Header, Body, Footer:
- Uso de patterns – dados agrupados, tabular, matriz, colunas múltiplas, gráficos.
Criação de parâmetros, formatação condicional:
- Recuperação dos dados, preenchimento do dataset e bind com o relatório
- APIs do ADO .NET, Stored Procedures, T-SQL
- Controle ReportViewer
Template de aplicação
Para nossos exemplos, tomaremos uma aplicação Windows Forms, como apresentado na figura abaixo. Atente para as pastas DataSources e Reports, onde respectivamente armazenaremos os DataSets e os relatórios criados.

Repositório de dados local – dataset
Relatórios são representações formatadas de um conjunto de registros provenientes de uma consulta em um repositório de dados. Para os relatórios criados na plataforma do Reporting Services é necessário um DataSet tipado com uma ou mais tabelas, que serão a estrutura de dados volátil contendo as informações dos relatórios. Esse dataSet será preenchido no aplicativo que hospeda o relatório e será utilizado na sua formatação.
Nota: Um DataSet é uma representação na memória de um banco de dados relacional. Maiores informações, consultar a página do MSDN especifica sobre essa estrutura de dados.

Podemos criar objetos DataSets de diversas formas. Utilizaremos aqui o wizard do Visual Studio para a criação dos nossos, bem como das tabelas necessárias para criação dos relatórios. Nesse primeiro exemplo teremos um relatório tabular com os produtos, suas respectivas categorias, quantidade em estoque e valor unitário. Então, modelaremos um dataset com uma única tabela contendo esses campos como mostrado na figura 2.6. A figura 2.5 ilustra a criação de um novo dataset através da inclusão de um novo item (DataSet) ao projeto.

Formatando os relatórios
Tipos e estrutura do relatório
Uma vez modelado o DataSet, é hora de utilizá-lo para formatar o relatório. O primeiro passo é decidir que tipo de relatório será utilizado. Por exemplo, se os dados estiverem relacionados a agrupamento de itens, a melhor escolha é utilizar um relatório tabular (como no caso desse nosso primeiro exemplo). No entanto, relatórios com gráficos são mais indicados para representar dados sumarizados. A estrutura dos relatórios do RS inclui três sessões como mostrado na figura 2.7:
- Header: indicado para incluir informações estáticas referentes ao relatório, tais como título, data, logo da empresa e, se for o caso, alguns dos parâmetros informados pelo usuário;
- Body: é a região dos detalhes do relatório, onde os dados provenientes das consultas (armazenados no DataSet), filtros e ordenação serão exibidos;
- Footer: ideal para outras informações do relatório, tais como número de página e informações de direitos autorais.

Report itens
Parte fundamental da formatação dos relatórios, os report items, disponíveis na Toolbox do Visual Studio, funcionam como um canal entre o DataSource e a estrutura do relatório. Os Report Itens são simples objetos, parecidos com os controles das aplicações Window e Web Forms, e como tal, o grande segredo do bom uso desses itens é conhecer suas propriedades. A figura 2.8 apresenta nossa caixa de ferramentas, onde já utilizamos alguns textbox e um table para formatar as sessões header e body.

A tabela a seguir descreve resumidamente os itens da nossa caixa de ferramentas:
Item | Descrição |
Poiter | Seleciona os itens do relatório. |
Textbox | Item mais utilizado da toolbox – exibe informações provenientes do datasource ou mesmo textos estáticos. |
Line | Desenha uma linha como separador de informações. |
Table | Exibe detalhadamente as informações do relatório em formato tabular, além de disponibilizar sessões de cabeçalho e rodapé. |
Matrix | Exibe detalhadamente as informações do relatório correlacionando linhas e colunas. |
Rectangle | Agrupa informações relacionadas. |
List | Exibe detalhadamente as informações do relatório. Parecido com o table, no entanto sem tantos recursos, tais como as sessões de cabeçalho e rodapé. |
Image | Permite inserir imagens no relatório. |
Subreport | Inclui outro(s) relatório(s) dentro de um relatório principal. |
Chart | Exibe as informações do relatório em formato gráfico, com diversas opções de formatação. |
Mais informações sobre os itens mais importantes:
- Textbox
Pode-se dizer que não é possível construir um relatório sem o Textbox, que é sem dúvida o componente mais versátil que temos à disposição. Ele pode ser utilizado para diversas finalidades, como o título do relatório no header e a exibição de totalizadores. Esse controle é usado para exibir textos estáticos, fazer bind com data source, campos calculados e expressões. - Table
É o melhor item para relatórios detalhados. Cada tabela possui uma estrutura com sessões Header, Detail e Footer – não confundir com as sessões homônimas do próprio relatório. O Header é indicado para os nomes das colunas; no Details, temos um conjunto de linhas provenientes do datasource e, finalmente, no Footer, temos informações sumarizadas dos dados do relatório. É possível ter mais de uma tabela em um relatório. É muito importante dominar quais são as propriedades do componente Table (figura 2.9 abaixo) – especialmente as tabs Groups, onde é possível configurar diversos agrupamentos das informações e Filter, onde podemos estabelecer restrições aos dados visíveis aos usuários.

Subreport
Um relatório é considerado um subreport quando inserido em outro relatório. O sub-relatório funciona como um filho do relatório que o hospeda (parent), tornando os sub-relatórios uma poderosa ferramenta para, por exemplo, implementar o tão requisitado conceito master/detail. No entanto é preciso ter muita cautela na sua utilização, uma vez que temos perdas consideráveis na performance do relatório.
Chart
O item Chart é responsável pela apresentação de informações numéricas em formato de gráficos. As ferramentas de gráficos foram inseridas nos relatórios do RS pela empresa Dunda Software, estando à disposição os tipos mais comuns de gráficos: pizza, barra e colunas.
Formatação
Não se faz um relatório capaz de atrair a atenção dos leitores se suas informações não forem bem formatadas. Dados numéricos, por exemplo, são muito melhor compreendidos se devidamente formatados conforme seu tipo – numérico inteiro, decimal, moeda ou científica, por exemplo. Outra informação digna de atenção na sua formatação são os campos referentes à data e hora. No processo de criação dos relatórios, a formatação é feita através de uma caixa de dialogo na tab Format das propriedades de uma caixa de texto, vide abaixo – figura 2.10.

Dicas importantes:
- Certifique-se que o tipo do campo esteja devidamente bem definido no DataTable, do contrário a formatação simplesmente não funciona. E o tipo default dos campos é System.String;
- Garanta que o idioma do relatório esteja devidamente configurado;
- Considere o uso de Expressions do tipo, Common Functions à Text (Format, FormatCurrency, FormatDateTime, FormatNumber e FormatPercent).
Ainda com o intuito de tornar nossos relatórios atrativos aos usuários, outros atributos das caixas de texto podem ser customizados, tais como Fontes, Cor, Alinhamento e Decoração. Todos esses, além de outros atributos, podem ser configurados na janela de propriedades do Textbox, como mostrado na figura 2.11.

Dentro da formatação, eis um recurso muito poderoso dos relatórios do RS, que é a formatação condicional, onde através do editor de Expressions, que utiliza um dialeto da linguagem Visual Basic, é possível criar instruções condicionais como a descrita abaixo.
=IIf(Fields!QT_ESTOQUE.Value<230,”Red”,”Blue”)
Parametrização
Os relatórios possuem um mecanismo de parametrização onde é possível passar informações a partir do cliente para o relatório em tempo de execução. A figura 2.12 ilustra a janela Report Parameters para criação dos parâmetros de um relatório, onde para acessar, basta clicar com o botão direito fora das sessões do relatório.

Os parâmetros aqui criados podem ser utilizados para formatação condicional ou em expressões. Ao contrário dos relatórios remote mode, esse modelo de relatórios não tem uma área para que o usuário selecione ou digite o valor dos parâmetros, sendo responsabilidade do cliente providenciar uma interface para coleta dessas informações. Dessa forma, gerar o conjunto de dados devidamente filtrado e carregá-lo no dataSet, os parâmetros são pouco utilizados para seleção dos registros, uma vez que é mais indicado fazer essa restrição diretamente na pesquisa, ainda que tenhamos como aplicar filtros (propriedade das tabelas, tab Filters). Essa funcionalidade é mais indicada para criação de relatórios do tipo master/detail com subreports.
Consumindo o relatório
Controle reportviewer
Para interação dos relatórios com os clientes, temos o controle ReportViewer, disponível no visual Studio em duas versões – uma para web e outra para Windows forms. Com ele é possível disponibilizar para as aplicações um conjunto de funcionalidades, tais como:
- Exportação dos dados nos formatos Excel e PDF;
- Suporte a impressão e visualização de impressão do relatório
- Rica interatividade com navegação, document map, bookmarks e ordenação;
- Pesquisa de texto no corpo do relatório;
- Zoom.
O controle é capaz de processar e renderizar os relatórios independente do seu modelo, local ou remote. A figura abaixo exibe o controle ReportViewer em ação renderizando um relatório.

Parte dos recursos do ReportViewer, tais como Zoom, botão Stop, os botões de pesquisa, de exportação, impressão, dentre outros, podem ser desativados na sua janela de propriedade, como mostrado na figura abaixo. Outra propriedade importantíssima do ReportViewer é seu ProcessingMode.

Código cliente
Uma vez modelados, o relatório e seu respectivo DataSet, chegou a hora de relacionar tudo. E como já dissemos, todo processamento é feito no cliente – da obtenção dos dados no repositório para carga do dataset, à renderização do relatório via controle ReportViewer. A figura 2.15 apresenta o fluxo padrão de um código cliente para utilização de relatórios RS em client-mode.

Eis um pseudocódigo utilizado em um cliente de um relatório local mode.
string cnString = "Database=[banco];Server=[servidor];User Id=sa;PassWord=sa"; SqlConnection conReport = new SqlConnection(cnString); SqlCommand cmdReport = new SqlCommand(); DataSet dsReport = new WFormReport.DataSources.ProdutosporCategoria(); conReport.Open(); SqlParameter[] parms = {new SqlParameter("@idCategorias", SqlDbType.VarChar,20)}; parms[0].Value = “1,2,3”; cmdReport.CommandType = CommandType.StoredProcedure; cmdReport.Connection = conReport; foreach (SqlParameter parm in parms) cmdReport.Parameters.Add(parm); cmdReport.CommandText = "getProdutosinCategorias"; SqlDataReader drReport = cmdReport.ExecuteReader(); dsReport.Tables[0].Load(drReport); drReport.Close(); conReport.Close();reportViewer1.LocalReport.ReportPath = “ProdutosporCategoria.rdlc";ReportDataSource rds = new ReportDataSource();rds.Name = "ProdutosporCategoria_ProdutosEstoque"; rds.Value = dsReport.Tables[0];reportViewer1.LocalReport.DataSources.Clear(); reportViewer1.LocalReport.DataSources.Add(rds); reportViewer1.RefreshReport();
Por hoje é isso pessoal. Na próxima edição imperdível, trarei só códigos! Diversos exemplos para boas horas de diversão.
Grande abraço e até lá.