Ver Mensaje Individual
  #5  
Antiguo 20-08-2010
razor7 razor7 is offline
Miembro
 
Registrado: abr 2007
Posts: 30
Reputación: 0
razor7 Va por buen camino
[Solucionado] LazReport: Calcular Subtotales por página

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)
Código:
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)
Código:
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.
Código:
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.
Código:
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.
Código:
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
Código:
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

Última edición por razor7 fecha: 20-08-2010 a las 02:34:31.
Responder Con Cita