André Alves de Lima

Talking about Software Development and more…

Trabalhando com múltiplas tabelas no Report Viewer através da expressão Lookup

Quem trabalha com o Report Viewer provavelmente já sabe que ele não permite a exibição de dados vindos de múltiplas tabelas em um único controle. Isso quer dizer que, se você quiser exibir dados de mais de uma tabela em um controle Tablix, você terá que partir para alguma alternativa.

A alternativa mais utilizada é a consolidação dos dados em uma única DataTable (ou classe) que servirá como fonte de dados para os nossos relatórios. Porém, essa não é a melhor das alternativas, uma vez que teremos que potencialmente construir DataSets e DataTables customizados para cada relatório do nosso sistema.

O que pouca gente conhece é que existe a expressão “Lookup” no Report Viewer, que nos permite justamente pegar informações de outras tabelas. No artigo de hoje eu vou mostrar para você como utilizar essa expressão. Você quer deixar os seus relatórios do Report Viewer mais simples? Então continue lendo e veja como a expressão “Lookup” pode simplificar consideravelmente os seus relatórios.

Entendendo o problema

Antes de apresentar a solução, vamos entender o problema? Para isso, vamos criar um exemplo onde temos que desenvolver um relatório que exibirá dados vindos de múltiplas tabelas. Temos inúmeros cenários onde isso se faz necessário, mas, para não complicarmos muito, preparei um exemplo bem simples para que vocês possam entender mais facilmente.

Imagine que a nossa tarefa seja gerar um relatório sobre uma entidade chamada “Pessoa” em um sistema de Recursos Humanos. Essa entidade, além das propriedades habituais, tem também uma ligação com a entidade “Empresa” (a pessoa trabalha em algum lugar) e outra ligação com a entidade “Cargo” (ela ocupa uma determinada posição nessa empresa).

Para simularmos essa estrutura, vamos começar criando um novo projeto do tipo “Windows Forms Application“. Dentro desse projeto, adicione um novo DataSet tipado (dando o nome de “DataSetPessoa“) com as seguintes tabelas, colunas e relacionamentos:

Aproveitando que temos um DataSet tipado, vamos dar um duplo clique para implementarmos um método que alimentará esse DataSet com alguns dados de exemplo. Obviamente, em um sistema “de verdade” você teria que ler esses dados do banco:

    // C#
    partial class DataSetPessoa
    {
        public void PreencherComDadosDeExemplo()
        {
            var abcdev = this.Empresa.AddEmpresaRow("abcdev", "AA Lima Dev EPP", "99.999.999/9999-99");
            var microsoft = this.Empresa.AddEmpresaRow("Microsoft", "Microsoft BR Ltda", "99.999.999/9999-99");
            var google = this.Empresa.AddEmpresaRow("Google", "Google Brasil S/A", "99.999.999/9999-99");

            var analista = this.Cargo.AddCargoRow("Analista de Sistemas", "XXX");
            var arquiteto = this.Cargo.AddCargoRow("Arquiteto de Sistemas", "YYY");
            var diretor = this.Cargo.AddCargoRow("Diretor Administrativo", "ZZZ");

            this.Pessoa.AddPessoaRow("Andre", "Lima", new System.DateTime(1984, 1, 1), abcdev, analista, "999.999.99-99");
            this.Pessoa.AddPessoaRow("Larissa", "Lima", new System.DateTime(1987, 2, 2), abcdev, diretor, "999.999.99-99");
            this.Pessoa.AddPessoaRow("Fulano", "de Tal", new System.DateTime(1978, 3, 3), microsoft, arquiteto, "999.999.99-99");
            this.Pessoa.AddPessoaRow("Paula", "Bellizia", new System.DateTime(1970, 4, 4), microsoft, diretor, "999.999.99-99");
            this.Pessoa.AddPessoaRow("Fabio", "Coelho", new System.DateTime(1968, 5, 5), google, diretor, "999.999.99-99");
        }
    }
