[Lazarus-es] Fw: Sumar grupos a partir de una variable en un reporte

Jesus Reyes jesusrmx en yahoo.com.mx
Lun Ago 26 17:27:03 CEST 2013


Citado: De: Martin Gomez <mmgomez en gmail.com>
[
En QuickReports (o era en FastReports? no lo recuerdo bien) podías poner los totales de grupo arriba, pero para hacerlo con una variable deberías sumar en cada renglón del grupo en esa variable, para que esté disponible y no sea 0.

Aquí hay una explicación en inglés:
http://www.fast-report.com/en/documentation/frx3user/Script/Printing%20the%20groups%20sum%20total%20in%20the%20groups%20header.htm
]


Parece que FastReport tiene un sistema de script mas avanzado que LazReport el cual no tiene eventos en los scripts, sin embargo algo parecido puede hacerse. Ver mas abajo.


Citado: De: Martin Gomez <mmgomez en gmail.com>
[Por cierto, los correos de Ismael no me llegan, sólo me llegan comentados en las respuestas de Maxi, a alguien más le pasa esto?
]

He revisado en la interfaz de administración de la lista y no encontré nada que pudiera estar filtrándote los mensajes, debe ser algo en tu ISP o en tu cliente de correo. 



2013/8/25 Maxi <maximiliano.duarte en gmail.com>

El día 23 de agosto de 2013 13:09, Ismael L. Donis Garcia
><ismael en citricos.co.cu> escribió:
>> Nadie de la lista me podría ayudar en el mensaje de abajo.
>>
>> He probado de las siguiente formas:
>>
>> [SUM([SALDEBE] ,MasterData1)]
>> [SUM(SALDEBE ,MasterData1)]
>> [SUM([SALDEBE ,MasterData1])]
>>
>> Y de ninguna me suma, siempre el valor devuelto es 0.
>>

>> Sin embargo si la pongo en el pie del grupo si me suma bien el resultado.


Esto es correcto, las funciones "aggregate" no son evaluadas en los las bandas encabezados.

>> Pero yo necesito la sumatoria en el encabezado del grupo, ósea en la parte
>> superior, no en la parte inferior.
>>

Como ya comenté, LazReport no tiene un interprete tan sofisticado como FastReport, pero la explicación que dan es igualmente válida en LazReport: Para obtener las sumatorias es necesario recorrer todos los registros involucrados y esto solo se puede hacer en un reporte de dos pasos (menu File->Report options->Two-pass report), en el primer paso se recolectan las sumas de los pies de grupo que se usan en un segundo paso en los encabezados de grupo.

Creo que hay algunas variaciones en cuanto a como hacerlo en LazReport, yo exploré la siguiente en un reporte ficticio de ventas por sucursal por departamento, así que tengo dos grupos anidados (después incluiré el ejemplo en LazReport)

Branch1 (TotalBranch1)

    Depto1 (TotalDepto1)
        Art1    price1
        Art2    price2
    Total      TotalDepto1

    Depto2 (TotalDepto2)
        Art1    price1
        Art2    price2
    Total      TotalDepto2

    ETC.
Total TotalBranch1

Branch2 (TotalBranch2)

ETC.


Sucursal y Departamenteo tienen la suma correspondiente tanto en el encabezado como en su pie de grupo. La estructura del reporte sería así:

Banda: GroupHeader, nombre:BranchHeader, condición=[branch]
Texto: Branch [branch], texto: [branch_sum]

Banda: GroupHeader, nombre:DeptoHeader, condición=[depto]
  memo: Depto [depto], memo: [depto_sum]
Banda: MasterData, nombre:MasterData1
  memo: [article]  memo: [price]

Banda:GroupFooter, nombre:DeptoFooter
  memo:Total [Sum([price], MasterData1)]


Banda:GroupFooter, nombre:BranchFooter
  memo:Total [Sum([price], MasterData1)]
En el componente TFrReport asignamos los siguientes eventos:

OnBeginBand():
....
if not frReport1.FinalPass then begin
  // PRIMER PASO
    if Band.name='BranchHeader' then begin
  
  i := Length(Hdrs);
  
  SetLength(Hdrs, i+1);
  end;
  if Band.Name='DeptoFooter' then begin
  
  i := Length(Hdrs)-1;
  
  j := Length(Hdrs[i].Deptos);
  
  SetLength(Hdrs[i].Deptos, j+1);
  
  Hdrs[i].Deptos[j] := frParser.Calc('SUM([price], MasterData1)');
  end else
  if Band.Name='BranchFooter' then begin
  
  i := Length(Hdrs)-1;
  
  Hdrs[i].Sum:= frParser.Calc('SUM([price], MasterData1)');
  end;
end else begin
  // SEGUNDO PASO
    if Band.Name='BranchHeader' then begin
  
  // reset depto index
  
  fDeptoIndex := -1;
  
  inc(fBranchIndex);
  end else
  if Band.Name='GroupHeader2' then begin
  
  inc(fDeptoIndex);
  end;
end;

Para llevar el registro de las sumas por sucursal y departamento utilizo un array de este tipo:

TBranch=record
  Sum: variant;
  Deptos: array of variant;
end; 
Hdrs: array of TBranch;

En el PRIMER PASO cada vez que aparece el BranchHeader aumento un elemento en el array Hdrs[] 
y cada vez que aparece un DeptoFooter aumentamos un elemento en Hdrs[x].Deptos[] y almacenamos ahí la suma del Depto actual, esto lo hacemos mendiante la evaluación de frParser.Calc(SUM[price], MasterData1); cada vez que aparece un BranchFooter mendiante la misma técnica calculamos la suma del Branch actual y la almacenamos en Hdrs[x].Sum

Con esto se han colectado todas las sumas, en el SEGUNDO PASO solo es necesario ir "indexando" cada uno de los encabezados conforme van siendo solicitados. Para que el índice de la sucursal sea el correcto lo iniciamos en el OnBeginDoc del TfrReport o en cualquier momento antes de iniciar el reporte.


OnBeginDoc()
...
FBranchIndex := -1;



Estos indices son utilizados "bajo demanda" en el evento:

OnGetValue()
...
if ParName='branch_sum' then
  ParValue := Hdrs[FBranchIndex].Sum;

if parName='depto_sum' then
  ParValue := Hdrs[FBranchIndex].Deptos[FDeptoIndex];



Esta técnica requiere al menos LazReport r40866 (o una anterior parchada con la susodicha revisión) que implementa obtener el nombre de la banda actualmente procesada en el evento OnBeginBand.
Supongo que para una cantidad mayor de grupos anidados, llevar el registro de todos las sumas se convierte en un desafio aún mayor. :)

Saludos.

Jesus Reyes A.
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es




More information about the Lazarus-es mailing list