André Alves de Lima

Talking about Software Development and more…

Gerando relatórios do Crystal Reports com Entity Framework

Umas semanas atrás eu escrevi um artigo mostrando como alimentar relatórios do Report Viewer com o Entity Framework. Aí eu parei e pensei: será que dá para utilizar o Entity Framework com o Crystal Reports também? Depois de pesquisar um pouco e fazer uns testes, cheguei à conclusão que sim, é possível! Prepare-se para aprender com este artigo, como gerar relatórios do Crystal Reports com Entity Framework.

Criando o modelo de dados

A utilização das entidades do Entity Framework em relatórios criados com o Crystal Reports no Visual Studio é até mais tranquilo que o Report Viewer. Antigamente era preciso fazer uma gambiarra, convertendo as entidades em DataSet, porém, hoje em dia o Crystal Reports suporta as entidades do Entity Framework de forma nativa. Para demonstrar essa possibilidade, vamos utilizar um projeto do tipo “Windows Forms Application” e o mesmo modelo de dados do artigo sobre o Entity Framework com Report Viewer:

Não vou repetir todo o procedimento novamente neste artigo. Para saber como criar o modelo de dados que será utilizado neste artigo, confira a seção “Criando o modelo de dados” do artigo sobre Entity Framework com Report Viewer.

Desenhando o relatório

Uma vez criado o modelo de dados, vamos adicionar um novo relatório ao nosso projeto, dando o nome de “RelatorioPedido“. Os relatórios do Crystal Reports estão disponíveis dentro da categoria “Reporting“:

Quando o Crystal Reports perguntar o tipo de relatório que queremos criar, escolha a opção “relatório em branco“:

Assim que o relatório em branco tiver sido criado, vá até a aba “Field Explorer“, clique com o botão direito sobre “Database Fields” e escolha a opção “Database Expert“:

É justamente na janela “Database Expert” que vamos configurar a fonte de dados para o nosso relatório. No caso do Report Viewer, nós criamos uma classe que representava os dados do relatório. Nós poderíamos fazer o mesmo com o Crystal Reports, mas, isso não é obrigatoriamente necessário, uma vez que o Crystal Reports permite que nós adicionemos várias tabelas em um único relatório, desde que nós especifiquemos os relacionamentos entre elas.

Dito isso, encontre os objetos do nosso modelo (Cliente, ItemPedido, Pedido e Produto) dentro da seção “Project Data / .NET Objects” e adicione-os na parte de “Selected Tables“:

Em seguida, temos que ir até a aba “Links” para ajustarmos os relacionamentos entre as tabelas. Como o Crystal Reports cria os relacionamentos entre as tabelas ItemPedido e Pedido e entre as tabelas Pedido e Cliente com a direção errada, temos que recriá-los, conforme você pode conferir neste gif animado:

Agora que já temos a fonte de dados devidamente configurada, vamos criar um novo agrupamento no nosso relatório. Como você pode observar no diagrama do modelo, teremos informações dos pedidos na parte “mestre” do relatório e informações dos itens de pedido na parte “detalhe” do relatório. Portanto, temos que agrupar os dados pelo ID do Pedido. Para isso, clique com o botão direito sobre “Group Name Fields” e escolha a opção “Group Expert“:

Na janela de criação do grupo, escolha o campo “PedidoId” da tabela “Pedido“:

Antes de confirmar a criação do grupo, vá até a aba “Options” e configure a paginação do grupo (de forma que cada pedido seja impresso em uma página separada):

Agora é só desenhar o relatório com os dados do pedido no cabeçalho do agrupamento e os dados dos itens do pedido na área de detalhes. O resultado deve ficar parecido com a imagem abaixo:

Como nós não utilizamos o cabeçalho e o rodapé do relatório, nós podemos desabilita-los escolhendo a opção “Suppress” nas regiões “Report Header” e “Report Footer“:

Criando o formulário para a exibição do relatório

Com o relatório criado, agora só falta ajustarmos o formulário que fará a exibição do relatório. A primeira coisa que temos que fazer é adicionarmos o controle de exibição do Crystal Reports (disponível dentro da categoria “Reporting” da caixa de ferramentas). Feito isso, clique em “Choose a Crystal Report” e escolha o relatório que criamos anteriormente:

Não esqueça de alterar o nome do componente do relatório de “RelatorioPedido1” para “RelatorioPedido” (sem o “1” no final):

