18 junio 2010

El editor de informes Report Manager (3)

Continuando con la factura del artículo anterior, vamos a darle formato a los números reales y a modificar su comportamiento en tiempo real desde Delphi. También veremos como enviar parámetros SQL desde Delphi al informe.

AJUSTAR LOS DECIMALES

Antes de cargar el informe en nuestro proyecto de Delphi vamos a tratar de adecentarlo un poco comenzando por el detalle del documento. Lo primero que apreciamos es que el número de decimales sale como le da la gana:

Para dar formato a dos decimales seleccionamos los campos PRECIO, PORIVA, IVA y TOTALLINEA y en su propiedad Formato le ponemos ###,##0.00:


Ahora si sale como nosotros queremos:

Lo mismo tenemos que hacer con los totales del documento.

MODIFICAR EL INFORME EN TIEMPO REAL

Una de las cosas que siempre me ha gustado de QuickReport es tener la posibilidad de modificar en tiempo real los componentes del informe justo antes de enviarlo a la impresora.

Vamos a verlo con un nuevo proyecto en Delphi con el formulario que va a imprimir la factura:

Al igual que el ejemplo de los contactos tenemos el componente VCLReport que configuramos al pulsar el botón Imprimir:

procedure TFImprimirFactura.BImprimirClick(Sender: TObject);
begin
VCLReport.Title := 'Factura';
VCLReport.Filename := ExtractFilePath(Application.ExeName) +
'factura.rep';
VCLReport.Report.Copies := StrToInt(NumCopias.Text);
VCLReport.Preview := VistaPrevia.Checked;
VCLReport.Execute;
end;

También controlamos el número de copias de que se imprimen según lo que tenemos puesto en el campo NumCopias. Una modificación que le vamos a hacer es que imprima en rojo y en negrita aquellos precios superiores a 1.000. Esto lo hacemos en el evento BeforePrint (antes de imprimir) del componente VCLReport:

procedure TFImprimirFactura.VCLReportBeforePrint(Sender: TObject);
var
i: Integer;
begin
with VCLReport.Report do
begin
if FindComponent('TRpExpression9') is TRpExpression then
begin
if (FindComponent('TRpExpression9') as TRpExpression).IdenExpression.Value >
1000 then
begin
(FindComponent('TRpExpression9') as TRpExpression).FontColor := clRed;
(FindComponent('TRpExpression9') as TRpExpression).FontStyle := 1;
end;
end;
end;
end;

Para poder acceder a la clase TRpExpression debemos añadir la unidad rplabelitem al formulario donde vamos a imprimir. El nombre que busco (TRpExpression9) nos lo dice el mismo editor:

Lo que hacemos es interceptarlo justo antes de imprimirlo y según el valor que va a imprimir tomamos la acción que queramos:
Los componentes de Report Manager tienen la propiedad Visible pero aunque la activemos no hacen ni caso. Así que si quieres hacer desaparecer un componente elige el color blanco:

(FindComponent('TRpExpression9') as TRpExpression).FontColor := clWhite;

Esto puede ser muy interesante para mostrar u ocultar ciertas etiquetas según las propiedades de la factura. Por ejemplo, según la forma de pago a lo mejor me interesa mostrar la etiqueta de que se ha pagado al contado:

Como antes de imprimir la factura ya sabemos si debemos imprimir esta etiqueta o no, podemos hacerla invisible sin utilizar el evento BeforePrint:

procedure TFImprimirFactura.BImprimirClick(Sender: TObject);
begin
VCLReport.Title := 'Factura';
VCLReport.Filename := ExtractFilePath(Application.ExeName) +
'factura.rep';
VCLReport.Report.Copies := StrToInt(NumCopias.Text);
VCLReport.Preview := VistaPrevia.Checked;

if not Contado.Checked then
with VCLReport.Report do
if FindComponent('TRpLabel14') is TRpLabel then
(FindComponent('TRpLabel14') as TRpLabel).FontColor := clWhite;

VCLReport.Execute;
end;

Si no está activado en la factura el CheckBox de Contado entonces lo hacemos invisible. Para hacerla invisible también le podemos quitarle el texto:

if not Contado.Checked then
with VCLReport.Report do
if FindComponent('TRpLabel14') is TRpLabel then
(FindComponent('TRpLabel14') as TRpLabel).Text := '';

De este modo podemos controlar si se imprimen o no las cuentas bancarias, los distintos tipos de IVA, los recargos de equivalencia o las retenciones. Aunque Report Manager tiene buenas funciones para evaluar expresiones, no hay nada como Delphi para meterle mano a los documentos.

ENVIAR PARÁMETROS AL INFORME

También podemos enviar parámetros formalmente al informe creando parámetros en el mismo. Esto se hace seleccionando las opciones Informe Configuración de datos y en el formulario que aparece pulsamos el botón Parámetros:

Se abrirá esta ventana:

Pulsamos el botón Añadir un nuevo parámetro y como queremos enviarle la cuenta bancaria le ponemos de nombre CCC:

Pulsamos Aceptar y otra vez Aceptar en la ventana anterior. Ahora vamos a crear una expresión al pie de la factura que recoja el valor de este parámetro:

Para mandarle el parámetro al imprimir desde Delphi hacemos esto:

