Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 1 de 1
 
 
Impresión Del Resultado De Una Consulta SQL
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje Impresión Del Resultado De Una Consulta SQL 
 
Se ofrece la definición de una clase que permite imprimir el resultado de una consulta.

El código está comentado y permite ver cómo realizar impresiones con Gambas3 (Que no es nada fácil ). Se puede adaptar fácilmente a otras necesidades de impresión.

También muestra un bug de la impresión con este sistema   .No funciona cuando se selecciona impresión en landscape.
Si alguien entiende que no es un bug sino que yo estoy haciéndolo mal agradeceré una corrección   .

Aquí está. Espero que sea útil a mucha gente.
' gambas class file

' *********************************************************************************************
' Esta clase dispone lo necesario para crear un listado a partir de un resultado
' ************************************************************************************************

Private iPages As Integer
Private iYPos As Integer
Private RMargin As Integer
Private LMargin As Integer
Private TMargin As Integer
Private BMargin As Integer

Private resDatos As Result

Private PrinterName As String
Private pPrinter As Printer
Private FontName As String
Private pFont As Font

Private bolPDF As Boolean
Private iOrientation As Integer
Private sTitulo As String

Private fLineHeight As Float
Private fTitleHeight As Float
Private fTitleFontSize As Float
Private fLineFontSize As Float


Public Struct FieldPrint
    'Esta estructura determina las características de un campo en la impresión
    Name As String
    X As Integer
    Width As Integer
    Align As Integer
End Struct

Public Struct Page
    'Esta estructura determina la estructura de una página
    sFields As FieldPrint[]
    lFirstRecord As Long
    lLastRecord As Long
End Struct

Private Pages As Page[] 'Almacenará las estructuras de todas las páginas que intervienen en el listado


Public Sub _new(res As Result, titulo As String, Optional sPrinter As String = "", Optional sFont As String = "Serif", Optional fFontSize As Integer = 3.5, Optional orientation As Integer = 0, Optional generarPDF As Boolean = False)
    
    resDatos = res
    bolPDF = generarPDF
    '*******************************************************
    iOrientation = orientation      'Esto no funciona
    '*******************************************************
    sTitulo = titulo
    fTitleFontSize = fFontSize * 1.5
    fLineFontSize = fFontSize
    PrinterName = sPrinter
    FontName = sFont
    
End

Public Sub Imprimir()
    pPrinter = New Printer As "FPrinter"
    
    If bolPDF Then
        pPrinter.Name = "Imprimir a un archivo"
        Dialog.Title = "Archivo destino"
        Dialog.Path = "/tmp/" & sTitulo
        Dialog.Filter = ["*.pdf", "Formato de documento portable"]
        Dialog.AutoExt = True
        Dialog.SaveFile
        pPrinter.OutputFile = Dialog.Path
    Else

        If Not PrinterName Then
            If pPrinter.Configure() Then Return
        Endif
    
    Endif

    'Para calcular las posiciones de impresión de cada elemento lo hacemos sobre el área completa de la página y no sobre la
    'parte efectivamente imprimible
    pPrinter.FullPage = True

    Inc Application.Busy
    
    'Esto no funciona cuando la orientación es 1 - Landscape
    'Lo mismo sucederá si se abre el diálogo de configuración de impresoras y se selecciona landscape en este
    ''*********************************************
    'pPrinter.Orientation = iOrientation
    '**********************************************

    pPrinter.print      'Dispara el evento Printer_Begin()
    Dec Application.Busy

    Catch
       Message.Error("Error " & Error.Code & " " & Error.Text, "Aceptar")  
    
End

Public Sub FPrinter_Begin()

    'La impresión se hace mediante Paint así que establecemos las medidas de Paint a las de nuestra página
    Paint.Scale((Paint.Width) / pPrinter.PaperWidth, (Paint.Height) / pPrinter.PaperHeight)    'Cooordenadas en milímetros
    
    pfont = New Font(FontName)

    LMargin = 12
    RMargin = pPrinter.PaperWidth - LMargin
    TMargin = 10
    BMargin = pPrinter.PaperHeight - 15
    
    'Aquí tenemos dos opciones que son:
    '1 - Indicar el número de páginas a imprimir si podemos conocerlo por ser un listado simple
    
    'pPrinter.Count = iPages
    
    '2 - comentar la línea anterior y utilizar el evento Paginate para calcular el número de páginas a imprimir.
    'El evento paginate se dispara si dentro del evento Begin en que estamos no se asigna ninguna cantidad a Count
    
