André Alves de Lima

Talking about Software Development and more…

Imprimindo múltiplas vias no Report Viewer

Alguns tipos de relatórios precisam ser impressos em múltiplas vias. Deixar a impressão das vias adicionais a cargo do usuário é um tiro no pé. Muito provavelmente ele esquecerá de configurar que o relatório deve ser impresso duas vezes e, todas as vezes que ele se esquecer disso, ele xingará mentalmente a empresa (ou desenvolvedor) que implementou aquele software sem a opção de imprimir múltiplas vias automaticamente.

Infelizmente não temos uma opção nativa que podemos configurar no Report Viewer de forma que ele imprima múltiplas vias do mesmo relatório. Porém, esse problema pode ser resolvido com algumas alterações na aplicação. No vídeo de hoje eu mostro para você três opções que podemos utilizar nos nossos projetos para imprimirmos múltiplas vias no Report Viewer:

Opção 1: Adicionando uma coluna “Via” no DataSet

Se você realmente tiver que exibir as duas vias no controle visualizador do Report Viewer (antes de realizar a impressão), ou se a primeira via for sutilmente diferente da segunda, aí não temos outra opção. Teremos que criar uma nova coluna no DataSet para representar o número da via:

Em seguida, nós temos que duplicar os dados da tabela que está alimentando o relatório (ou triplicar, quadruplicar, etc. – depende da quantidade de vias necessárias). No vídeo eu mostro um método que eu implementei para fazer a duplicação dos dados. Esse método recebe a DataTable original e retorna uma DataTable com “N” cópias das linhas:

        // C#
        private DataTable GerenciarVias(DataTable origem, string nomeColunaVia, int qtdVias)
        {
            var retorno = origem.Copy();

            for (var c = 2; c <= qtdVias; c++)
            {
                foreach (DataRow linha in origem.Rows)
                {
                    var novaLinha = retorno.NewRow();
                    novaLinha.ItemArray = (object[])linha.ItemArray.Clone();
                    novaLinha[nomeColunaVia] = c;
                    retorno.Rows.Add(novaLinha);
                }
            }

            return retorno;
        }
    ' VB.NET
    Private Function GerenciarVias(Origem As DataTable, NomeColunaVia As String, QtdVias As Integer) As DataTable
        Dim Retorno = Origem.Copy()

        For C = 2 To QtdVias
            For Each Linha As DataRow In Origem.Rows
                Dim NovaLinha = Retorno.NewRow()
                NovaLinha.ItemArray = DirectCast(Linha.ItemArray.Clone(), Object())
                NovaLinha(NomeColunaVia) = C
                Retorno.Rows.Add(NovaLinha)
            Next
        Next

        Return Retorno
    End Function

Com esse método à nossa disposição (você pode colocá-lo em uma classe estática ou biblioteca de forma que ele possa ser utilizado em múltiplos lugares), basta chamarmos passando a DataTable original e a quantidade de vias desejada. Por fim, nós trocamos a DataSource do relatório, de forma que ele utilize essa nova DataTable com os dados duplicados:

            // C#
            var novaTabela = GerenciarVias(this.DataSetRelatorio.Produto, "Via", 2);
            this.reportViewer1.LocalReport.DataSources.Clear();
            this.reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("DataSetRelatorio", novaTabela));
            this.reportViewer1.RefreshReport();
        ' VB.NET
        Dim NovaTabela = GerenciarVias(Me.DataSetRelatorio.Produto, "Via", 2)
        Me.ReportViewer1.LocalReport.DataSources.Clear()
        Me.ReportViewer1.LocalReport.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DataSetRelatorio", NovaTabela))
        Me.ReportViewer1.RefreshReport()

Uma vez alterado o código da nossa aplicação, nós temos que ajustar também o nosso relatório. A primeira coisa que vamos fazer é dar um “refresh” nos campos do relatório, a fim de que o novo campo “Via” seja reconhecido:

Nota: caso você esteja tendo algum problema nessa etapa e o campo “Via” não esteja aparecendo, você pode utilizar o Report Viewer DataSet Editor para adicionar esse campo no seu relatório manualmente.

Em seguida, adicionamos um agrupamento “pai” no relatório, considerando essa nova coluna “Via” como expressão de agrupamento:

Como nós não precisaremos da informação do número da via no Tablix, nós podemos deletar a coluna que foi criada. Só tome cuidado para excluir apenas a coluna, e não o agrupamento todo!

Uma última coisa que temos que configurar é a quebra de página entre as instâncias do agrupamento. Dessa forma, cada via do relatório será impressa em uma página diferente:

Pronto! Com essas alterações o relatório será gerado “N” vezes, dependendo da quantidade de vias que configuramos na chamada do método “GerenciarVias“.

Opção 2: Configurando a quantidade de cópias no evento “Print”

Uma segunda sistemática que podemos utilizar para imprimirmos múltiplas vias no Report Viewer é alterarmos automaticamente a quantidade de vias que serão impressas quando o usuário clicar no botão “imprimir“. Essa opção pode ser utilizada quando você quiser imprimir duas (ou mais) vias idênticas do relatório sem necessariamente exibi-las no controle visualizador do Report Viewer.

Para implementarmos essa funcionalidade, temos que manipular o evento “Print” do controle do Report Viewer. Dentro desse evento, nós configuramos o número de cópias que queremos imprimir:

        // C#
        private void reportViewer1_Print(object sender, Microsoft.Reporting.WinForms.ReportPrintEventArgs e)
        {
            e.PrinterSettings.Copies = 2;
        }
    ' VB.NET
    Private Sub ReportViewer1_Print(sender As Object, e As Microsoft.Reporting.WinForms.ReportPrintEventArgs) Handles ReportViewer1.Print
        e.PrinterSettings.Copies = 2
    End Sub

Com essa alteração, quando o usuário clicar em “imprimir“, a quantidade de cópias será preenchida automaticamente:

Opção 3: Configurando a quantidade de cópias no PrintDocument

Por fim, uma última opção que podemos utilizar caso estivermos imprimindo o relatório sem o controle visualizador do Report Viewer (impressão direta) seria configurarmos o número de cópias no PrintDocument. Se utilizarmos o código apresentado no meu artigo sobre impressão direta com o Report Viewer, basta configurarmos a quantidade de cópias para o PrintDocument no método “Imprimir“.

Baixe o projeto de exemplo

Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, 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 no final do artigo.

Concluindo

Como você pode observar nesse vídeo, apesar de não termos uma opção nativa para imprimirmos múltiplas vias no Report Viewer, isso pode ser facilmente implementado de três maneiras. Ou nós adicionamos um campo para controlar o número da via no DataSet e agrupamos o relatório por esse campo, ou nós configuramos automaticamente o número de cópias a serem impressas no controle do Report Viewer ou nós configuramos essa mesma opção no PrintDocument, caso estejamos imprimindo o relatório direto na impressora.

Você já teve algum cenário na sua aplicação em que você precisou gerar múltiplas vias do mesmo relatório? Como é que você implementou essa funcionalidade? Utilizando uma das três maneiras indicadas nesse artigo ou de alguma outra forma? Aguardo ansiosamente os seus comentários no final do post!

Até a próxima!

André Lima

Photo by Peter Shanks used under Creative Commons
https://pixabay.com/en/startup-start-up-notebooks-creative-593327/

Song Rocket Power Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 3.0 License
http://creativecommons.org/licenses/by/3.0/

Newsletter do André Lima

* indicates required



Powered by MailChimp

5 thoughts on “Imprimindo múltiplas vias no Report Viewer

Deixe uma resposta

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