' VB.NET
Partial Class DataSetPessoa
    Public Sub PreencherComDadosDeExemplo()
        Dim Abcdev = Me.Empresa.AddEmpresaRow("abcdev", "AA Lima Dev EPP", "99.999.999/9999-99")
        Dim Microsoft = Me.Empresa.AddEmpresaRow("Microsoft", "Microsoft BR Ltda", "99.999.999/9999-99")
        Dim Google = Me.Empresa.AddEmpresaRow("Google", "Google Brasil S/A", "99.999.999/9999-99")

        Dim Analista = Me.Cargo.AddCargoRow("Analista de Sistemas", "XXX")
        Dim Arquiteto = Me.Cargo.AddCargoRow("Arquiteto de Sistemas", "YYY")
        Dim Diretor = Me.Cargo.AddCargoRow("Diretor Administrativo", "ZZZ")

        Me.Pessoa.AddPessoaRow("Andre", "Lima", New System.DateTime(1984, 1, 1), Abcdev, Analista, "999.999.99-99")
        Me.Pessoa.AddPessoaRow("Larissa", "Lima", New System.DateTime(1987, 2, 2), Abcdev, Diretor, "999.999.99-99")
        Me.Pessoa.AddPessoaRow("Fulano", "de Tal", New System.DateTime(1978, 3, 3), Microsoft, Arquiteto, "999.999.99-99")
        Me.Pessoa.AddPessoaRow("Paula", "Bellizia", New System.DateTime(1970, 4, 4), Microsoft, Diretor, "999.999.99-99")
        Me.Pessoa.AddPessoaRow("Fabio", "Coelho", New System.DateTime(1968, 5, 5), Google, Diretor, "999.999.99-99")
    End Sub
End Class

E agora? Como poderíamos fazer para montarmos um relatório que lista as pessoas desse DataSet, porém, incluindo as informações da empresa onde ela trabalha e as informações do cargo que ela ocupa?

Primeira alternativa: juntando tudo em uma única tabela

A primeira alternativa para resolvermos essa situação (e a mais utilizada) é criarmos um novo DataSet (ou classe) juntando todas as colunas que queremos exibir no relatório em uma única tabela. Ou seja, no nosso caso, teríamos somente uma tabela com todas as informações da Pessoa, Empresa e Cargo.

Para implementarmos essa alternativa, vamos adicionar um segundo DataSet tipado no nosso projeto (dando o nome de “DataSetRelatorio“), que deverá conter a seguinte tabela:

Vamos também dar um duplo clique no DataSet para criarmos um método que receberá uma instância de “DataSetPessoa” e juntará tudo na tabela unificada:

    // C#
    partial class DataSetRelatorio
    {
        public DataSetRelatorio(DataSetPessoa dsPessoa)
        {
            foreach (var pessoa in dsPessoa.Pessoa)
            {
                this.Pessoa.AddPessoaRow(
                    pessoa.PessoaID,
                    pessoa.Nome,
                    pessoa.Sobrenome,
                    pessoa.DataNascimento,
                    pessoa.EmpresaID,
                    pessoa.CargoID,
                    pessoa.CPF,
                    pessoa.EmpresaRow.NomeFantasia,
                    pessoa.EmpresaRow.RazaoSocial,
                    pessoa.EmpresaRow.CNPJ,
                    pessoa.CargoRow.Nome,
                    pessoa.CargoRow.Descricao);
            }
        }
    }
' VB.NET
Partial Class DataSetRelatorio
    Public Sub DataSetRelatorio(DsPessoa As DataSetPessoa)
        For Each PessoaRow In DsPessoa.Pessoa
            Me.Pessoa.AddPessoaRow(
                    PessoaRow.PessoaID,
                    PessoaRow.Nome,
                    PessoaRow.Sobrenome,
                    PessoaRow.DataNascimento,
                    PessoaRow.EmpresaID,
                    PessoaRow.CargoID,
                    PessoaRow.CPF,
                    PessoaRow.EmpresaRow.NomeFantasia,
                    PessoaRow.EmpresaRow.RazaoSocial,
                    PessoaRow.EmpresaRow.CNPJ,
                    PessoaRow.CargoRow.Nome,
                    PessoaRow.CargoRow.Descricao)
        Next
    End Sub
End Class

