Jump to content

ayuda con impresiones en VB


Recommended Posts

buenas a todos, estoy haciendo un pequeño programa para poder imprimir folios en papel continuo 11x15" ya tengo listo la impresion, lo que me falta y no pillo como solucionarlo es como hago para imprimir varias hojas de una sola pasada.

 

hasta ahora puedo imprimir bien pero solo la primera hoja y despues salta a la siguiente y no imprime mas, he rebuscado soluciones y modificado el codigo pero nada solo imprime la primera pagina.

 

les dejo el codigo para que lo vean:

 

boton imprimir:

 Private Sub imprimir_Click(sender As Object, e As EventArgs) Handles imprimir.Click
        'ajusto el tamaño de la pagina'
        Dim pkCustomSize1 As New Printing.PaperSize("Custom Paper Size", 2794, 3810)

        folio = 0
        'for que gestiona x cantidad de folios a imprimir'
        For i As Integer = 0 To txthojas.Text - 1
            'aumentador de folios'
            If i = 0 Then
                folio = txtDesde.Text
            Else
                folio += 1
            End If
            linea = 1

            'actualizo el formato de la pagina'
            PrintDocument1.PrinterSettings.DefaultPageSettings.PaperSize = pkCustomSize1
            'envio a imprimir'
            PrintDocument1.Print()

            'muestro avanze de fiolios en pantalla'
            folio1.Text = folio
            folio2.Text = txthasta.Text

        Next

    End Sub

evento print()

 Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
      
            ' Definimos el tipo de fuente y de mas'
            Dim Fuente As New Font("Arial Narrow", 9)
        ' Contador de lineas que se van imprimiendo'
            Dim lineaimpresa As Integer = 0
            ' Variable para ver cuando se va hacer un salto de pagina'
        Dim salto_pagina As Boolean = False
            ' Variable para designar cuantos lineas se van a imprimir por hoja'
            Dim NroLineasPagina As Integer = 4

        'for que imprime 4 lineas en cada pagina'
        For a As Integer = 1 To 4
            If a = 1 Then
                e.Graphics.DrawString("NOMBRE EMPRESA", Fuente, Brushes.Black, 5, 4)
            Else
                If a = 2 Then
                    e.Graphics.DrawString("DIRECCION - CIUDAD EMPRESA", Fuente, Brushes.Black, 5, 18)
                    e.Graphics.DrawString("FOLIO UNICO NACIONAL", Fuente, Brushes.Black, 910, 18)
                Else
                    If a = 3 Then
                        e.Graphics.DrawString("GIRO EMPRESA", Fuente, Brushes.Black, 5, 30)
                        e.Graphics.DrawString("N° " & folio, Fuente, Brushes.Black, 910, 30)
                    Else
                        If a = 4 Then
                            e.Graphics.DrawString("RUT. XX.XXX.XXX-X", Fuente, Brushes.Black, 5, 42)
                        End If
                    End If
                End If
            End If

            'aumenta en 1 la linea impresa'
            lineaimpresa += 1

            'si linea impresa es igual a 4 coloca un true en salto de pagina y sale de for'
            If lineaimpresa = NroLineasPagina Then
                salto_pagina = True
                Exit For
            End If
        Next

        'si salto de pagina es true deberia saltar a la siguiente hoja e imprimir lo siguiente'
        If salto_pagina = True Then
            e.HasMorePages = True
        Else
            e.HasMorePages = False
        End If
    End Sub

coloque los comentarios en '' para que se viera mejor

 

si alguien identifica cual es mi error favor decirme, recien estoy entendiendo como es la impresion directa con Visual por medio de los eventos PrintDocument y PrintDialog

 

gracias de antemano

Edited by Variator
Link to comment
Share on other sites

:mmm: Como no entendí muy bien lo que hace tu aplicación, hice un pequeño programa de ejemplo que imprime un documento de varias páginas.

En todo caso, la llamada al método Print la tienes dentro de un ciclo For, eso es mala idea. Si quieres imprimir un documento de varias páginas y tienes que repetir el proceso pero cambiando el número de folio, entonces tienes que hacer que el manejador del evento PrintPage vuelva a empezar de la primera página e incremente el número de folio, y así hasta que no queden más folios (o lo que sea. Como dije, no entendí bien lo que hace tu aplicación :huasonto: ).

 

[hide]

La interfaz gráfica del programa de ejemplo que hice sería así:

 

p1.png

Contiene los siguientes controles (de arriba hacia abajo):

  • NumericUpDown
  • Label
  • ProgressBar
  • Button
Lo único que hay que hacer es seleccionar la cantidad de páginas que quieres que tenga el documento y hacer clic en el botón que dice "Imprimir...".

 

Al imprimir un documento de varias páginas, se recomienda crear una clase derivada de PrintDocument, y en ésta se guarda toda la información de estado de la impresión en curso. Tienes que tener en cuenta que el manejador del evento PrintPage debe imprimir sólo 1 página a la vez, así que cualquier cosa que no alcance a imprimirse en la página actual debe quedar pendiente para la siguiente página, y toda la información de lo que quede pendiente se guarda en la instancia de dicha clase derivada (esta instancia se pasa como parámetro sender al manejador del evento PrintPage).

En este ejemplo, la clase derivada de PrintDocument se llama TrabajoImpresion. Para simplificar las cosas, la única información que se guarda es la cantidad de páginas que se han impreso hasta el momento y la cantidad total de páginas que se van a imprimir (se accede a esta información a través de las propiedades PaginasImpresas y PaginasEnTotal, respectivamente).

 