procedure TFImprimirFactura.BImprimirClick(Sender: TObject);
begin
VCLReport.Title := 'Factura';
VCLReport.Filename := ExtractFilePath(Application.ExeName) +
'factura.rep';
VCLReport.Report.Copies := StrToInt(NumCopias.Text);
VCLReport.Preview := VistaPrevia.Checked;
VCLReport.Report.Params.ParamByName('CCC').AsString := '1234-5678-44-1234567890';
VCLReport.Report.PrepareParamsBeforeOpen;
VCLReport.Execute;
end;

Debemos llamar al método PrepareParamsBeforeOpen para que el informe se chupe los parámetros que le mandamos:

Pero es que además podemos utilizar los parámetros para cambiar las condiciones de la SQL de la tabla. Vamos a crear un parámetro para el detalle de la factura llamado PRECIOMINIMO para que muestre sólo aquellas líneas de detalle cuyo precio rebase el que le pasamos como parámetro:

Ahora modificamos la SQL del detalle de este modo:

SELECT DETALLE.*,ARTICULOS.NUMERO,
ARTICULOS.NOMBRE FROM DETALLE
LEFT JOIN ARTICULOS ON ARTICULOS.ID=DETALLE.IDARTICULO
WHERE PRECIO >= :PRECIOMINIMO

Si intentamos hacer la vista previa en el informe nos dirá esto:

Para probar que vaya bien, entramos de nuevo al parámetro, lo ponemos de tipo moneda y con el valor 20:

Al hacer la vista previa solo mostrará las líneas de detalle cuyo precio es mayor de 20:

En Delphi le pasamos el parámetro como hemos visto antes:

VCLReport.Report.Params.ParamByName('CCC').AsString := '1234-5678-44-1234567890';
VCLReport.Report.Params.ParamByName('PRECIOMINIMO').Value := 20;
VCLReport.Report.PrepareParamsBeforeOpen;
VCLReport.Execute;

Aunque Report Manager pueda parecer un editor de informes algo simple al principio, conforme vamos profundizando en sus detalles vemos que podemos hacer cosas bastante potentes. El próximo artículo veremos como realizar informes a varias bandas y como sumar el contenido de varias de ellas.

Pruebas realizadas en RAD Studio 2007.

11 comentarios:

delphi-neftali dijo...

Hola.
Mi nombre es Germán Estévez (Neftalí) y sigo desde hace bastante tiempo tu blog.

Perdona, ya se que no es la forma correcta de ponerse en contacto contigo, pero no he encontrado otra.

Me gustaría comentar contigo la publicación de un contenido que se ha hecho en clubdelphi (del que soy uno de los moderadores) de cierto contenido de tu web; Al menos para que lo sepas y me digas si debemos retirarlo, dejarlo,...

Un saludo.

german_ral[ARROBA]hotmail.com

Administrador dijo...

El contenido de este blog puedes publicarlo sin problemas en el Club Delphi. He aprendido mucho de ese foro.

Si quieres escribirme en privado, me escribes a:

taxylon@gmail.com

Saludos.

Mariano Rocha dijo...

Hola queria saber si puedes escribir de delphi 2010, estoy probandolo y me gustaria leer la opinion de un experto.

Administrador dijo...

Entre las vacaciones y el atraso que llevo de trabajo, últimamente lo tengo muy crudo para actualizar este blog.

Cuando me quite el lío de trabajo que tengo encima seguiré escribiendo artículos con normalidad.

Tengo que escribir no solo de Delphi 2010 sino del nuevo Delphi XE que tiene buena pinta por la demo que estoy probando.

Saludos.

MAXIUM dijo...

Vuelve Taxylon, añoramos tus aportes.

Administrador dijo...

Ya queda menos para quitarme el lio de trabajo que tengo encima. Ya estoy metiéndole mano a RAD Studio XE.

Saludos.

HALWSEMON dijo...

hola amigo.. muy bueno tu blog.. apenas estoy comensando a leerlo y tiene cosas muy buenas.. oye amigo ando buscando dos soluciones.. como agregar a un memo informacion.. en forma lineal. es decir sin el lines.add.. y el otro seria.. tienes de casualidad alguna forma de crear archivos xml!?.. saludos....

Administrador dijo...

La forma más fácil de crear archivos XML es utilizando los componentes TClientDataSet, que permite almacenar la información en binario o en XML.

Mira la documentación de este documento y verás que fácil es.

Saludos.

santiago14 dijo...

.... Aunque Report Manager pueda parecer un editor de informes algo simple al principio, conforme vamos profundizando en sus detalles vemos que podemos hacer cosas bastante potentes. El próximo artículo veremos como realizar informes a varias bandas y como sumar el contenido de varias de ellas.

Compañero, muy bueno tu blog. ¿Has escrito algo mas después de este último? pues no lo he podido encontrar.

Un saludo.

Administrador dijo...

Pues no, este fue mi último artículo en el blog.

Si tuviese tiempo seguiría escribiendo, pero no hay manera.

Maldita crisis.

João Júnior dijo...

Hola, saludos a todos del blog... tengo un problema al cargar un archivo .rep, sale la siguiente mensaje: "La aplicación no admite la depuración Just In Time (JIT)
de Windows Forms. Póngase en contacto con el autor de la aplicación para obtener más
información". ¿Hay alguna solución?. Un cordial saludos a todos.

Publicidad