Vamos agora até o code-behind para passarmos os dados para o nosso relatório, o que é muito tranquilo de ser feito. Basta criarmos uma instância do nosso contexto do Entity Framework e chamarmos o método “SetDataSource” em cada uma das tabelas do nosso relatório, passando cada um dos DbSets do nosso contexto, só que convertidos para lista (método ToList):

        public FormCrystalComEF()
        {
            InitializeComponent();

            PopularBancoDeDadosSeNecessario();

            using (var contexto = new Contexto())
            {
                RelatorioPedido.Database.Tables["CrystalReportsEF_Models_Cliente"].SetDataSource(contexto.Clientes.ToList());
                RelatorioPedido.Database.Tables["CrystalReportsEF_Models_Produto"].SetDataSource(contexto.Produtos.ToList());
                RelatorioPedido.Database.Tables["CrystalReportsEF_Models_Pedido"].SetDataSource(contexto.Pedidos.ToList());
                RelatorioPedido.Database.Tables["CrystalReportsEF_Models_ItemPedido"].SetDataSource(contexto.ItensPedido.ToList());
            }
        }

Você encontra os nomes das tabelas na janela “Field Explorer” do relatório:

Muito tranquilo, não é mesmo? Vamos executar o projeto para ver se funciona? É claro que nunca funciona da primeira vez!

An unhandled exception of type ‘System.IO.FileNotFoundException’ occurred in mscorlib.dll
Additional information: Could not load file or assembly ‘file:///C:\Program Files (x86)\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Common\SAP BusinessObjects Enterprise XI 4.0\win64_x64\dotnet1\crdb_adoplus.dll’ or one of its dependencies. The system cannot find the file specified.

Essa exceção não tem nada a ver com a utilização do Crystal Reports com o Entity Framework. Ela acontece também com outros tipos de fontes de dados. O problema é, na verdade, com o .NET Framework 4.5. Para conseguirmos utilizar essa versão do .NET Framework com o Crystal Reports, temos que adicionar um atributo na tag “startup” do nosso app.config:

Dessa forma, abra o arquivo app.config do projeto onde o controle do Crystal Reports está sendo utilizado e ajuste a tag startup desta maneira:

  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>

Mais informações sobre este erro você encontra nesta thread do StackOverflow.

Pronto! Execute a aplicação novamente e veja o resultado, conforme esperado:

Concluindo

Alimentar relatórios do Crystal Reports com entidades do Entity Framework é muito tranquilo, até mais tranquilo do que com o Report Viewer, uma vez que não precisamos criar uma classe especial com os dados de todas as tabelas. Neste artigo você viu como criar um relatório mestre/detalhe no Crystal Reports baseado em quatro entidades do Entity Framework.

Você utiliza o Crystal Reports como ferramenta de relatórios nos seus projetos? Como você alimenta os seus relatórios? Com DataSets? Você sabia que dava para passar as entidades do Entity Framework diretamente para o seu relatório do Crystal Reports? Conte-nos a sua experiência nos comentários.

Antes de me despedir, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado, ficará sabendo em primeira mão sobre o artigo da próxima semana e receberá também dicas “bônus” que eu só compartilho por e-mail. Além disso, você já deve ter percebido que eu recebo muitas sugestões de temas e eu costumo dar prioridade às sugestões vindas de inscritos da minha newsletter. Inscreva-se utilizando o formulário logo abaixo.

Até a próxima!

André Lima

Image by Pixabay used under Creative Commons
https://pixabay.com/en/tax-forms-income-business-468440/

Newsletter do André Lima

* indicates required



Powered by MailChimp