End

Public Sub FPrinter_Paginate()
    Dim fld As ResultField, curFieldPrint As FieldPrint, intRecordsPerPage As Integer, curPage As Page, iColPages As Integer
    Dim cp As Integer, rp As Integer, iRowPages As Integer
    
    Debug "Paginando"
    
    'Determinando la altura de la línea de título
    pFont.Size = fTitleFontSize
    fTitleHeight = pFont.TextHeight("H")
    'determinando la altura de la línea de texto
    pFont.Size = fLineFontSize
    fLineHeight = pFont.TextHeight("H")
    
    'Creando las definiciones de páginas
    Pages = New Page[]
    curPage = New Page
    iRowPages = 1       'iRowPages contendrá el número de páginas que ocupa cada fila de datos teniendo en cuenta el tamaño
                        'de la impresión
    curPage.sFields = New FieldPrint[]  
    pFont.Size = fLineFontSize
    'El número de registros que cabrán por página se calcula restando del margen inferior el margen superior, el alto del título,
    'el alto de los títulos de columnnas 1 líneas y 1.5 líneas para el número de página
    intRecordsPerPage = (BMargin - TMargin - fTitleHeight - fLineHeight - fLineHeight * 1.5) / fLineHeight
    
    For Each fld In resDatos.Fields
        curFieldPrint = New FieldPrint
        Select Case fld.Type
            Case gb.Boolean
                curFieldPrint.Width = pFont.TextWidth("T")
                curFieldPrint.Align = 3

            Case gb.Integer
                curFieldPrint.Width = pFont.TextWidth("12345")
                curFieldPrint.Align = 2

            Case GB.Long
                curFieldPrint.Width = pFont.TextWidth("1234567")
                curFieldPrint.Align = 2

            Case gb.Float
                curFieldPrint.Width = pFont.TextWidth("12345,12")
                curFieldPrint.Align = 2

            Case gb.Date
                curFieldPrint.Width = pFont.TextWidth("01/01/0000")
                curFieldPrint.Align = 3

            Case gb.String
                If (fld.Length / 3) > 20 Then       'Length devuelve tres veces la longitud de la cadena
                    curFieldPrint.Width = pFont.TextWidth("M") * 20
                Else
                    curFieldPrint.Width = (fld.Length / 3) * pFont.TextWidth("a")
                Endif

                curFieldPrint.Align = 1
         End Select
         'Comprobamos si entra en la página y si no creamos otra
         pFont.Bold = True
         curFieldPrint.Width = Max(curFieldPrint.Width, pFont.TextWidth(fld.Name))
        
         If curPage.sFields.Count = 0 Then
             curFieldPrint.X = LMargin + 2
             curFieldPrint.Name = fld.Name
         Else
             'CurrentX es igual al anterior X + su ancho + 4 mm de separación
             curFieldPrint.X = curPage.sFields[curPage.sFields.Count - 1].X + curPage.sFields[curPage.sFields.Count - 1].Width + 4
             curFieldPrint.Name = fld.Name
         Endif
         If (curFieldPrint.X + curFieldPrint.Width + 2) > (RMargin) Then
             curPage.lFirstRecord = 0
             curPage.lLastRecord = intRecordsPerPage - 1
             Pages.Add(curPage)
             curFieldPrint.X = LMargin + 2
             curPage = New Page
             curPage.sFields = New FieldPrint[]
             Inc iRowPages
         Endif
         curPage.sFields.Add(curFieldPrint)
    Next
    curPage.lFirstRecord = 0
    curPage.lLastRecord = intRecordsPerPage - 1
    Pages.Add(curPage)

    IRowPages = Pages.Count

    iColPages = Int(resDatos.Count / intRecordsPerPage)     'Páginas necesarias para cada columna de datos
                                                            'El número total de páginas es iRowPages * iColPages
    If resDatos.Count Mod intRecordsPerPage Then Inc iColPages
    
    For cp = 1 To iColPages - 1     'cp es contador para iColPages Contamos desde 1 porque la primera fila de páginas
                                    'ya ha sido definida
                                    
        For rp = 0 To iRowPages - 1 'rp es contador de iRowPages
            curPage = New Page
            curPage.sFields = Pages[rp].sFields     'Cada fila de páginas clona la definición de campos de la anterior
            
            'Definiendo filas del resultado a imprimir en la página
            curPage.lFirstRecord = cp * intRecordsPerPage
            curPage.lLastRecord = (cp + 1) * intRecordsPerPage - 1
            'Cuidamos no pasar del último registro aunque en la página quepan más filas
            If curPage.lLastRecord > resDatos.Count - 1 Then curPage.lLastRecord = resDatos.Count - 1
            Pages.Add(curPage)
        Next
    Next
    'Debug "Páginas a imprimir " & Str(Pages.Count)
    pPrinter.Count = Pages.Count
