16 enero 2009

Creación de informes con QuickReport (III)

Hoy vamos a ver como modificar la impresión de un informe en tiempo real para poder cambiar su aspecto. También veremos otro ejemplo de un informe con detalle y subdetalle.

MODIFICANDO LA IMPRESIÓN EN TIEMPO REAL


Supongamos que en el listado de clientes que vimos en ejemplos anteriores hemos añadido la columna SALDO INICIAL y nos interesa que salgan todos los importes en negro menos aquellos con saldo negativo que aparecerán en rojo:

Cuando se insertan campos en un informe, Delphi suele darles el nombre QRDBText1, QRDBText2, etc. Debemos acostumbrarnos a poner en la propiedad Name de estos componentes el mismo nombre que tiene el campo en la tabla, en nuestro caso SALDOINICIAL. Sólo para los campos de la base de datos, no es necesario para etiquetas y figuras gráficas.

También sería recomendable ponerle nombre a la banda donde se imprimen los campos (Detalle).

Luego programamos el evento BeforePrint de la banda Detalle del siguiente modo:

procedure TFListadoClientes.DetalleBeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
if Form1.Clientes['SALDOINICIAL'] >= 0 then
SALDOINICIAL.Font.Color := clBlack
else
SALDOINICIAL.Font.Color := clRed;
end;

El evento BeforePrint (antes de imprimir) se va a ejecutar antes de dibujar cada registro en la banda. De este modo podemos cambiar en tiempo real la visualización de cada campo antes de que se plasme en el folio.

Otro caso especial que nos puede solucionar este método es el de modificar los campos booleanos para que no imprima True o False. Por ejemplo, si quiero imprimir el campo activo pasaría esto:


Para solucionar esto en vez de imprimir directamente el campo ACTIVO utilizando un objeto TQRBDText lo que vamos a hacer es meter una etiqueta llamada EActivo (TQRLabel):


Ahora modificamos el método BeforePrint de la banda Detalle:

procedure TFListadoClientes.DetalleBeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
if Form1.Clientes['SALDOINICIAL'] >= 0 then
SALDOINICIAL.Font.Color := clBlack
else
SALDOINICIAL.Font.Color := clRed;

if Form1.Clientes['ACTIVO'] then
EActivo.Caption := 'SI'
else
EActivo.Caption := 'NO';
end;

Si el campo ACTIVO está a True imprimimos SI, NO en canso contrario. Estos truquillos nos ahorran mucho tiempo y evitan tener que modificar los datos de la tabla original.

Hasta modemos meter en la banda figuras gráficas o iconos según los datos del registro actual. Pongamos por ejemplo que a los clientes cuyo saldo inicial sea superor a 800 euros le ponemos el icono de un lápiz a lado como advertencia para su edición:

Lo que he hecho es insertar el objeto imagen TQRImage con el icono del lápiz (a través de su propiedad Picture) y luego vuelvo a ampliar el evento BeforePrint de este modo:

procedure TFListadoClientes.DetalleBeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
if Form1.Clientes['SALDOINICIAL'] >= 0 then
SALDOINICIAL.Font.Color := clBlack
else
SALDOINICIAL.Font.Color := clRed;

if Form1.Clientes['ACTIVO'] then
EActivo.Caption := 'SI'
else
EActivo.Caption := 'NO';

if Form1.Clientes['SALDOINICIAL'] >= 800 then
Icono.Enabled := True
else
Icono.Enabled := False;
end;

Como puede verse en el código he utilizado la propiedad Enabled en vez de la propiedad Visible para ocultar el icono. La propiedad Visible no tiene ningún efecto en QuickReport (por lo menos a mi no me ha funcionado en ningún caso).

Con estos pequeños retoques nuestros informes parecerán mucho más profesionales (y a nuestros clientes les sacamos más pasta diciendo que nos ha costado mucho hacerlo :)

CREANDO UN INFORME CON DETALLE Y SUBDETALLE

Ahora vamos a complicar un poco más el asunto y vamos hacer un listado desglosado de facturas con dos bandas de tipo detalle. Más bien con un detalle y un subdetalle:


Este listado muestra las cabeceras de las facturas (los totales) y sus líneas de detalle. Este sería su diseño en QuickReport:


El documento se compone de tres bandas:

Cabecera: esta banda es un objeto TRQBand y va a ser de tipo rbTitle. En esta banda sólo vamos a meter el título del listado:


Detalle: también va a ser un objeto TRQBand y su tipo será rbDetail. En esta banda necesitamos los títulos de la factura así como los campos de la misma:


El único campo que no hay que vincular con la tabla Factura es el NOMBRE que va vinculado a la tabla CLIENTES.

SubDetalle: aquí introducimos una banda de tipo TQRSubDetail. No es lo mismo una banda TRQBand de tipo rbSubDetail que una banda TQRSubDetail. La primera sólo suele utilizarse para totalizar datos (sin vincularlo a tablas) pero esta última tiene la propiedad DataSet que permite vincular sus campos a otra tabla:


Ahora viene la vinculación con las tablas. Primero hay que seleccionar el objeto TQuickRep y vincular a su propiedad DataSet la tabla Facturas (la cabecera). En la banda de Detalle vinculamos todos los campos a la tabla Facturas.

En la banda SubDetail tenemos que vincular los campos a la tabla Detalle (el contenido de la factura).

Si ejecutáramos el listado como está, nos pasaría esto:


Han ocurrido dos cosas:

1º Al no filtrar la tabla de Clientes por cada factura resulta que aparece el mismo cliente en ambas facturas. Debería ser: CLIENTES.ID = FACTURAS.IDCLIENTE.

2º Al no filtrar la tabla Detalle por cada factura nos aparece el detalle de ambas facturas debajo de cada cabecera. Debería ser así: DETALLE.IDFACTURA = FACTURAS.ID.

Para solucionar esto tenemos que escribir este código en el evento BeforePrint (antes de imprimir) de la banda Detalle:

procedure TFListadoFacturas.DetalleBeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
with Form1 do
begin
Clientes.Filter := 'ID=' + IntToStr(Facturas['IDCLIENTE']);
Clientes.Filtered := True;

Detalle.Filter := 'IDFACTURA=' + IntToStr(Facturas['ID']);
Detalle.Filtered := True;
end;
end;

Lo que hacemos es filtrar el cliente y el detalle de la factura respecto a la factura que estamos imprimiendo en cada momento. De este modo no hay que recurrir a sentencias SQL para filtrar la tablas (aunque también se podría hacer así).

En la siguiente parte de este artículo veremos más ejemplos de informes así como la forma de exportar a PDF y otros formatos.

Pruebas realizadas en RAD Studio 2007.

Publicidad