Este é um
assunto muito requisitado em nosso suporte técnico, não apenas em se tratando
de relatórios e sim exemplos envolvendo cadastros e consultas utilizando esta
técnica.
Para quem
não sabe, Mestre-Detalhe é a Típica Entidade Relacionamento “Um para Muitos”.
Mestre é o registro que existe por si só, já o detalhe necessita de um “Mestre”
para poder existir.
Podemos
realizar esta tarefa sem muitos esforços utilizando o gerador de Relatórios ReportViewer
junto com o Microsoft Visual Studio 2010. O intuito deste artigo será de descrever
todas as etapas envolvendo um exemplo básico
de Pedido de Venda utilizando como Banco de Dados o Microsoft SQL Server 2008
com a base de dados padrão “NorthWind”.
Tabelas Utilizadas
Para
exemplificar melhor, nos próximos passos montarei um Modelo (Entidade
Relacinamento –ER) utilizando a ferramenta SQL Server Management Studio do
próprio SQL Server 2008.
Usamos
como base uma Tabela de Pedido (Orders) se relacionando com outra de itens
(OrderDetail), fechando um relacionamento Mestre-Detalhe. Relacionamos também
com a tabela de Clientes (Customers) e de Produtos (Products). Iremos recuperar
os dados através de uma Instrução SQL envolvendo todas estas tabelas citadas.
Ver
Imagem 01 para maiores detalhes.
Figura
01: Modelo Entidade Relacionamento (ER) das tabelas envolvidas.
Montando um
exemplo
Para Isto
abra o Microsoft Visual Studio clicando em “File/New/Web Site...” para assim
criarmos uma página web do zero.
1-) Definindo a
fonte de Dados
A fonte
de dados nada mais é do que a origem e a forma como os dados serão coletados
para podermos trabalhar com eles. Clique com o botão direito sobre a solução e
escolha “Add New Item...”. Localize o item “Dataset” e defina um nome para este
objeto, por exemplo: “dsMestreDetalhe”. Notem que foi criada uma pasta
“App_Code” e dentro dela um arquivo do tipo “.xsd”. Geralmente dentro desta pasta
é onde armazenamos estes ou outros tipos de arquivos, como por exemplo do tipo
classe (.cs). Dê um duplo clique para podermos definir a fonte de dados.
Importante
salientar que na região esquerda da tela aparecerá uma ToolBox.
Figura 02: ToolBox.
Para
trabalhar com relatórios existem diversos tipos de componentes, eu recomendo a
utilização do “TableAdapter”, nele conseguimos configurar tudo o que precisamos
no quesito de instruções SQL. Arraste-o na tela e seguiremos os passos adiante.
Na tela “Choose your data Connection” é o local onde escolhemos a conexão, Ver
Imagem 03.
Figura 03: Tipo de Conexão.
Já na
próxima etapa denominada “Choose a Command Type”, é o local onde definimos o
modo como o tableAdapter irá acessar a Base de Dados. Possuímos três opções,
sendo:
- Uso de Instruções SQL;
- Criar Stored Procedures;
- Usar Stored Procedures.
Escolha a primeira opção e clique em “Next”. Ver Imagem 04.
- Uso de Instruções SQL;
- Criar Stored Procedures;
- Usar Stored Procedures.
Escolha a primeira opção e clique em “Next”. Ver Imagem 04.
Figura 04: Acesso a Base de Dados.
Faremos
uma Instrução SQL baseada no diagrama disposto logo no início do artigo (Figura
01). Parametrizamos pelo “OrderID” (Número do Pedido) utilizando a cláusula
“Between” (intervalo de valores) .
SELECT
Customers.CompanyName, Orders.OrderID, Orders.RequiredDate,
Products.ProductName, OrderDetails.ProductID, OrderDetails.UnitPrice,
OrderDetails.Quantity
FROM Orders
INNER JOIN Customers ON Customers.CustomerID =
Orders.CustomerID
INNER JOIN OrderDetails ON OrderDetails.OrderID =
Orders.OrderID
INNER JOIN Products ON Products.ProductID =
OrderDetails.ProductID
WHERE (Orders.OrderID BETWEEN @COD_INI AND @COD_FIM)
A tabela a seguir nos mostra o significado dos campos utilizados.
Campos
|
Significado
|
CompanyName
|
Nome do Cliente
|
OrderID
|
Número do
Pedido Venda
|
RequiredDate
|
Data Requisição
|
ProductName
|
Nome do Produto
|
ProductID
|
Código do
Produto
|
UnitPrice
|
Preço Unitário
|
Quantity
|
Quantidade
|
Podemos também montar instruções SQL com o auxílio do “Query Builder”, sem
nenhuma codificação. Ver Image 05.
Figura 05: Instrução SQL.
O
“TableAdapter” deverá ficar idêntico ao da Figura 06.
Figura 06: TableAdapter “DsMestreDetalhe”.
2-) Definindo o
Lay-out do Relatório
- Criando
Parâmetros
Crie um
arquivo do tipo “.rdlc” e o nomeie como “RptMestreDetalhe”. O passo inicial da
nossa tarefa é definir alguns parâmetros como por exemplo: o Título e o
SubTítulo, para isto clique no menu “View/Report Data”. Na pasta “Parameters”
clique como o botão direito e escolha “Add Parameter...”. Na aba “General”
defina em “Name” como “ParamTitulo” e em “Data type” como “text”. O restante
deixaremos como padrão, clique em OK para concluir este processo. Os mesmos
passos descritos deverão ser realizados para o parâmetro “SubTítulo”. Ver
Imagem 07.
Figura 07: Criando Parâmetros.
No
Cabeçalho do relatório adicione dois componentes “textBox” contendo os
seguintes valores:
Título:
=Parameters!ParamTitulo.Value
Subtítulo:
=Parameters!ParamSubtitulo.Value
Esta é a referência dos parâmetros que iremos passar mais adiante através do Preview do relatório.
- Criando o
agrupamento
No corpo
insira um “Table” e na propriedade “DataSetname” deixe como DsMEstreDetalhe.
Para adicionar um grupo clique com o botão direito sobre a linha “Data” e
escolha “Add Group/Parent Group”. Ver Imagem 08.
Figura 08: Adicionando o Agrupamento.
Na Janela
“Tablix group” escolha “Group by: [OrderID]” para agrupar por “orderID” e
cheque os valores “Add group header” e “Add group footer”, significando
respectivamente para adicionar cabeçalho e rodapé para o grupo. Ver Imagem 09.
Figura 09: Tablix Group.
Um
detalhe importante é que a linha que contém os dados a serem agrupados possui
um leve tracejado. (=) . Montaremos
um lay-out contendo no cabeçalho os dados: “RequiredDate” e “CompanyName”. No
corpo inserimos o “ProductID”, “ProductName”, “UnitPrice”, “Quantity” e um
campo calculado com o “Total”, já no rodapé a soma total dos Produtos. Ver
Lay-out proposto na Figura 10.
Figura 10: Relatório em desenvolvimento.
- Formatação de
Valores
Em se
tratando de relatórios, sempre utilizamos a formatação de campos a fim de dar
um visual mais atraente ao usuário, como por exemplo uma máscara numérica ou de
Data. Veja exemplos a seguir:
Máscara Numérica:
=format(Fields!UnitPrice.Value,"###,###,##0.00").tostring()
Máscara Data:
=format(Fields!RequiredDate.Value,"dd/MM/yyyy").tostring()
A Função
“Format()” tem como primeiro parâmetro o campo e o segundo o tipo de formatação
desejada.
Estes
valores são inseridos clicando com o botão direito sobre o campo escolhendo a
opção “Expression...”. A expressão deverá ser inserida no campo “Set Expression
for: Value”. Ver Imagem 11.
Figura 11:
Formatando campos.
Faremos
este procedimento para os campos “RequiredDate” (Data), “UnitPrice” (Valor
Unitário), “Quantity” (Quantidade), “Total” e “Total Geral”.
- Campos
Calculados
Os campos
calculados são utilizados para obter valores sem a utilização de campos
específicos em Banco de Dados. Podemos realizar operações de subtração, adição,
multiplicação, divisão e funções específicas do relatório. Segue exemplo a
seguir utilizando o campo “Total” e “Total Geral” respectivamente.
Campo “Total”:
=format(Fields!UnitPrice.Value*Fields!Quantity.Value, "###,###,##0.00")
Campo “Total Geral”:
=format(SUM(Fields!UnitPrice.Value*Fields!Quantity.Value), "###,###,##0.00")
3-) Definindo o Preview
do relatório
Adicionaremos
alguns componentes na tela para efetuar a parametrização e a execução do
relatório. Primeiramente adicione uma tabela para organização e em seu interior
2 Labels, 2 TextBoxes e um Button, para podermos filtrar por “OrderID”, que
seria o número do pedido de venda. Já o componente ReportViewer é responsável
pela visualização do relatório, junto com o Scriptmanager (componente
necessário para execução de scripts) e o ObjectDataSource para inserção de
alguns parâmetros. Ver Imagem 12.
Figura 12: Preview do Relatório.
Clique
sobre o componente “ReportViewer” e na região superior direita clique na
setinha (>) escolha “Choose
Report” para vincular o relatório “RptMestreDetalhe.rdlc” ao preview.
Configurando o
ObjectDataSource
O
“ObjectDataSource” serve para configurar diretamente com classes de acesso a
dados, ou seja, neste caso apontaremos para a fonte de dados citado
anteriormente. Para isto clique sobre o mesmo e escolha a opção “Configure Data
Source”. A Figura 13 é onde definimos o objeto “DsMestreDetalhe”. Clique em
“Next” para configuração da próxima etapa.
Figura 13: Definindo
o objeto.
Esta tela é muito
importante, pois é nela onde são situados os métodos de Seleção, Atualização,
Inserção e Exclusão. Em se tratando de relatórios apenas utilizaremos o
primeiro método, o de Seleção de Dados. Neste caso estamos retornando um objeto
do tipo “DsMestreDetalhe” e inserindo dois parâmetros do tipo inteiro, o
“COD_INI” e o “COD_FIM”, ambos responsáveis pela parametrização dos dados ali
obtidos. Ver Imagem 14.
Figura 14:
Definindo o método de Seleção de Dados.
Já na
próxima etapa, na região esquerda, estão situados os “Parameters” (parâmetros
Nome e Valor) junto com algumas configurações como: “Source” (fonte, a origem
do parâmetro), “QueryStringField” (nome do parâmetro) e “DefaultValue” (valor
padrão). Clique em “Finish” para terminar este processo. Ver Imagem 15 para
maiores detalhes das configurações.
Figura 15: Definindo
os Parâmetros.
Codificando o botão
“Imprimir”
Antes de iniciarmos a
codificação no evento “Click()” do botão importe a seguinte biblioteca:
using Microsoft.Reporting.WebForms;
Esta
biblioteca é responsável por alguns métodos utilizados ao decorrer do artigo.
protected
void Button1_Click(object sender, EventArgs e)
{
ObjectDataSource1.SelectParameters[0].DefaultValue = TextBox2.Text;
ObjectDataSource1.SelectParameters[1].DefaultValue
= TextBox3.Text;
ReportParameter[] parametros =
{
new
ReportParameter("ParamTitulo","The Club - O Maior Clube de
Programadores do Brasil"),
new
ReportParameter("ParamSubtitulo","Relatório de Venda -
Mestre/Detalhe")
};
ReportViewer1.LocalReport.SetParameters(parametros);
ReportViewer1.LocalReport.Refresh();
}
Utilizamos
o método “SelectedParameters” para filtrar os dados na instrução SQL. Faremos
referência respectivamente com o primeiro e segundo TextBox. Já com a classe
“ReportParameter” inserimos algumas informações que mais adiante serão
recuperadas dentro do próprio arquivo “.rdlc”. Temos um par chave/valor sendo o
nome do Parâmetro seguido do valor. Para finalizar passamos os dados utilizando
a função “SetParameters”.
Para
atualizar os dados na tela usamos o “refresh()”. Para testar o exemplo
pressione o botão F5 e teremos um resultado parecido com a Imagem 16.
Figura
16: Relatório.
Conclusão
O
desenvolvimento de relatórios do Tipo “Mestre/Detalhe” é muito habitual para
nós programadores, usando para diversas tarefas como: Pedidos de Venda,
Orçamentos de Produtos, entre outros tipos. A minha intenção neste artigo foi
de proporcionar um exemplo prático para a utilização do ReportViewer em uma
página Asp.Net. Podemos também aplicar estes conhecimentos, sem muitos esforços,
na plataforma Desktop por exemplo. O ReportViewer, na minha opinião, é uma das
melhores ferramentas em se tratando de Desenvolvimento de relatórios na plataforma
“.Net”, tanto pela sua facilidade quanto pela grandiosidade de recursos
encontrados. Vou procurar abranger em artigos futuros outros tipos de exemplos
envolvendo esta ferramenta.
Um forte
abraço e até o mês que vem!
Nenhum comentário:
Postar um comentário