End


Public Sub FPrinter_Draw()
    'Este evento se dispara para cada página a imprimir
        Dim fp As FieldPrint, r As Integer
    Dim sTexto As String
    'Debug "Llegamos a la impresión"


    Paint.Font = Font[pFont.ToString()]
    Paint.LineWidth = 0.1
    
    Paint.Font.Size = fTitleFontSize
    Debug Paint.Font.ToString
    Paint.DrawText("Este es el título", LMargin, TMargin, pPrinter.PaperWidth - LMargin * 2, fTitleHeight, Align.Center)
    
    Debug "TextExtends alto " & Paint.TextExtents("Este es el título").Height
    iYPos = TMargin + fTitleHeight

    ' Paint.MoveTo(LMargin, iYPos)
    ' Paint.LineTo(RMargin, iYPos)
  
    Paint.Font.Size = fLineFontSize
    Debug Paint.Font.ToString
    Paint.Font.Bold = True
    
    Paint.MoveTo(LMargin, iYpos)
    Paint.LineTo(LMargin, BMargin - fLineHeight * 1.5)
    
    For Each fp In Pages[pPrinter.Page - 1].sFields
        Paint.drawText(fp.Name, fp.X, iYPos, Paint.TextExtents(fp.Name).Width, fLineHeight, Align.Left)
        'Paint.Fill
         Paint.MoveTo(fp.X + fp.Width + 2, iYPos)
         Paint.LineTo(fp.X + fp.Width + 2, BMargin - fLineHeight * 1.5)
         Paint.Stroke
    Next
    
    Paint.MoveTo(LMargin, TMargin + fTitleHeight)
    Paint.LineTo(fp.X + fp.Width + 2, TMargin + fTitleHeight)
    Paint.MoveTo(LMargin, TMargin + fTitleHeight + fLineHeight)
    Paint.LineTo(fp.X + fp.Width + 2, TMargin + fTitleHeight + fLineHeight)
    Paint.MoveTo(LMargin, BMargin - fLineHeight * 1.5)
    Paint.LineTo(fp.X + fp.Width + 2, BMargin - fLineHeight * 1.5)
    Paint.Stroke
    iypos += fLineHeight
    
    ' Paint.MoveTo(LMargin, iYPos)
    ' Paint.LineTo(RMargin, iYPos)
    
    Paint.MoveTo(LMargin, iYPos - fLineHeight)
    Paint.LineTo(LMargin, BMargin - fLineHeight * 1.5)
    Paint.Stroke
    Paint.Font.Bold = False
    For r = Pages[pPrinter.Page - 1].lFirstRecord To Pages[pPrinter.Page - 1].lLastRecord
        'Debug "Record " & Str(r)
        resDatos.MoveTo(r)
        With Pages[pPrinter.Page - 1]
            For Each fp In .sFields
                Paint.drawText(resDatos[fp.Name], fp.X, iYPos, fp.Width, fLineHeight, fp.Align)
                'Paint.Fill
              
            Next
        End With
        'Inc r
        iYPos += fLineHeight
    Next
    
    Paint.Font.Bold = True
    iypos = BMargin - fLineHeight
    Paint.DrawText("Página " & Str(pPrinter.Page), LMargin, iypos, pPrinter.PaperWidth - LMargin * 2, fLineHeight, Align.center)
End
 

 



 
última edición por Sebas el Viernes, 11 Enero 2013, 17:44; editado 1 vez 
Sebas - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Impresión Del Resultado De Una Consulta SQL 
 
Muchas gracias. Los novatos con el 3 agradecemos el aporte.
Lo miraré despacito y te comento, si hay algo que comentar, claro.

Un saludo.
 



 
shordi - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Impresión Del Resultado De Una Consulta SQL 
 
Sebas:

Buen aporte. Es conveniente que tengamos siempre varias opciones a elegir para poder hacer informes.

Saludos
 




===================
Blog personal
Web: SoloGambas seleccion de articulos dedicados a Gambas
Visita el Curso de Gambas3 ¡¡¡Gratuito!!!
 
jsbsan - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Impresión Del Resultado De Una Consulta SQL 
 
Anoto una errata y una observación de última hora.

Primero en la definición de la clase:

Public Sub _new(res As Result, titulo As String, Optional sPrinter As String = "", Optional sFont As String = "Serif", Optional fFontSize As Integer = 3.5, Optional orientation As Integer = 0, Optional generarPDF As Boolean = False)
 


fFontSize debe ser As Float  

Por otro lado he comprobado en el siguiente código;
Public Sub Imprimir()
    pPrinter = New Printer As "FPrinter"
    
    
    If bolPDF Then
        pPrinter.Name = "Imprimir a un archivo"
        Dialog.Title = "Archivo destino"
        Dialog.Path = "/tmp/" & sTitulo
        Dialog.Filter = ["*.pdf", "Formato de documento portable"]
        Dialog.AutoExt = True
        Dialog.SaveFile
        pPrinter.OutputFile = Dialog.Path
    Else

        If Not PrinterName Then
            If pPrinter.Configure() Then Return
        Endif
    
    Endif
....pPrinter.FullPage = True
 


Que cuando entramos en el diálogo printer.configure()  si cancelamos la impresión el resto del código no se ejecuta, tal como está previsto. Pero si se selecciona vista previa de la impresión tampoco ejecuta el resto del código en esta función sino que internamente llama a Printer.Print   y, por lo tanto,  el pPrinter.FullPage = True que viene a continuación o cualquier otro código debe colocarse con anterioridad al cuadro de diálogo o la vista previa no responderá al código escrito.
 



 
Sebas - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Impresión Del Resultado De Una Consulta SQL 
 
Buen trabajo, se agradece mucho.

En poco tiempo tendré que ponerme a actualizar una aplicación grande de gambas2  a gambas3, así que voy a estudiar tu ejemplo a ver si por fin asimilo el tema de impresión y paginado que por alguna razón siempre me ha parecido bastante complicado.

Saludos y gracias nuevamente.


P.D. Sebas, he visto que has creado un artículo a partir de este post, pero por alguna razón el código sale mal, porque convierte algunos caracteres en entidades html. Creo que es un fallo en el módulo de base de conocimientos del foro, tendré que revisarlo cuando tenga un rato.
Sin pretender abusar de tu bondad, te aconsejo, sólo para mayor claridad, que trates de elaborar el artículo paso a paso con fragmentos de código limpio (sin comentarios largos) y que los comentarios formen parte del artículo explicando esa parte concreta del código. Estoy seguro de que toda la comunidad te estará muy agradecida, yo el primero
 




===================
Jesús Guardón

Por favor, usemos el corrector ortográfico antes de pulsar el botón "Enviar".

"uo ǝs ʇɐu pıɟıɔıן ɐdɹǝupǝɹ ɐ dɹoƃɹɐɯɐɹ, soןo ɥɐʎ bnǝ dɹodouǝɹsǝןo"
 
jguardon - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Impresión Del Resultado De Una Consulta SQL 
 
jguardon escribió: [Ver mensaje]
Buen trabajo, se agradece mucho.

En poco tiempo tendré que ponerme a actualizar una aplicación grande de gambas2  a gambas3, así que voy a estudiar tu ejemplo a ver si por fin asimilo el tema de impresión y paginado que por alguna razón siempre me ha parecido bastante complicado.

Saludos y gracias nuevamente.


P.D. Sebas, he visto que has creado un artículo a partir de este post, pero por alguna razón el código sale mal, porque convierte algunos caracteres en entidades html. Creo que es un fallo en el módulo de base de conocimientos del foro, tendré que revisarlo cuando tenga un rato.
Sin pretender abusar de tu bondad, te aconsejo, sólo para mayor claridad, que trates de elaborar el artículo paso a paso con fragmentos de código limpio (sin comentarios largos) y que los comentarios formen parte del artículo explicando esa parte concreta del código. Estoy seguro de que toda la comunidad te estará muy agradecida, yo el primero


Bueno no es un abuso. Para mí es un placer poder ayudar a la comunidad dentro de mis posibilidades así que  lo intentaré.

Impresión en gambas 3. Clase para imprimir el resultado de una consulta SQL

La impresión en gambas3 es la más extraña con la que me he topado desde que programo. Está conducida por eventos.
Intentaré explicarla a partir del código.

' gambas class file