Imports System.Drawing.Printing
Imports System.Windows.Forms

Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        lblProgreso.Text = ""
    End Sub

    Private Sub btnImprimir_Click(sender As System.Object, e As System.EventArgs) Handles btnImprimir.Click
        Dim doc As PrintDocument
        Dim CustomPageSize1 As New PaperSize("Tamaño de papel personalizado", 280, 300)

        doc = New TrabajoImpresion(CInt(NumericUpDown1.Value))
        doc.DefaultPageSettings.PaperSize = CustomPageSize1

        'Asignar manualmente el manejador de evento '
        AddHandler doc.PrintPage, AddressOf doc_PrintPage

        'Asociar manualmente el documento al "PrintDialog"  '
        PrintDialog1.Document = doc

        If PrintDialog1.ShowDialog() = DialogResult.OK Then
            ProgressBar1.Value = 0
            ProgressBar1.Maximum = CInt(NumericUpDown1.Value)
            lblProgreso.Text = "Imprimiendo..."
            doc.Print()
        End If
    End Sub

    Private Sub doc_PrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs)
        Dim Fuente As New Font("Arial Narrow", 15)
        Dim impresion As TrabajoImpresion = CType(sender, TrabajoImpresion)

        impresion.PaginasImpresas += 1

        'Imprimir contenido de la página    '
        e.Graphics.DrawString("Esta es la página " & CStr(impresion.PaginasImpresas) & " que se", Fuente, Brushes.Crimson, 5, 180)
        e.Graphics.DrawString("imprime correctamente", Fuente, Brushes.Crimson, 5, 210)

        System.Threading.Thread.Sleep(250)  'ELIMINAR ESTA LÍNEA    '

        'Verificar si quedan más páginas por imprimir   '
        e.HasMorePages = (impresion.PaginasImpresas < impresion.PaginasEnTotal)

        'Realizar cualquier tipo de actualización a controles que muestren el progreso de la impresión  '
        lblProgreso.Text = String.Format("{0} de {1}", impresion.PaginasImpresas, impresion.PaginasEnTotal)
        ProgressBar1.Value = impresion.PaginasImpresas
        Application.DoEvents()
    End Sub

End Class

Public Class TrabajoImpresion
    Inherits PrintDocument

    Private _pagTotal As Integer
    Private _pagImpresas As Integer

    Public Sub New(ByVal TotalPaginas As Integer)
        PaginasEnTotal = TotalPaginas
        PaginasImpresas = 0
    End Sub

    Public Property PaginasEnTotal As Integer
        Get
            Return _pagTotal
        End Get
        Set(value As Integer)
            _pagTotal = value
        End Set
    End Property

    Public Property PaginasImpresas As Integer
        Get
            Return _pagImpresas
        End Get
        Set(value As Integer)
            _pagImpresas = value
        End Set
    End Property
End Class
Si usas un PrintDialog, no tienes que asignar nada a la propiedad Document, ya que esto se hace manualmente en tiempo de ejecución (recuerda que se usa una clase derivada de PrintDocument ;) ).

 

p2.png

Si pruebas el programa usando la impresora virtual Microsoft XPS Document Writer y seleccionando 5 páginas, obtienes un documento como este:

p3.png

En tu caso, tienes que modificar la clase TrabajoImpresion de tal forma que el constructor acepte todos los datos relevantes para realizar la impresión. Quizás necesites pasar un arreglo con varios números de RUT, folio inicial, cantidad de folios, incremento de folio, cantidad de líneas por página,... :nose: eso lo sabes tú.

 


Lo siguiente es opcional (ignora esto si no te manejas mucho en VB.NET)

Por si acaso, el código de arriba funciona, pero no es la forma ideal de hacerlo. Lo ideal es que la clase TrabajoImpresion realice la impresión en un método (en este caso lo llamo ImprimirPagina) y que toda la información de estado se guarde en variables de instancia privadas y sólo se tenga acceso a información que sirva para saber el progreso de la impresión en curso a través de propiedades de sólo lectura (por ejemplo, cantidad de páginas impresas hasta el momento). Así que, en rigor, el manejador del evento PrintPage debería verse más parecido a esto:

    Private Sub doc_PrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs)
        Dim impresion As TrabajoImpresion = CType(sender, TrabajoImpresion)

        'Imprimir y verificar si quedan más páginas por imprimir   '
        e.HasMorePages = impresion.ImprimirPagina(e.Graphics)

        'Realizar cualquier tipo de actualización a controles que muestren el progreso de la impresión  '
        lblProgreso.Text = String.Format("{0} de {1}", impresion.PaginasImpresas, impresion.PaginasEnTotal)
        ProgressBar1.Value = impresion.PaginasImpresas
        Application.DoEvents()
    End Sub
Obviamente, para que esto funcione, hay que hacer varias modificaciones a la clase TrabajoImpresion ;)

 

Además, todos los objetos de tipo Font, Brush, etc. deberían ser variables de instancia privadas y deberían instanciarse en el constructor, y una vez que finalice la impresión, se liberan los recursos usados por éstas llamando al método Dispose para cada una de ellas.

 

Si quieres hacer todo esto, queda como ejercicio... ;)

[/hide]

 

:huasonto:

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...