12 thoughts on “Gerando relatórios do Crystal Reports com Entity Framework

  • duard disse:

    Eu estava começando a estudar aqui desenvolver relatórios com Entity Framework, porém, o VS2015 não está conseguindo funcionar bem com o Crystal Report. Criei uma aplicação zerada, apenas um dataSet para o banco ligado a uma tabela (id descricao) e fui executar e recebo erros bizarros.

    http://imgur.com/IxSHvfJ
    http://imgur.com/rIACWiW

    Neste momento estou realizando update no VS, e instalando o DotNet 3.5 no sistema, para ver se é algo relacionado a isto.

    Windows 10, VS2015.

  • duard disse:

    André,
    tentei esta solução, e me ocorre outro problema. O simples fato de adicionar um Crystal Report Viewer no projeto já faz ocorrer este problema ao executar uma simples aplicação.

    http://i.imgur.com/arqegWR.jpg

    Estou a manhã toda tentando criar um relatório tabular simples com Crystal Reports no Visual Studio 2015 (Windows 10) e nada, apenas erros.

    • andrealveslima disse:

      Olá Duard, obrigado pelo comentário..

      Como está a configuração de plataforma no seu projeto? x86, x64 ou Any CPU? Você instalou o runtime do Crystal tanto 32 bits quanto 64 bits? Pode ser que você esteja rodando, por exemplo, em x86 e só tem instalado a runtime 64 bits (que é o que o Crystal Reports instala automaticamente no final da instalação dos componentes do Visual Studio)..

      Abraço!
      André Lima

      • duard disse:

        Passei o dia todo quebrando a cabeça com isto ontem, sem resultados interessntes, e após assistir um vídeo seu onde você aponta que a parte de distribuição do CR é terrível, resolvi ir com o Report Viewer. Consegui um progresso já, acho que vai me atender bem, só me preocupa que mais à frente terei que fazer um relatório em impressora matricial (LX 300), quando o fiz em Delphi tive que fazer na unha, conversando com a impressora, mandando linha a linha montada via ASCII.

        Meu ambiente de desenvolvimento é Windows 10 64bits, Visual Studio 2015 atualizado, Entity Framework Code First com Mysql ;-)

        OFF-Post

        Neste exato momento, o que me está matando de agonia no Report Viewer é uma rebarba de borda, que não consigo eliminar dele, à direita e abaixo, sempre sobra 1px de borda, acho que é bug dele. Você sabe se tem como eliminar isto ?

        imagem da borda que sobra http://i.imgur.com/4Ngs3QK.png

        Sinto muita falta de propriedades de comportamento Align para os objetos inseridos dentro do RV, tipo a propriedade DOCK dos outros objetos que existem no ambiente fora do RV.

        Desde já muito obrigado pelo retorno, seu site tem bastante conteúdo que irei utilizar.

        • andrealveslima disse:

          Olá Duard!

          O Report Viewer é mais fácil de aprender mesmo.. Ele só começa a ficar difícil se você tiver que fazer relatórios muito complexos.. Se os relatórios forem simples listagens ou mestre/detalhe, o Report Viewer costuma atender bem..

          Se você ainda quiser tentar com o Crystal, eu checaria se você tem ambas as runtimes (x86 e x64) instaladas.. Aquela mensagem de erro é típica de quando você tem uma runtime instalada e o projeto sendo compilada em outra arquitetura..

          Enfim, quanto à impressão matricial, provavelmente você terá que imprimir direto na impressora mesmo.. O Carlos dos Santos desenvolveu uma biblioteca que facilita a impressão direta na LPT.. Talvez te ajude em algo:

          Impressão Matricial 2.0

          E esse esquema do 1px de borda sobrando no Report Viewer, está esquisito hein.. Nunca vi esse problema.. Se quiser mandar o projetinho pra eu dar uma olhada, manda para contato arroba andrealveslima ponto com ponto br.. Ah, e o negócio do dock realmente faz falta.. Mas, nunca vi esse tipo de coisa em ferramentas de relatórios (nem no Crystal).. Fazer o que..

          Abraço!
          André Lima

          • duard disse:

            Vou compactar aqui e te envio,
            como é Code First o banco deverá ser criado automaticamente.
            Este projetinho que enviarei é um paralelo ao oficial, onde eu faço testes para coisas novas que preciso fazer, brinco com componentes e outras bugigangas

          • andrealveslima disse:

            Olá Carlos,

            Recebi o seu projeto.. Assim que eu conseguir dar uma olhada nele, eu te aviso por e-mail..

            Abraço!
            André Lima

  • Carlos Eduardo disse:

    Olá novamente André,
    aparentemente, após uma reinstalação total do Windows 10 (agora estou usando a build nova, 14316), Visual Studio 2015 (demora mais para instalar do que um game tipo GTA V) e tudo mais, ENFIM, rodei um simples app form com o Report Viewer do Crystal Report.

    Agora irei tentar fazer um relatório tabular simples, minha dúvida e se você puder ajudar é sobre como fazer isto usando Code First da melhor maneira.

    Valeu.

    • andrealveslima disse:

      Olá Carlos!

      Na questão do relatório no Crystal, que eu saiba, não tem diferença se você está utilizando code first ou não.. De qualquer forma você vai ter as classes de modelo (no exemplo desse tutorial seriam as classes Cliente, Produto, Pedido e ItemPedido).. Aí é só escolher essas classes no Database Expert do Crystal Reports e seguir em frente com o relatório..

      Você chegou a tentar dessa forma? Caso você fique com alguma dificuldade, é só avisar..

      Abraço!
      André Lima

      • Carlos Eduardo disse:

        O problema era a conexão de dados André, que eu não achava como fazer, fui no chute aqui e escolhi uma opção que me deixava escolher um arquivo e escolhi a minha DLL/Project onde tem a conexao :-) e consegui fazer.

  • […] Como mencionado anteriormente, o objetivo desse artigo é mostrar coisas relacionadas à exportação dos relatórios do Crystal Reports. Dessa forma, criaremos um relatório extremamente simples em um projeto “Windows Forms“, que mostrará uma listagem de Clientes. Se você quiser dar uma olhada em um tutorial que mostra um relatório mais complexo do Crystal Reports, confira o meu artigo sobre Crystal Reports com Entity Framework. […]

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *