09 enero 2009

Creación de informes con QuickReport (II)

Después de crear nuestro primer informe con QuickReport vamos a hacer otro a dos bandas el cual va a ser un listado de clientes. En un listado cualquiera necesitamos que la banda superior se mantenga fija en todas las hojas que se impriman y que la banda que va a imprimir lo datos se adapte al folio según los mismos.

CREANDO UN LISTADO SIMPLE A DOS BANDAS

Para cumplir nuestro cometido vamos a crear un nuevo formulario llamado FListadoClientes y dentro del mismo volvemos a añadir el objeto de la clase TQuickRep que llamaremos Informe.

Como necesito imprimir columnas bien anchas entonces debemos imprimir el folio de manera apaisado. Esto se hace pinchando el objeto QuickRep con el botón derecho del ratón y seleccionando Report Settings:


Y aparecerá este cuadro de diálogo:


Como puede verse en la imagen no sólo podemos seleccionar el tipo de folio (A4, A5, B4, etc.) sino que además se puede configurar el folio a un ancho y alto determinado en milímetros que viene muy bien para formatos de documentos que se imprimen en impresoras matriciales con papel continuo (lo más asqueroso para un programador).

En la parte derecha de esta ventana tenemos un ComboBox que por defecto tiene seleccionada la opción Portrait. Esto significa que va a imprimir el folio verticalmente. Como lo vamos a imprimir apaisado seleccionamos LandScape.

Ahora añadimos al objeto TQuickRep un par de bandas (TQRBand) y a la segunda banda le podemos mediante el inspector de objetos a su propiedad BandType el valor rbDetail:


También es buena costumbre ponerle nombre a las bandas para luego poder modificar sus acciones mediante código. A la primera banda le ponemos en su propiedad Name el nombre Cabecera y a la segunda banda la llamamos Detalle.

Insertamos etiquetas en la cabecera mediante objetos TQRLabel y los campos en el detalle mediante TQRDBText:


Al igual que hicimos en el artículo anterior debemos vincular este formulario a la unidad donde están los dados (uses Unit1) y añadir en la propiedad DataSet del objeto TQuickReport la tabla Clientes.

Hay que procurar que la banda de Detalle tenga la altura ajustada a los campos a imprimir, para que la separación de las líneas no sea muy grande y no se desperdicien folios (algunos jefes de empresas son muy tacaños).

Creamos el formulario del informe y lo ejecutamos desde la ventana principal:

Application.CreateForm( TFListadoClientes, FListadoClientes );
FListadoClientes.Informe.Preview;

Al ejecutar nuestro informe ya lo tendremos apaisado:


INFORMES MAESTRO/DETALLE A TRES BANDAS

El siguiente ejemplo que vamos a ver es la impresión de una factura que tiene cabecera, detalle y pie así como los datos de un cliente que viene de otra tabla, es decir, vamos a imprimir datos de tres tablas a la vez.

Como en los casos anteriores creamos un nuevo formulario llamado FImprimirFactura e insertamos el objeto TQuickRep y lo llamamos Informe.

Para este ejemplo voy a añadir al formulario principal un nuevo objeto TClientDataSet llamado Facturas con los siguientes campos:


Esta sería la cabecera de la factura. Ahora creamos otro ClientDataSet para el Detalle de la factura con estos campos:


Introducimos una factura en la tabla con un par de líneas de detalle:

Facturas.Append;
Facturas['ID'] := 1;
Facturas['FECHA'] := Date;
Facturas['IDCLIENTE'] := 1;
Facturas['BASEIMPONIBLE'] := 300;
Facturas['IVA'] := 48;
Facturas['TOTAL'] := 348;
Facturas.Post;

Detalle.Append;
Detalle['IDFACTURA'] := 1;
Detalle['UNIDADES'] := 1;
Detalle['ARTICULO'] := 'MOVIL SAMSUNG';
Detalle['PRECIO'] := 100;
Detalle['TOTALLINEA'] := 100;
Detalle.Post;

Detalle.Append;
Detalle['IDFACTURA'] := 1;
Detalle['UNIDADES'] := 1;
Detalle['ARTICULO'] := 'MOVIL NOKIA';
Detalle['PRECIO'] := 200;
Detalle['TOTALLINEA'] := 200;
Detalle.Post;

A continuación creamos un nuevo formulario llamado FImprimirFactura e insertamos un objeto TQuickRep con tres bandas:


A las bandas las vamos a llamar Cabecera, Detalle, Pie y serán del tipo (BandType) rbTitle, rbDetail y rbPageFooter respectivamente.

Como hicimos en ejemplos anteriores, vinculamos a formulario con el formulario principal para poder traernos los datos de las tablas (uses Unit1). Seleccionamos el objeto TQuickRep y vinculamos mediante la propiedad DataSet la tabla Detalle.

Aunque pueda parecer extraño, cuando vamos a imprimir un documento maestro/detalle debemos vincular a la propiedad DataSet del objeto TQuickRep la tabla Detalle y no la del maestro. Esto se debe a que es el detalle la banda que se va a repetir en la factura, es decir, el centro de la misma. La cabecera y el pie son sólo datos adicionales. Eso no quita que luego cada campo se vincule con una tabla distinta. No hay limitaciones a la hora de vincular campos con tablas.

Pero vayamos por partes. Primero implementamos la cabecera de la factura en la primera banda:


Los campos ID y FECHA están vinculados con la tabla FACTURAS. En cambio todos los campos encerrados en el rectángulo están vinculados con la tabla CLIENTES (sólo hay que procurar tener filtrado que FACTURA.IDCLIENTE = CLIENTES.ID).

Lo demás son todo etiquetas TQRLabel. El rectángulo y las líneas que he puesto debajo de los títulos de los campos del detalle lo he hecho con un objeto TQRShape que en su propiedad Shape soporta estos formatos:

qrsRectangle: Un rectángulo.
qrsCircle: Un círculo.
qrsHorLine: Línea horizontal.
qrsVerLine: Línea vertical.
qrsRoundRect: Rectángulo con las esquinas redondeadas.
qrsRightAndLeft: dos líneas verticales (un rectángulo sin techo ni suelo).
qrsTopAndBottom: dos líneas horizontales (un rectángulo sin paredes).

En mi formato de factura sólo he utilizado líneas horizontales y un rectángulo.

Vamos ahora con el detalle de la factura en la segunda banda:


Esta banda sólo va a contener campos TQRDBText vinculados a la tabla DETALLE. Es importante quitar en este tipo de campos el valor Autosize y ajustar el ancho manualmente para que por ejemplo el nombre del artículo no chafe el precio en el caso de que el nombre sea demasiado largo.

También es importante que todos los campos de tipo float estén alineados a la derecha mediante su propiedad Alingment = taRightJustify.

Hay que procurar que la altura de la banda de detalle sea un poco más grande que la altura de los campos para que el espacio entre líneas no sea ni muy ancho ni muy estrecho.

Vamos con la última banda, el pie:


Esta banda sólo contiene los tres campos que totalizan la factura y que están vinculados con la tabla FACTURAS. Un detalle que hay que tener presente es que la posición vertical a la que van a salir estos totales es inversamente proporcional a la altura de la banda de tipo rbPageFooter, es decir, si queremos que los totales salgan más arriba hay que ampliar verticalmente la altura de esta banda. Y si queremos que los totales salgan pegados en la parte inferior del folio entonces hay que procurar que esta banda sea lo más estrecha posible (verticalmente).

Este seria nuestro diseño de la factura:



Llamamos a la vista previa como siempre:

Application.CreateForm( TFImprimirFactura, FImprimirFactura );
FImprimirFactura.Informe.Preview;

Y esta sería la vista previa al imprimirla:


Esta sería la parte superior:


Y la parte inferior:


También sería recomendable que los campos que vamos a imprimir de tipo moneda tengan definida su máscara a dos decimales para evitar problemas de redondeo. Esto se hace en el diseño de la tabla original a través de la propiedad DisplayFormat:


De modo que al imprimir aparezcan los dos decimales:

Estos tres ejemplos que hemos visto son los tres típicos informes que nos suelen pedir: un formulario, un listado o un documento maestro/detalle (y pie). Aunque aquí no se acaban nuestras pesadillas ya que esto solo son juguetes comparado con lo que los clientes suelen pedir de verdad.

En el próximo artículo veremos casos más complejos y algunos truquillos para modificar el aspecto del informe en tiempo real.

Pruebas realizadas en RAD Studio 2007.

Publicidad