' *********************************************************************************************
' Esta clase dispone lo necesario para crear un listado a partir de un resultado
' ************************************************************************************************

Private iPages As Integer   'Contador de páginas
Private iYPos As Integer    'Índice de la posición vertical durante la impresión
Private RMargin As Integer  'Márgenes derecho, izquierdo, superior e inferior
Private LMargin As Integer
Private TMargin As Integer
Private BMargin As Integer

Private resDatos As Result  'Resultado que vamos a imprimir

Private PrinterName As String  
Private pPrinter As Printer  
Private FontName As String      
Private pFont As Font          

Private bolPDF As Boolean           'Imprimir a un archivo pdf
Private iOrientation As Integer     'Orientación        'En apaisado no funciona pero lo incluyo para cuando se pueda solucionar
Private sTitulo As String           'Título del listado

Private fLineHeight As Float        'Alto de la línea de texto
Private fTitleHeight As Float       'Alto del título
Private fTitleFontSize As Float     'Tamaño de letra para el título
Private fLineFontSize As Float      'Tamaño de letra para las líneas


Public Struct FieldPrint
    'Esta estructura determina las características de un campo en la impresión
    Name As String
    X As Integer
    Width As Integer
    Align As Integer
End Struct

Public Struct Page
    'Esta estructura determina la estructura de una página
    sFields As FieldPrint[]
    lFirstRecord As Long
    lLastRecord As Long
End Struct

Private Pages As Page[] 'Almacenará las estructuras de todas las páginas que intervienen en el listado

 


Inicialmente establecemos todas las variables que vamos a necesitar para realizar la impresión.
Estructura FieldPrint.
contendrá los datos necesarios para imprimir el contenido de un campo (Nombre, Posición X, Ancho de impresión y Alineación)
Estructura Page
Contiene los datos necesarios para imprimir una página (Un array con los FieldPrint que se van a utilizar en dicha página, el primer registro y el último que corresponden a dicha página).
Por último una array -Pages- guardará todas las definiciones de páginas.

Dada la forma de imprimir de gambas necesitamos conocer el número total de páginas antes de iniciar la impresión (lo veremos más adelante). Este conjunto de estructuras y variables nos ayudan a conocer el número de páginas a utilizar y ya de paso definir su contenido. Esto no será necesario en impresiones más simples.

Creación de la clase
Public Sub _new(res As Result, titulo As String, Optional sPrinter As String = "", Optional sFont As String = "Serif", Optional fFontSize As Float = 3.5, Optional orientation As Integer = 0, Optional generarPDF As Boolean = False)
    
    resDatos = res
    bolPDF = generarPDF
    '*******************************************************
    iOrientation = orientation      'Esto no funciona
    '*******************************************************
    sTitulo = titulo
    fTitleFontSize = fFontSize * 1.5
    fLineFontSize = fFontSize
    PrinterName = sPrinter
    FontName = sFont
    
End
 


Aquí se da valor a las variables más importantes. Las variables que no están en los parámetros tomarán valor más adelante aunque cada cual puede parametrizar aquellas variables que le parezcan más oportunas para sus listados.

Public Sub Imprimir()
    pPrinter = New Printer As "FPrinter"
    'Para calcular las posiciones de impresión de cada elemento lo hacemos sobre el área completa de la página y no sobre la
    'parte efectivamente imprimible
    pPrinter.FullPage = True

    'Esto no funciona cuando la orientación es 1 - Landscape
    'Lo mismo sucederá si se abre el diálogo de configuración de impresoras y se selecciona landscape
    '*********************************************
    'pPrinter.Orientation = iOrientation
    '**********************************************

    If bolPDF Then
        pPrinter.Name = "Imprimir a un archivo"
        Dialog.Title = "Archivo destino"
        Dialog.Path = "/tmp/" & sTitulo
        Dialog.Filter = ["*.pdf", "Formato de documento portable"]
        Dialog.AutoExt = True
        Dialog.SaveFile
        pPrinter.OutputFile = Dialog.Path
    Else
        
        If Not PrinterName Then
            ''Cuando se selecciona vista previa no se ejecuta nada del código que venga a continuación
            If pPrinter.Configure() Then Return
        Endif
    
    Endif

    Inc Application.Busy

    pPrinter.print      'Dispara el evento Printer_Begin()
    Dec Application.Busy

    Catch
       Message.Error("Error " & Error.Code & " " & Error.Text, "Aceptar")  
    
End

 

Esta es la única función pública de la clase. Básicamente crea el objeto printer y le manda imprimir. Pero hay que fijarse en varias cosas.