Com esse DataSet em mãos, podemos simplesmente criar um novo relatório baseado nessa DataTable unificada. Vamos dar o nome de “RelatorioPessoa” para esse novo relatório:

Dentro desse relatório, vamos adicionar um componente do tipo “Table“. Quando fazemos isso, o Visual Studio automaticamente nos perguntará as informações sobre o DataSet que deverá alimentar essa tabela. Nessa janela, vamos dar o nome de “DataSetPessoa” para o DataSet que será criado e vamos escolher a tabela “Pessoa” do nosso “DataSetRelatorio“:

Em seguida, vamos arrastar cada uma das colunas do DataSet para dentro da tabela:

O resultado final deverá ficar parecido com a imagem abaixo:

Por fim, vamos até o nosso formulário, onde arrastaremos um controle visualizador do Report Viewer para dentro do formulário e escolheremos o relatório que acabamos de criar:

No code-behind do formulário, vamos criar os DataSets que serão passados para o relatório:

        // C#
        private void Form1_Load(object sender, EventArgs e)
        {
            var dsPessoa = new DataSetPessoa();
            dsPessoa.PreencherComDadosDeExemplo();
            var dsRelatorio = new DataSetRelatorio(dsPessoa);

            this.reportViewer1.LocalReport.DataSources.Clear();
            this.reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("DataSetPessoa", (DataTable)dsRelatorio.Pessoa));
            this.reportViewer1.RefreshReport();
        }
    ' VB.NET
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim DsPessoa As New DataSetPessoa()
        DsPessoa.PreencherComDadosDeExemplo()
        Dim DsRelatorio As New DataSetRelatorio(DsPessoa)

        Me.ReportViewer1.LocalReport.DataSources.Clear()
        Me.ReportViewer1.LocalReport.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DataSetPessoa", DirectCast(DsRelatorio.Pessoa, DataTable)))
        Me.ReportViewer1.RefreshReport()
    End Sub

Pronto! Execute a aplicação e confira o resultado:

Obviamente o relatório poderia ser melhor formatado, mas, como esse não é o foco desse artigo, resolvi deixa-lo com a formatação padrão.

Alternativa mais simples: múltiplas tabelas + expressão Lookup

Como vimos na seção anterior, para exibirmos dados de múltiplas tabelas no Report Viewer, nós podemos criar um novo DataSet (ou classe) juntando todos os dados em uma só estrutura. Apesar de essa alternativa resolver o problema, muitas vezes ela acaba sendo um tanto quanto custosa. Imagine se o nosso sistema tiver diversos relatórios e todos eles tiverem que exibir dados de múltiplas tabelas? Teríamos que criar um DataSet novo para cada relatório, o que seria possível, mas, impraticável.

Uma alternativa mais simples seria trabalharmos com vários DataSets no mesmo relatório, sendo que um DataSet apontaria para a tabela “principal” (no nosso caso a tabela “Pessoa“) e os outros DataSets seriam as tabelas de “Lookup” (no nosso caso as tabelas “Empresa” e “Cargo“). Então, através da função “Lookup“, nós conseguimos pegar dados das tabelas de “Empresa” e “Cargo” no nosso relatório (seria a mesma ideia do PROCV ou VLOOKUP do Excel).

Para vermos como ficaria essa alternativa, vamos criar uma cópia do “RelatorioPessoa“, dando o nome de “RelatorioPessoaMultiplasTabelas“. Dentro desse relatório, vamos excluir o DataSet que tínhamos criado no relatório original (o “DataSetPessoa“) e vamos adicionar três novos DataSets, cada um apontando para uma tabela do nosso DataSetPessoa:

Em seguida, vamos alterar o DataSource da nossa tabela, de forma que ele aponte para o DataSet “Pessoa“:

E agora é que vem o segredo. Como é que conseguimos pegar os dados da Empresa, uma vez que o DataSet da tabela não tem essas informações? Simples, através da expressão Lookup! Por exemplo, para pegarmos o nome fantasia da empresa, a expressão ficaria assim:

=Lookup(Fields!EmpresaID.Value, Fields!EmpresaID.Value, Fields!NomeFantasia.Value, "Empresa")

