Além de suas funcionalidades primordiais para manutenção de dados, sistemas costumam exigir uma área gerencial que permita a visualização dos dados manipulados. Para tal é comum utilizar ferramentas de relatório do .NET, tais como Crystal Reports ou Reports.
Reports associados com seu Report Viewer devem ser conectados a base de dados de maneira que aceite os filtros necessários para atender aos critérios do cliente. Quando pesquisamos por conteúdo que demonstre a utilização desta ferramenta, é comum encontrar tutoriais e/ou artigos que demonstrem sua utilização, porém com um velho vicio de desenvolvedores em ASP.NET ou Windows Form, o famoso “clica e arrasta”. São poucos os artigos que ensinem o leitor a popular a criar, popular e vincular um DataSet ao Report de forma dinâmica.
O objetivo deste artigo é demonstrar de maneira simples como criar um DataSet de maneira programática e vinculá-lo ao Report. Neste exemplo utilizaremos a base de exemplo da Microsoft AdventureWorks. O Report irá listar os empregados e seus respectivos cargos, a figura 1 mostra o Database Diagram do SQL Server com as tabelas que utilizaremos. Para fazer download do AdventureWorks acesse o link http://sqlserversamples.codeplex.com/.
Figura 1 Diagrama da Base utilizada
Nosso projeto será simples, terá uma classe de acesso a dados, uma página de filtros e uma página contendo o ReportViewer, além do Report.rdlc é claro.
Para iniciar abra o Visual Studio e vá a novo Projeto -> ASP.NET WebSite, conforme figura 2.Figura 2 Criando o Projeto
A figura 3 mostra a tela de criação do projeto, como utilizaremos o servidor interno do Visual Studio para executar o projeto, recomendo deixar selecionado File System na caixa de seleção Web Location, assim podemos indicar um diretório físico para o projeto, que demos o nome de “PopulandoReport”.
Figura 3 Salvando o Projeto
O primeiro passo para implementar nosso projeto é acessar a base de dados e retornar os dados que queremos, como o objetivo desse artigo é demonstrar a utilização dinâmica do ReportViewer, nossa classe de acesso a dados será simples e ficará na pasta App_Code do projeto. Para criar a classe EmpregadoDataAccess, clique com o botão direto do mouse sobre o projeto -> Add New Item e escolha Class, assim como exibido na figura 4.
Figura 4 Adicionando a Classe EmpregadoDataAccess
Ao clicar em Add o Visual Studio irá sugerir que seja criada a pasta App_Code ao projeto e adicione a nossa classe dentro dela, clique em sim e a classe será criada normalmente. Note que a estrutura da classe é simples, teremos um construtor e um método: GetEmployees.
A listagem 1 apresenta o código da classe, note que utilizamos a instrução using para garantir que o Garbage Collector entre em ação para limpar os recursos utilizados. Por boas práticas não recomendamos a utilização da connectionstring direto no código fonte e sim, no Web.Config da aplicação, como este é apenas um código de exemplo será utilizado diretamente. Outro ponto importante é a utilização de parâmetros na query, parâmetros além de serem boa prática, também agregam segurança, reduzindo os riscos de Sql Injection.Listagem 1 Classe EmpregadoDataAccess
Em nossa página default serão adicionados um DropDownList, o qual popularemos com alguns cargos, um Button para o submit e o ReportViewer, para geração do Report. Para adicionar o ReportViewer expanda a toolbox do visual Studio, clique em Reporting, então clique sobre ReportViewer e arraste para dentro da página, a figura 5 exibe o controle exatamente o controle a ser selecionado. Neste ponto é recomendada a utilização do “Clica e Arrasta”, pois conforme pode ser visto nas figuras 6 e 7, o visual Studio adiciona as referências necessárias para utilização de Reports na Página e no Web.Config.
Figura 5 Selecionando o Report Viewer
Figura 6 Registrando o Assembly para utilização de reports
Figura 7 Assembly registrado no Web.Config
Por questão de organização iremos adicionar duas pastas ao nosso projeto: 1) report – irá abrigar o nosso Report.rdlc e; 2) xsd – onde será salvo o nosso DataSet gerado dinamicamente. Então sem mais delongas vamos a .cs de nossa Default.aspx para inciarmos a programação. Antes de abrir a default.aspx.cs dê dois cliques sobre o botão para que o visual Studio adicione automaticamente o evento necessário para a pesquisa de dados do relatório.
Dentro do evento gerado iremos receber o valor selecionado no DropDownList de cargos e instanciar nossa Classe EmpregadoDataAccess. O próximo passo é criar um DataSet que recebe o retorno do método GetEmployess, veja a Listagem 2.Listagem 2 Estrutura Default.aspx.cs
O próximo passo é adicionar logo abaixo da linha de criação do dataset, a instrução para que seja criado o DataSet físico no projeto, para isso utilizamos o método WriteXmlSchema da classe DataSet, veja Listagem 3. Execute o projeto pressionando Ctrl + F5, logo após vá a pasta xsd e pressione F5 para atualizar seu conteúdo.
Listagem 3 Criando o DataSet
Abra o DataSet gerado e note que ele possui somente uma Table, correspondente ao resultado de nossa query, os campos da Table são exatamente os chamados no select, assim como vemos na Figura 8. É importante lembrar que o método WriteXmlSchema é necessário ser executado somente uma vez, para geração do xml, após recomendo que comente a linha com a chamada do método.
Figura 8 DataSet Gerado
O próximo passo é trabalhar nosso Report, para isso clique com o botão direito sobre a pasta Report-> Add New Item... Report. Em nosso projeto, chamaremos o report de ReportEmpregado, confira na Figura 9.
Figura 9 Adicionando o Report
Com o Report aberto expanda ToolBox e arraste uma Table, o visual Studio irá solicitar vinculação de um dataset, a figura 10 exibe a tela de vinculação. Escolha nosso DataSet criado para vincular a Table. Note que se estiver utilizando o Visual Studio 2008, o procedimento para vincular o DataSet ao Report é diferente, para isso vá em Report, na barra de ferramentas, selecione DataSources e escolha o datasource desejado.
Figura 10 Vinculando DataSet
Em sua Table adicione os campos e seus valores, basta clicar sobre a célula, selecionar Expression e então utilizar a Expressão =Fields![NomeCampo].Value, onde [NomeCampo] corresponde ao nome do campo que deseja exibir, conforme a Figura 11. O report possui inúmeras funções que possibilitam a manipulação de dados, como somar, contar, formatação de dados, vale a pena conferir.
Figura 11 Adicionando valores às colunas
Voltando ao nosso evento no código da Default.aspx.cs adicionaremos algumas linhas de código, para vincular o dataset e o report ao ReportViewer da pagina, assim poderemos executar nossa pesquisa e visualizar o relatório. A primeira coisa a fazer é criar um objeto do tipo ReportDataSource e vinculá-lo ao DataSet, utilizaremos duas propriedades do objeto: Name e Value. Name receberá o nome dado ao DataSet no momento da criação da Table no report, em nosso projeto foi DataSetEmployees. Value receberá o objeto de nosso DataSet já populado anteriormente, na Listagem 4 podemos ver esta alteração.
Listagem 4 Criando o ReportDataSource
A seguir criamos uma string indicando o endereço do Report. Feito isto estamos finalizando nosso projeto, agora basta atribuir os objetos ao ReportViewer da Página. Para atribuir o datasource ao ReportViewer utilizaremos o método Add da ReportDataSourceCollection do Report, this.ReportViewer1.LocalReport.DataSources.Add. Por se tratar de uma Collection podemos atribuir quantos ReportDataSource quisermos. O endereço do report é adicionado por meio da propriedate ReportPath, this.ReportViewer1.LocalReport.ReportPath, veja a Listagem 5 para maior detalhe.
Listagem 5 Adicionando parâmetros ao ReportViewer
Agora basta executar o projeto e ver o resultado, a figura 12 exibe o relatório sendo gerado corretamente. Cada vez que clicamos no botão consultar nosso filtro é aplicado.
Listagem 6 Visualização do Relatório
Para criação de consultas personalizadas e criação de relatórios com Report sem precisar adicionar query diretamente nas propriedades do DataSet para vinculá-lo. A possibilidade de parametrizar o report dinamicamente via código facilita na hora de criar o DataSet e trabalhar com diferentes reports em um só ReportViewer, eliminando a necessidade de criar varias paginas para cada report. Lembre-se que o ReportViewer possui varias propriedades e vale a pena explorá-las.
É na hora de implementar programaticamente que separam-se meninos e adultos.
ResponderExcluirO mercado tá cheio de gente que se diz profissional mas não faz idéia do que acontece por trás do clica e arrasta.
Parabéns pelo post!
Este comentário foi removido pelo autor.
ExcluirParabens pelo post, era exactamente isto que eu precisava....
ResponderExcluirCumprimentos
Fiz esse seu exemplo no meu sistema e no final tá me retornando a seguinte mensagem:
ResponderExcluirA data source instance has not been supplied for the data source 'DataSet1'.
Esse "DataSet1" deve ser o mesmo nome do dataset que voce criou para o report. No código do post é o "DataSetEmployees"
ExcluirFernando tenho um relatorio que adicionei um tabeladapter e adicionei os campos dele ao report, mais queria alterar o select do tableadapter dinamicamente eu teria como fazer isso, tipo assim, tenho um radiobuttonlist onde seleciono 1 - aberto 2 - concluido onde conforme a opção altero no select o where de um campo data para is null ou not null.
ResponderExcluirFernando segui o seu passo a passo sendo que qdo vou vincular o dataset criado ou report ele não me dá a opção de seleciona-lo, estou usando o vs2010, qdo clico em reportdata e new dataset o dataset criado nao aparece na lista, como faço para ele aparecer ?
ResponderExcluirJunior, boa tarde!
ExcluirObservei que estou com mesmo problema, conseguiu solucionar?
Sds,
Diego
Fernando, Parabéns pelo tutorial. Obrigado
ResponderExcluirAdicionei uma linha ao código do método do Button1_click
ResponderExcluirthis.ReportViewer1.LocalReport.DataSources.Clear();
no meu caso o DataSource não atualizava entre um filtro e outro. Fiz isso e tudo ok.
Fernando, segui todo o passo a passo, mas quando crio o report não consigo visualizar o dataset criado. O que posso ter feito de errado?
ResponderExcluirestou com este mesmo problema, conseguiu resolver?
ExcluirFernando, quando aplico o filtro este nao funciona. Ja conferi o codigo esta igual, como posso faze-lo
ResponderExcluirURGENTE por favor como fazer isso em crystalreport com vs 2010?
ResponderExcluirMuito bom o post, parabéns.
ResponderExcluirOlá, qual é o comando para windows form referente a Server.MapPath?
ResponderExcluirÓtimo tutorial. Mas eu preciso fazer isso com MVC 3 + Razor. Vc em algum tutorial para indicar, só acho com configuração prontas e não programando igual ao seu.
ResponderExcluirOlá como coloco subtotal de uma coluna por página e um total geral na ultima página.
ResponderExcluirShow de bola.
ResponderExcluirEstou utilizando esse código em um projeto windowsForms, só que não estou conseguindo criar dinamicamente o dataSet porque o método .WriteXmlSchema() não aceita os parâmetros passados no código.
como que faço para criar um dataSet no WindowsForms ?
dificuldade está nessa linha abaixo
// Cria um dataSet físico no projeto
// DataSetEmpregados.WriteXmlSchema(parâmetros.);
obrigado
Como faço para conseguir este projeto pois não conseguir criar um e estou precisando urgentemente.
ResponderExcluirMeu Email: adao_lucas_2020@hotmail.com
desde já agradeço.
aaaah, mentira que é WEB cara =/
ResponderExcluirto faz 2 semanas procurando um relatorio dinamico em codigo..e agora que acho ta web :(
alguem sabe uma versao em form?
Obrigada Fernando, seu post ajudou bastante!
ResponderExcluirAbraço!