pPrinter.FullPage=TRUE indica que tomaremos las medidas completas de la página para imprimir. De otra forma no conoceremos los márgenes de impresión ya que el objeto printer no tiene propiedades para fijarlos.

pPrinter.Print inicia el proceso de impresión por eventos y no retorna hasta completar la impresión. Si se quiere capturar el resultado devuelve FALSE cuando la impresión se llevó a término sin errores o TRUE si falló o fue interrumpida.
El primer evento que se genera es Begin.

Public Sub FPrinter_Begin()

    'La impresión se hace mediante Paint así que establecemos las medidas de Paint a las de nuestra página
    Paint.Scale((Paint.Width) / pPrinter.PaperWidth, (Paint.Height) / pPrinter.PaperHeight)    'Cooordenadas en milímetros
    
    pfont = New Font(FontName)

    LMargin = 12
    RMargin = pPrinter.PaperWidth - LMargin
    TMargin = 10
    BMargin = pPrinter.PaperHeight - 15
    
    'Aquí tenemos dos opciones que son:
    '1 - Indicar el número de páginas a imprimir si podemos conocerlo por ser un listado simple
    
    'pPrinter.Count = iPages
    
    '2 - comentar la línea anterior y utilizar el evento Paginate para calcular el número de páginas a imprimir.
    'El evento paginate se dispara si dentro del evento Begin en que estamos no se asigna ninguna cantidad a Count
    
End
 


El código de este evento lo aprovechamos para fijar algunas características de la impresión como los márgenes y crear un objeto fuente que nos va a ayudar a calcular los tamaños de impresión. Fijamos también las escalas a que trabajará Paint para ajustarse las medidas de la página que gambas cuenta en mm.

Lo más importante a tener en cuenta es que el bucle local de eventos de impresión exige que se defina el número de páginas que se van a imprimir asignando valor a pPrinter.Count; este valor es fácilmente calculable para trabajos de impresión simples pero en muchos casos solo lo sabremos realizando la impresión o simulándola.
Si no se indica el número de páginas el bucle local dispara el evento Paginate.