O primeiro parâmetro dessa expressão deve ser o nome do campo na tabela de origem (campo “EmpresaID” da tabela “Pessoa“). Já o segundo parâmetro corresponde ao nome do campo na tabela destino (no nosso caso, “EmpresaID“, que é o nome do campo chave na tabela “Empresa“). Ou seja, esses dois primeiros parâmetros indicam os campos de relacionamento entre a tabela origem e a tabela destino.

Em seguida, o terceiro parâmetro deve conter o nome que você quer pegar na tabela de destino. Nesse caso, queremos pegar o campo “NomeFantasia“. Por fim, no último parâmetro nós temos que indicar o nome da tabela de lookup (nesse caso, “Empresa“).

Fácil, não? Veja só como fica a expressão para os outros campos:

' Razão social:
=Lookup(Fields!EmpresaID.Value, Fields!EmpresaID.Value, Fields!RazaoSocial.Value, "Empresa")
' CNPJ
=Lookup(Fields!EmpresaID.Value, Fields!EmpresaID.Value, Fields!CNPJ.Value, "Empresa")
' Nome do Cargo
=Lookup(Fields!CargoID.Value, Fields!CargoID.Value, Fields!Nome.Value, "Cargo")
' Descrição do Cargo
=Lookup(Fields!CargoID.Value, Fields!CargoID.Value, Fields!Descricao.Value, "Cargo")

Agora que já temos o nosso novo relatório, vamos criar um novo formulário para exibi-lo (Form2). Como fizemos no primeiro formulário, nós temos que adicionar um controle exibidor do Report Viewer, só que dessa vez nós selecionaremos o nosso novo relatório (“RelatorioPessoaMultiplasTabelas“). No code-behind, nós não temos mais que criar um DataSetRelatorio, mas sim, temos que passar cada uma das tabelas para o relatório em DataSources diferentes:

        // C#
        private void Form2_Load(object sender, EventArgs e)
        {
            var dsPessoa = new DataSetPessoa();
            dsPessoa.PreencherComDadosDeExemplo();

            this.reportViewer1.LocalReport.DataSources.Clear();
            this.reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("Pessoa", (DataTable)dsPessoa.Pessoa));
            this.reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("Empresa", (DataTable)dsPessoa.Empresa));
            this.reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("Cargo", (DataTable)dsPessoa.Cargo));
            this.reportViewer1.RefreshReport();
        }
    ' VB.NET
    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim DsPessoa = New DataSetPessoa()
        DsPessoa.PreencherComDadosDeExemplo()

        Me.ReportViewer1.LocalReport.DataSources.Clear()
        Me.ReportViewer1.LocalReport.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("Pessoa", DirectCast(DsPessoa.Pessoa, DataTable)))
        Me.ReportViewer1.LocalReport.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("Empresa", DirectCast(DsPessoa.Empresa, DataTable)))
        Me.ReportViewer1.LocalReport.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("Cargo", DirectCast(DsPessoa.Cargo, DataTable)))
        Me.ReportViewer1.RefreshReport()
    End Sub

Por fim, vamos alterar o objeto de inicialização para que o nosso Form2 seja exibido (ao invés do Form1). Em projetos C#, fazemos isso no arquivo Program.cs:

Application.Run(new Form2());

Já no VB.NET, temos que alterar o “Startup Form” nas propriedades do projeto:

Pronto! Execute o projeto e veja que o resultado é idêntico ao primeiro relatório:

Concluindo

Quando estamos desenvolvendo relatórios para as nossas aplicações, não é tão difícil nos depararmos com uma situação em que precisamos de dados vindos de múltiplas tabelas. Como o Report Viewer não suporta a exibição de dados de mais de uma tabela no mesmo controle e também não tem o conceito de relacionamentos entre tabelas (como temos no Crystal Reports), a saída mais utilizada é a criação de um segundo DataSet (ou classe) onde todos os dados são consolidados em uma única DataTable.

Apesar dessa alternativa ser a mais utilizada, ela não é a mais ideal. O que pouca gente sabe é que nós podemos utilizar a expressão Lookup para pegarmos dados de outras tabelas no Report Viewer. Esse procedimento é muito mais simples do que termos que criar um DataSet consolidado para cada relatório.

