Wrong behavior when calculating summaries for groupfooters in preview
Hi!
I?m using the ReportBuilder Enterprise Edition Version 9.03.
The Report:
My actual task is to create a report that displays grouped data in the
Detailband. Addtionally every group has its own header in the
GroupHeaderBand and some statistical values in the GroupFooterBand.
Because the statistical values of the group are too complex to be
calculated by simple CalcFields I calculate them manually in RAP, by
adding the needed values in each DetailBeforeGenerate-Event to global
variables.
the Report ist set to TwoPass (for page numbers) and CachePages = True,
the mentioned group is set to 'Keep group together' and 'Reprint group
headers on subsequent pages'.
The Problem:
At first sight everything works fine:
-When all Datarows can by displayed on one single page the footer?s values
are calcualted correctly.
-When moving page by page through the preview the values are also
correctly calculated, even if there are too much DataRows to show on one
single page.
My Problem occurs, when I jump directly to a specific page for example the
last page that definitely contains a GroupFooter with the summary values.
In this case only the DataRows of the last page are added to my
calculations by the DetailBeforeGenerate-Event, but if there are also rows
of this group on the previous page/s these are not effected, which leads
to wrong values in the calculations.
Strange thing is, that I found out that in the FirstPass everything works
fine, because page by page is caculated in the Report. Because of
CachePages is set to true, in my opinion it would not be neccesary to
caculate even one page again afterwards. But the Problem is, that in the
SecondPass as the user goes through the Preview manually, everything is
calculated again (and in my described case it is calculated wrong).
How can I solve this problem?
Regards
Ralf
--- posted by geoForum on http://delphi.newswhat.com
I?m using the ReportBuilder Enterprise Edition Version 9.03.
The Report:
My actual task is to create a report that displays grouped data in the
Detailband. Addtionally every group has its own header in the
GroupHeaderBand and some statistical values in the GroupFooterBand.
Because the statistical values of the group are too complex to be
calculated by simple CalcFields I calculate them manually in RAP, by
adding the needed values in each DetailBeforeGenerate-Event to global
variables.
the Report ist set to TwoPass (for page numbers) and CachePages = True,
the mentioned group is set to 'Keep group together' and 'Reprint group
headers on subsequent pages'.
The Problem:
At first sight everything works fine:
-When all Datarows can by displayed on one single page the footer?s values
are calcualted correctly.
-When moving page by page through the preview the values are also
correctly calculated, even if there are too much DataRows to show on one
single page.
My Problem occurs, when I jump directly to a specific page for example the
last page that definitely contains a GroupFooter with the summary values.
In this case only the DataRows of the last page are added to my
calculations by the DetailBeforeGenerate-Event, but if there are also rows
of this group on the previous page/s these are not effected, which leads
to wrong values in the calculations.
Strange thing is, that I found out that in the FirstPass everything works
fine, because page by page is caculated in the Report. Because of
CachePages is set to true, in my opinion it would not be neccesary to
caculate even one page again afterwards. But the Problem is, that in the
SecondPass as the user goes through the Preview manually, everything is
calculated again (and in my described case it is calculated wrong).
How can I solve this problem?
Regards
Ralf
--- posted by geoForum on http://delphi.newswhat.com
This discussion has been closed.
Comments
When making calculations in ReportBuilder, you need to be sure you always
use the OnCalc event of a TppVariable. Other events, such as the
BeforeGenerate and BeforePrint have the possibility to fire multiple times
per record and do not contain any logic to cache values as a user moves
through a report. I would suggest placing TppVariables inside the
GroupFooterBand and updating their values in the OnCalc events and see if
that solves the problem.
----------------------------------------------------------------------
TECH TIP: Performing Calculations
----------------------------------------------------------------------
Calculations can be done either on the data access side
or within ReportBuilder.
When designing reports there are always decisions to be made as to how much
processing to do on the data side versus the report side. Usually doing more
on one side can greatly simplify the other. So it is often a personal choice
based on the power and flexibility of the data and report tools being used.
DataAccess
----------
a. Use SQL - using SQL you can perform many common calculations:
example: Select FirstName + ' ' + LastName As FullName,
Quantity * Price AS Cost,
b. Delphi TDataSets enable you to create a calculated TField object and use
the DataSet.OnCalcFields event
c. Perform any amount of data processing, summarizing, massaging etc. to
build a result set (query or temp table) to feed to the report.
ReportBuilder
-------------
Calculations in ReportBuilder are performed primarily using the TppVariable
component.
a. Set the Variable.DataType
b. Code the calculations using the Variable.OnCalc event.
c. Use the Timing dialog to control the timing of the OnCalc event. To
access the Timing dialog, right click over the Variable component and select
the Timing... option from the speed menu.
d. Set the LookAhead property to True, when you need to display summary
calculations in the title, header, group header, etc.
e. To perform calculations based on the results of other calculations use
the Calc Order dialog of the band. To access the Calc Order dialog, right
click over the Band component and select the Calc Order... option from the
speed menu.
By using TppVariable components ReportBuilder will take care of caching
intermediate results of accumlated calcs that cross pages.
There are a number of calculation examples in the main demos.dpr project.
---
Additional Notes:
1. Do NOT use Band.BeforePrint or Band.AfterPrint. These events fire
multiple times and therefore should not be used for calculations.
2. Do NOT store results in variables that exist outside of the reports.
For example - form level variables.
--
Regards,
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Sorry, my previous post was a bit confusing. The problem does not relate to
the actual components you are using to make the calculations but rather in
the ReportBuilder events you are using to make them in. As you mentioned in
your first post, during the first pass, everything is being caluculated
correctly then during the second pass (if the entire report is not viewed
page by page) errors can occur. Using the OnCalc event of a TppVariable
(whether you actually use the TppVariable component or not) will ensure that
this does not happen.
Putting TppVariables aside, one thing to try would be to check which pass
you are currently in before executing the code you have inside your
DetailBand.BeforeGenerate event. If you only execute the calculation during
the first pass, you may be able to avoid any problems.
if Report.FirstPass then
//execute BeforeGenerate code
--
Regards,
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
I guess, I didn?t explain my problem good enough, but give me another try:
First of all, I can?t calculate my summaries on the data layer (like you
suggested via SQL) because at one hand I can?t manipulate the data
request, I only get a DataTable from my other colleagues and that it. At
the other hand it would not be possible to make my calculations via SQL
because the calculated values are dimensioned values (I hope I translated
that correct, but I?ll explain that later). Well, all I want to say here:
I have to do my calc in the report directly.
As I already told you (indirectly) I can not use Variable.DataType or
DBCalc.Datatype controls to calculate my summaries because these values
are dimensioned: The field I want to summarize is a string field and
contains values like 'kg;-2;123' (== 1,23 Kilogram). Let me give you a
concrete but simple example: Let assume there are three Datarows in the
same group with the following values:
'kg;-2;1'
'g;-0;2000'
'kg;-2;30'
The correct summary that should be displayed would be '2,32 kg' or '2320 g'...
I guess you understand now, why I don?t calculate my Groupsummaries via
Variable.Datatype. Therefore I have a separate .dll that provides an
object to calculate the correct values to my ReportDesigner.
Calculating the summaries for my dimensioned fields with my dll works in
five steps:
1. CreateSumObject {No Problem => is done in GlobalOnCreate of the Report}
2. InitGroup(GroupValues) {Initiaties the calculation with some neccesary
group wide values; should be done in the group?s header}
3. AddValue(SingleValue) {Adds the values of the Datarow; should be done
in the Detailband or something like that}
4. ReadSummaries {Read the actual summaries for the footer via properties
from the SumObject and write them to the labels of the group?s footer}
5. FreeSumObject {No Problem => is done in GlobalOnDestroy of the Report}
Well, like I said in the previous post: The hole things works as long as
preview on page after the other. If I jump to a specific page that has
DataRows that are not displayed on this page, the calculation goes wrong,
because the values of the previous page/s are not added to the group.
I hope you have better insight into my problem now.
Any suggestions? :-/
Regards
Ralf
--- posted by geoForum on http://delphi.newswhat.com
To the first part of your response: Using the OnCalc-Event of a TppVariable.
I tried this idea already but recognized a strange behaviour again: I used
three TppVariables in my report, one in the group header, one in the
detail band and one in the group footer. The one in the header I set to
CalcType Groupstart an the corresponing group, the one in the detail band
I set to Traversal and the last one to Groupend.
Then I observed the event firing and recognized that the TppVariable in
the detail band was always fired before the one in the header. I tried out
many settings and other arrangements (eg LookAhead or CalcOrder / all
three TppVariables in the detail band), but it was always the same. Only
the OnCalc in the Footer was fired correctly but at the beginning of a new
group the OnCalc of the DetailBand was always fired one time before the
OnCalc in the header, then the other details followed. I don??t know how to
get the correct order for the TppVariables... Could you explain me how to
set up the TppVariables, so I can use them for my problem (init,
add...add, evaluate)?
To the second suggestion of your response: Before I opened this thread I
already played around with the Report.FirstPass and Report.SecondPass
properties. I figured out that using a 'if not Report.SecondPass then' in
the GroupFooterBeforeGenerate could prevent that the correct values were
overwritten in the second pass. At the first sight this seemed to work,
because in my test data I had only one group, but as I used more than one
group in my data I recognized that after the report ended with the whole
calculation ALL group summaries where reset to the values of the LAST
group. This is a really strange behavior that I can??t comprehend.
If you could explain at least one of these behaviours to me, then I could
give the whole thing another try.
I really hope you can help me solving this problem...
Regards
Ralf
--- posted by geoForum on http://delphi.newswhat.com
If possible, please send a small example that demonstrates the behavior you
describe below (or perhaps the original problem). I believe that if I can
see what is happening first hand, I will have a better chance of
understanding what you are trying to accomplish and provide you with a
solution. Send the example to support@digital-metaphors.com in .zip format.
--
Regards,
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Thanks for your sample project and efforts. In fact your sample did not
work properly on my environment at all and even your Report was not
displayed correctly in my ReportDesigner, but at least I was able the
check the structure of the report, your code and the idea behind it.
Now everything works as expected.
Big thanks to you and your team.
Regards
Ralf
--- posted by geoForum on http://delphi.newswhat.com