Public Sub FPrinter_Paginate()
    Dim fld As ResultField, curFieldPrint As FieldPrint, intRecordsPerPage As Integer, curPage As Page, iColPages As Integer
    Dim cp As Integer, rp As Integer, iRowPages As Integer
    
    Debug "Paginando"
    
    'Determinando la altura de la línea de título
    pFont.Size = fTitleFontSize
    fTitleHeight = pFont.TextHeight("H")
    'determinando la altura de la línea de texto
    pFont.Size = fLineFontSize
    fLineHeight = pFont.TextHeight("H")
    
    'Creando las definiciones de páginas
    Pages = New Page[]
    curPage = New Page
    iRowPages = 1       'iRowPages contendrá el número de páginas que ocupa cada fila de datos teniendo en cuenta el tamaño
                        'de la impresión
    curPage.sFields = New FieldPrint[]  
    pFont.Size = fLineFontSize
    'El número de registros que cabrán por página se calcula restando del margen inferior el margen superior, el alto del título,
    'el alto de los títulos de columnnas 1 líneas y 1.5 líneas para el número de página
    intRecordsPerPage = (BMargin - TMargin - fTitleHeight - fLineHeight - fLineHeight * 1.5) / fLineHeight
    
    For Each fld In resDatos.Fields
        curFieldPrint = New FieldPrint
        Select Case fld.Type
            Case gb.Boolean
                curFieldPrint.Width = pFont.TextWidth("T")
                curFieldPrint.Align = 3

            Case gb.Integer
                curFieldPrint.Width = pFont.TextWidth("12345")
                curFieldPrint.Align = 2

            Case GB.Long
                curFieldPrint.Width = pFont.TextWidth("1234567")
                curFieldPrint.Align = 2

            Case gb.Float
                curFieldPrint.Width = pFont.TextWidth("12345,12")
                curFieldPrint.Align = 2

            Case gb.Date
                curFieldPrint.Width = pFont.TextWidth("01/01/0000")
                curFieldPrint.Align = 3

            Case gb.String
                If (fld.Length / 3) > 20 Then       'Length devuelve tres veces la longitud de la cadena
                    curFieldPrint.Width = pFont.TextWidth("M") * 20
                Else
                    curFieldPrint.Width = (fld.Length / 3) * pFont.TextWidth("a")
                Endif

                curFieldPrint.Align = 1
         End Select
         'Comprobamos si entra en la página y si no creamos otra
         pFont.Bold = True
         curFieldPrint.Width = Max(curFieldPrint.Width, pFont.TextWidth(fld.Name))
        
         If curPage.sFields.Count = 0 Then
             curFieldPrint.X = LMargin + 2
             curFieldPrint.Name = fld.Name
         Else
             'CurrentX es igual al anterior X + su ancho + 4 mm de separación
             curFieldPrint.X = curPage.sFields[curPage.sFields.Count - 1].X + curPage.sFields[curPage.sFields.Count - 1].Width + 4
             curFieldPrint.Name = fld.Name
         Endif
         If (curFieldPrint.X + curFieldPrint.Width + 2) > (RMargin) Then
             curPage.lFirstRecord = 0
             curPage.lLastRecord = intRecordsPerPage - 1
             Pages.Add(curPage)
             curFieldPrint.X = LMargin + 2
             curPage = New Page
             curPage.sFields = New FieldPrint[]
             Inc iRowPages
         Endif
         curPage.sFields.Add(curFieldPrint)
    Next
    curPage.lFirstRecord = 0
    curPage.lLastRecord = intRecordsPerPage - 1
    Pages.Add(curPage)

    IRowPages = Pages.Count

    iColPages = Int(resDatos.Count / intRecordsPerPage)     'Páginas necesarias para cada columna de datos
                                                            'El número total de páginas es iRowPages * iColPages
    If resDatos.Count Mod intRecordsPerPage Then Inc iColPages
    
    For cp = 1 To iColPages - 1     'cp es contador para iColPages Contamos desde 1 porque la primera fila de páginas
                                    'ya ha sido definida
                                    
        For rp = 0 To iRowPages - 1 'rp es contador de iRowPages
            curPage = New Page
            curPage.sFields = Pages[rp].sFields     'Cada fila de páginas clona la definición de campos de la anterior
            
            'Definiendo filas del resultado a imprimir en la página
            curPage.lFirstRecord = cp * intRecordsPerPage
            curPage.lLastRecord = (cp + 1) * intRecordsPerPage - 1
            'Cuidamos no pasar del último registro aunque en la página quepan más filas
            If curPage.lLastRecord > resDatos.Count - 1 Then curPage.lLastRecord = resDatos.Count - 1
            Pages.Add(curPage)
        Next
    Next
    'Debug "Páginas a imprimir " & Str(Pages.Count)
    pPrinter.Count = Pages.Count
End
 


El evento paginate debe finalmente dar valor a pPrinter.Count o seguirá generándose este evento en un bucle sin fin. Por lo tanto este valor debe asignarse aunque no es necesario que se haga en una sola ejecución del evento.

Respecto a nuestro código calcula con ayuda de las estructuras FieldPrint y Page los campos que se van a listar en cada página y el número de registros que caben dejando sitio para el título y el número de página.

En el evento Begin habíamos creado un objeto fuente que nos ayudará a calcular el espacio ocupado por los textos mediante los métodos Font.TextWidth y Font.TextHeight.
El objeto Paint no está disponible aún y no podemos utilizar Paint.Font.

Una vez definido el valor de pPrinter.Count se dispara el evento Draw ¡¡¡POR FIN VAMOS A IMPRIMIR!!!



