PDA

Ver la Versión Completa : LazReport: Calcular Subtotales por página


razor7
17-08-2010, 20:28:43
Hola, estoy trabajando con LazReport y no encuento la manera de colocar el subtotal de una columna en cada página.

Lo que necesito es que si el reporte tiene, por ejemplo, 3 páginas, que se calcule el subtotal de cada una de ellas, sumandole el anterior.

Ej: Si el subtotal de cada página es $100, necesitaria mostrar el subtotal de la página 1 ($100) el de la página 2 ($200) y el de la 3 ($300).

Alguien sabe como sonseguir eso?

Gracias!

razor7
18-08-2010, 16:38:13
Hola, disculpas por el Bump, pero necesito ayuda con esto.

Gracias!

Casimiro Notevi
18-08-2010, 17:45:46
Si no trae un componente específico para hacerlo entonces tendrás que usar una variable donde vayas almacenando la suma e ir imprimiéndola por página.

rretamar
19-08-2010, 16:47:27
Si no trae un componente específico para hacerlo entonces tendrás que usar una variable donde vayas almacenando la suma e ir imprimiéndola por página.

Es así como dice Casimiro. Los reporteadores suelen tener un evento que se dispara cada vez que se llega al fin de página. Ahí se puede escribir el código que muestre ese subtotal.

(recuerdo los malabarismos que hice con código para en el QuicReports 4 poder imprimir un listado a dos columnas por página)

razor7
20-08-2010, 02:23:41
Hola, lamentablemente ese método no soluciona el problema. Si tengo un informe de 3 páginas, en la primera me muestra $100, en la segunda $100 y en la tercera $100 como subtotales!!!.

De todas maneras ya encontre una solución que paso a explicar por si alguien necesita hacer algo similar.

Creo una variable global entera llamada totalPages (increible pero no encontre esta propiedad en el componente TfrReport)
totalPages:Integer;
En el evento OnBeginDoc inicializo la variable totalPages:=0; (es importante hacer esto puesto que si en una ejecucion del programa se muestra varias veces un reporte cualquiera, la variable puede seguir contando páginas de otros reportes)
procedure TForm1.frReport1BeginDoc;
begin
totalPages:=0;
end;
En el evento OnEndPage incremento la variable totalPages, ademas agregue unas condiciones para que no incremente constantemente la variable en un reporte de dos pasadas como es el caso de mis reportes.
procedure TForm1.frReport1EndPage(pgNo: Integer);
begin
if frReport1.DoublePass and not frReport1.FinalPass then
Inc(totalPages);
end;
Luego acumulo el valor de la columna que quiero sumar en una variable, usando los eventos, OnFirst y OnNext de un componente TfrDBDataSet. En mi caso use un TSqlite3Dataset como fuente de datos del TfrDBDataSet.
procedure TForm1.frReport1First(Sender: TObject);
begin
total_acum:=0;
total_acum:=total_acum+Sqlite3Dataset1.FieldByName('nombre_del_campo').Value;
end;

procedure TForm1.frReport1Next(Sender: TObject);
begin
if not frPackinglist_det.Eof then
total_acum:=total_acum+Sqlite3Dataset1.FieldByName('nombre_del_campo').Value;
end;
Hasta aqui obtengo los valores acumulados, ahora solo basta pasarselos al reporte. Por alguna extraña razon, siempre acumula un elemento mas del que se muestra en el reporte, por ejemplo, si en la primera hoja del reporte hay 25 elementos, suma 26...por eso, es necesario saber cuantas paginas tiene el reporte...de ahi la condicion, si estas en la ultima pagina, mostra la sumatoria, si no, mostra la sumatoria menos el elemento actual (que seria el 26), de paso, como en mi caso se trata de un Float, lo paso formateado.
procedure TForm1.frReport1GetValue(const ParName: String;
var ParValue: Variant);
begin
if ParName='TOTAL_ACUM' then
begin
if frReport1.EMFPages.Count = totalPages then
ParValue:=FormatFloat('0.#0',total_acum)
else
ParValue:=FormatFloat('0.#0',total_acum - Sqlite3Dataset1.FieldByName('nombre_del_campo').Value);
end;
end;
Por ultimo, solo basta crear un memo en el reporte con el texto Dummy (para poder identificarlo) con el siguiente código en su script
begin
Text:=TOTAL_ACUM;
end;
Para evitar errores al previsualizar el reporte, conviene crear la variable "TOTAL_ACUM" en el editor de variables del reporte, y luego asignerle el valor [Nada]

Con esto logro tener subtotales acumulativos por página

Espero que les sirva, adjunto un PDF para que se vean los resultados, tener en cuenta que el total esta tomado de la base de datos y el sub total es el valor calculado, con eso se confirma que el metodo funciona bien.

http://www.mgscreativa.com/Invoice_DB-10-0548.pdf

Casimiro Notevi
20-08-2010, 18:09:57
Precisamente esa era la solución que te dimos, usando una variable :)

Por cierto, si usas la variable integer no funcionará correctamente cuando tengas importes con decimales.

razor7
20-08-2010, 18:22:12
Precisamente esa era la solución que te dimos, usando una variable :)

Por cierto, si usas la variable integer no funcionará correctamente cuando tengas importes con decimales.

Hola, me parece que hay una pequeña diferencia entre tu solucion "Si no trae un componente específico para hacerlo entonces tendrás que usar una variable donde vayas almacenando la suma e ir imprimiéndola por página." y el post que escribi.

Por otro lado, la variable "total_acum" debe ser Double, pero en ningun momento lo ongo en el post por que seguro que el que quiera implementarlo lo sabra.

Por ultimo, por favor, lean el post completo, creo que esta bastante detallado.

Saludos!