No artigo de hoje você conferiu essas duas alternativas para a exibição de dados vindos de múltiplas tabelas no Report Viewer. Como você pode perceber, o resultado é idêntico, então, não pense duas vezes se você puder utilizar a expressão Lookup nos seus relatórios, que é muito mais prática.

E você, já passou por essa situação onde você tinha que exibir dados de múltiplas tabelas no Report Viewer? Se sim, como é que você resolveu? Você já conhecia a expressão Lookup? Conte-nos mais detalhes na caixa de comentários!

Por fim, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário logo abaixo.

Até a próxima!

André Lima

Image by Jake Przespo used under Creative Commons
https://www.flickr.com/photos/jakeprzespo/4566115233/

Newsletter do André Lima

* indicates required



Powered by MailChimp

33 thoughts on “Trabalhando com múltiplas tabelas no Report Viewer através da expressão Lookup

  • Will Batista disse:

    Olá André, realmente a expressão Lookup é muito útil, eu mesmo não sabia dessa alternativa. Sempre que precisava de dados de múltiplas tabelas tinha que criar Datasets tipados já com as informações das outras tabelas. Sempre me perguntei, como utilizar no Report Viewer as relações, que podem serem criadas, entre as tabelas.
    Muito obrigado por compartilhar mais essa dica. Tenho certeza que, além de mim, irá ajudar muitos programadores.
    Abraço.

    • andrealveslima disse:

      Olá Will, obrigado pelo comentário!

      Pois é, também demorou bastante tempo para eu conhecer essa expressão Lookup e inúmeras vezes eu também construi DataSets customizados para os relatórios, como você mencionou.. Inclusive tenho vários artigos sobre o Report Viewer onde eu ainda utilizava essa técnica de juntar tudo em uma DataTable só..

      Vivendo e aprendendo.. Espero que fique documentado aqui e que ajude a simplificar o relatório de outras pessoas também.. :)

      Abraço!
      André Lima

  • Edward Gómez disse:

    Buen día para todos,

    André, como siempre muy buena información y sobre todo la utilidad que brinda para conocer mejor el manejo de varias tablas para los reportes, debido a que en muchos casos la información se encuentra pero no es muy clara para comprender.

    Saludos desde Colombia,

    Un abrazo.

    • andrealveslima disse:

      Olá Edward, muito obrigado pelo comentário! Fico feliz que você tenha gostado.. :)

      Realmente essa função Lookup é muito útil e, mesmo assim, pouco utilizada.. Em inúmeras situações eu já criei datasets ou classes customizadas para alimentar o relatório, sendo que eu poderia ter simplesmente utilizado essa expressão Lookup, que deixaria o relatório e a aplicação menos complicadas..

      Um grande abraço!
      André Lima

  • Erik Janson Vieira Coelho disse:

    Desculpe a ignorância, mas onde é colocada esta expressão LOOKUP?

    • andrealveslima disse:

      Olá Erik!

      A expressão Lookup deve ser inserida no campo (TextBox, por exemplo) onde você quer exibir o conteúdo da outra tabela.. É só clicar com o botão direito no TextBox e escolher a opção “Expression”.. Para mais informações sobre como trabalhar com expressões no Report Viewer, confira este outro artigo:

      Utilizando expressões no Report Viewer

      Abraço!
      André Lima

    • andrealveslima disse:

      Olá Erik! Deu certo aí a expressão Lookup? Conseguiu utilizá-la no seu relatório?

      Abraço!
      André Lima

  • Neto disse:

    André, boa noite.

    Poderia me ajudar?

    Fiz exatamente como vc passou, mas por algum motivo a expressão:
    dsPessoa.PreencherComDadosDeExemplo();

    Está dando erro no Preencher….
    Não localiza a expressão.

    Como faço para arrumar?

  • Lério Sindane disse:

    Bom dia
    Grande Adré

    Grande Dica Mesmo
    Grande Dica

    Ainda não conhecia a expressão Lookup.

    Já estava para fechar o meu projecto que vinhas me ajudando.
    Mas Restruturei toda minha base de dados graças a esse conteudo acima.
    Achei mais elegante e simples do que criar novas tabelas para cada reporte.
    Valeu Mesmo.

    Muito obrigado
    Mesmo Mesmo, meu cara.

    Mas não estou a saber onde colocar a expressãp look up no tablix

    • andrealveslima disse:

      Olá Lério!

      Não entendi a sua dúvida.. Você coloca a expressão “Lookup” no controle onde você quer exibir dados de outra tabela.. Me manda mais detalhes aqui ou por e-mail mostrando o que você quer exibir de qual tabela para eu entender melhor..

      Abraço!
      André Lima

  • lerio.sindane disse:

    Já consegui

    muito obrigado
    Como sempre excelente explicação

    • andrealveslima disse:

      Olá Lério! Que bom que conseguiu resolver.. Quero ver se consigo responder hoje o seu e-mail com a sua outra dúvida, OK?

      Abraço!
      André Lima

  • Airton disse:

    Olá André, bom dia!

    Com relação a chaves compostas como deve ser feito? Concatenar os campos é a solução?

    Abraços

    • andrealveslima disse:

      Olá Airton!

      Que eu saiba, para chaves compostas a única solução é, como você falou, concatenar as informações em uma única coluna..

      Se você estiver alimentando o relatório com DataSets, você pode criar colunas calculadas nas duas DataTables que farão a concatenação das informações para você, aí no relatório você usa essa coluna calculada como “join” entre as tabelas.. Se estiver alimentando com classes, você pode criar uma propriedade só com um “get” retornando o resultado da concatenação.. Ou você pode também fazer a concatenação direto na expressão do relatório, caso você não queira alterar nada na sua estrutura de dados..

      Abraço!
      André Lima

  • Valdemar Paulo disse:

    Olá André!
    Acho que é isso que estava a faltar no projecto, porem eu tenho um problema maior, ou seja eu pretendo imprimir as informações de da tabela matriculas só que a tabela NomeEmpresa não migrou como estrangeira na tabela Matriculas.
    Neste caso o que faço, porque o meu objectivo é criar um cabeçario dinâmico onde o usuário pode alterar a qualquer hora!

    Já a gora não sei o que se passa com o outro link! do Reports porque não consigo acede-la. Abraço.

    • andrealveslima disse:

      Olá Valdemar!

      Cara, não entendi o que você quis dizer nesse último comentário.. “A tabela NomeEmpresa não migrou como estrangeira na tabela Matriculas”.. O que isso tem a ver com o relatório? Você pode passar as duas tabelas para o relatório e fazer o relacioamento diretamente nele (na janela de Database Expert)..

      Por favor, me explica melhor (e detalhadamente) o seu problema atual para eu tentar te ajudar.. Tá ficando difícil de acompanhar.. :)

      Abraço!
      André Lima

  • Valdemar Paulo disse:

    Olá André!
    é mesmo isso quanto a questão das permissões de login do Crystal Reports, optei trabalhar como desiste outro hora trabalhar num dataset fiquei mesmo com este porem vi esta:
    Trabalhando com múltiplas tabelas no Report Viewer através da expressão Lookup
    percebi que esta é exactamente o que precisava para unir o relatório,

    será que também da certo em Crystal Reports?

    • andrealveslima disse:

      Olá Valdemar!

      No Crystal Reports você não precisa de algo parecido com a expressão de Lookup do Report Viewer, uma vez que você consegue utilizar dados de múltiplas tabelas sem problema nenhum.. Você só precisa ajustar os relacionamentos na janela Database Expert.. Tem um artigo meu sobre Crystal Reports com Entity Framework onde eu utilizei múltiplas tabelas no mesmo relatório.. Veja:

      Gerando relatórios do Crystal Reports com Entity Framework

      Abraço!
      André Lima

      • Valdemar Paulo disse:

        Olá André!
        Pelo que eu vi la elas estão ligadas, mas no meu caso a tabela empresa não esta ligada com nenhuma tabela simplesmente preparei ela aparte para o cabeçario não imaginava migra-la para as demais

        • Valdemar Paulo disse:

          Eu já consigui ultrapassar a dificuldade de impressão, ela imprimi sem problema, as tuas explicações ajudaram muito, o que eu pretendo é se tiver que instalar numa outra entidade não preciso trocar nada no aplicativo. Por Ex. A empresa hoje chama-se Graças & Filhos amanhã Irmão em Graças, porque pediram-me para aplicar em mais de um local e todas com nomes diferentes.

          • andrealveslima disse:

            Olá Valdemar!

            Se são somente dados para o cabeçalho, desconectados com o resto da estrutura do relatório, na minha opinião faria mais sentido passar essas informações via parâmetro para o relatório.. Você pode passar o nome da empresa normalmente via parâmetro e depois você exibe ele no cabeçalho do relatório.. Eu já fiz um exemplo disso neste artigo:

            Passando parâmetros para relatórios do Crystal Reports com C#

            Abraço!
            André Lima

          • Valdemar Paulo disse:

            Ola André!
            Obrigado pela dica valeu muito, tem um problema quando eu coloco o dataset com o parameto ele retoma o relatório em branco… O que, se eu usar o dataset ela imprime, se for só o parameto também imprimi mais juntos da em branco.

          • andrealveslima disse:

            Olá Valdemar!

            Atenção.. Parâmetros do DataSet e parâmetros do relatório são duas coisas completamente diferentes.. O que eu estou sugerindo é trabalhar com parâmetros do relatório, e não do DataSet (que aparentemente é o que você entendeu).. Dê uma olhada com calma no artigo daquele link que te passei e tente implementar daquela forma..

            Abraço!
            André Lima

          • Valdemar Paulo disse:

            André!
            Obrigado Pela atenção, vou fazer isso.

          • Valdemar Paulo disse:

            Ola André!
            Conforme disseste consegui resolver a situação,
            como faço para inserir a imagem gravada no banco de dados via Parâmetros?

          • andrealveslima disse:

            Olá Valdemar!

            No caso de imagens você não consegue passar o conteúdo binário delas através de parâmetros, mas você pode salvar os logotipos em disco e passar o caminho adequado via parâmetro, conforme explicado nesta thread do StackOverflow:

            How do I load images dynamically in Crystal Reports XI

            Abraço!
            André Lima

  • William Deivid disse:

    André, e como funciona as funções LookupSet e MultiLookup?
    Um problema que estou tendo é quando uso um filtro numa tabela e o first, o first não está levando em conta o filtro. Pelo que li na documentação ele deveria ser aplicado depois do filtro.

    • andrealveslima disse:

      Olá William!

      As funções LookupSet e MultiLookup são meio que extensões da expressão Lookup para trabalhar com múltiplos dados (retornando mais de um resultado por linha, que você pode juntar com a expressão “Join”).. Na própria documentação do Reporting Services tem exemplos muito bem explicativos sobre essas funções:

      Report Builder Functions – LookupSet Function

      Report Builder Functions – Multilookup Function

      Já quanto ao seu problema com o “First”, não sei o que pode estar acontecendo.. Você está filtrando tanto a tabela (Tablix) quando os dados na parte de agrupamento (naquela janela inferior onde temos os detalhes dos agrupamentos)?

      Abraço!
      André Lima

  • Vanderson Oliveira dos Santos disse:

    Olá André, realmente a expressão Lookup é muito útil.Porém fiz todos os passos do tutorial, refiz varias vezes e não estou conseguindo pegar o segundo parâmetro ou seja o ID da tabela que esta relacionada com minha tabela que quero usar no relatório.
    Sou uma observação estou usando Entity Framework para fazer conexão.

    • andrealveslima disse:

      Olá Vanderson!

      Você está reconstruindo exatamente o mesmo relatório apresentado no artigo ou você está tentando adapta-lo para o seu cenário? Caso esteja tentando adaptar, tente primeiramente o exemplo do artigo para entender completamente o conceito, depois você tenta adaptar para o seu cenário..

      Abraço!
      André Lima

  • Hermógenes Neto disse:

    Ótima explicação, muito boa mesmo, muito obrigado, tem me ajudado muito!!!

Deixe uma resposta

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