Public Sub FPrinter_Draw()
    'Este evento se dispara para cada página a imprimir
    Dim fp As FieldPrint, r As Integer
    Dim sTexto As String
    'Debug "Llegamos a la impresión"


    Paint.Font = Font[pFont.ToString()]
    Paint.LineWidth = 0.1
    
    Paint.Font.Size = fTitleFontSize
    Debug Paint.Font.ToString
    Paint.DrawText("Este es el título", LMargin, TMargin, pPrinter.PaperWidth - LMargin * 2, fTitleHeight, Align.Center)
    
    Debug "TextExtends alto " & Paint.TextExtents("Este es el título").Height
    iYPos = TMargin + fTitleHeight
  
    Paint.Font.Size = fLineFontSize
    Debug Paint.Font.ToString
    Paint.Font.Bold = True
    
    Paint.MoveTo(LMargin, iYpos)
    Paint.LineTo(LMargin, BMargin - fLineHeight * 1.5)
  
    For Each fp In Pages[pPrinter.Page - 1].sFields
        Paint.drawText(fp.Name, fp.X, iYPos, Paint.TextExtents(fp.Name).Width, fLineHeight, Align.Left)
         Paint.MoveTo(fp.X + fp.Width + 2, iYPos)
         Paint.LineTo(fp.X + fp.Width + 2, BMargin - fLineHeight * 1.5)
         Paint.Stroke
    Next
    
    Paint.MoveTo(LMargin, TMargin + fTitleHeight)
    Paint.LineTo(fp.X + fp.Width + 2, TMargin + fTitleHeight)
    Paint.MoveTo(LMargin, TMargin + fTitleHeight + fLineHeight)
    Paint.LineTo(fp.X + fp.Width + 2, TMargin + fTitleHeight + fLineHeight)
    Paint.MoveTo(LMargin, BMargin - fLineHeight * 1.5)
    Paint.LineTo(fp.X + fp.Width + 2, BMargin - fLineHeight * 1.5)
    Paint.Stroke
    iypos += fLineHeight
    
    ' Paint.MoveTo(LMargin, iYPos)
    ' Paint.LineTo(RMargin, iYPos)
    
    Paint.MoveTo(LMargin, iYPos - fLineHeight)
    Paint.LineTo(LMargin, BMargin - fLineHeight * 1.5)
    Paint.Stroke
    Paint.Font.Bold = False
    For r = Pages[pPrinter.Page - 1].lFirstRecord To Pages[pPrinter.Page - 1].lLastRecord
        'Debug "Record " & Str(r)
        resDatos.MoveTo(r)
        With Pages[pPrinter.Page - 1]
            For Each fp In .sFields
                Paint.drawText(resDatos[fp.Name], fp.X, iYPos, fp.Width, fLineHeight, fp.Align)
                'Paint.Fill
              
            Next
        End With
        iYPos += fLineHeight
    Next
    
    Paint.Font.Bold = True
    iypos = BMargin - fLineHeight
    Paint.DrawText("Página " & Str(pPrinter.Page), LMargin, iypos, pPrinter.PaperWidth - LMargin * 2, fLineHeight, Align.center)
End

 


El evento Draw se dispara una vez por cada página que tenemos que imprimir. La variable pPrinter.Page nos indica qué página es está imprimiendo en cada entrada y por lo tanto utilizamos la definición de página correspondiente teniendo en cuenta que pPrinter.Page pagina desde la página 1 y el array Pages[] cuenta desde 0.

Aquí es donde se inicializa el objeto Paint para cada página y en este momento ya se pueden utilizar los métodos de Paint para dibujar en la página. En este caso utilizamos el método Paint.DrawText para escribir texto y los métodos Paint.MoveTo y Paint.LineTo para situar el pincel y dibujar líneas respectivamente. Las líneas y otras operaciones de dibujo no se dibujan hasta que se llama al método Paint.Stroke.

Finalmente se produce el evento End del objeto Printer pero en este caso yo no he necesitado utilizarle. este evento se produce cuando la impresión ya ha finalizado por lo tanto no se podrán realizar operaciones de dibujo ni texto en el mismo.


Espero haber dejado claro el funcionamiento de la impresión y no haber sido demasiado extenso o farragoso en las explicaciones. Aquí queda de todas formas una herramienta para imprimir listados por un lado y un tutorial para comprender el sistema de impresión de Gambas3 por otro.

Sebas
 



 
última edición por Sebas el Viernes, 11 Enero 2013, 17:48; editado 1 vez 
Sebas - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 
OcultarTemas parecidos
Tema Autor Foro Respuestas último mensaje
No hay nuevos mensajes Impresión En Gambas3 Sebas General 3 Jueves, 24 May 2012, 18:48 Ver último mensaje
arubioc
No hay nuevos mensajes Impresión En WebView marcopc Aplicaciones/Fragmentos de Código 0 Jueves, 24 Octobre 2013, 16:13 Ver último mensaje
marcopc
No hay nuevos mensajes No Veo El Resultado En La Clase Resultado.... portaro General 3 Miercoles, 07 May 2014, 10:42 Ver último mensaje
jsbsan
No hay nuevos mensajes Caracteres Ilegibles En El Resultado De Un... Shell Bases de Datos 4 Miercoles, 19 Abril 2017, 01:49 Ver último mensaje
tincho
 

Publicar nuevo tema  Responder al tema  Página 1 de 1
 

Usuarios navegando en este tema: 0 registrados, 0 ocultos y 0 invitados
Usuarios registrados conectados: Ninguno


 
Lista de permisos
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario



  

 

cron