How can I increment a variable with value of another variable in JasperReports? - jasper-reports

I need to make a grand total of the items I'm counting in a subReport. To do that, I think I need to add the value of that variable to another variable for each iteration, or "increment" it by that value. The subReport gets called for each group, and I get a total for that group. I need to add the variable values, rather than database columns/fields.
I'm receiving an integer returnValue from the subReport, which is itself the count of rows in the sub-report. I want to get the grand total, since that subReport is called multiple times for the different results (each for a GROUP) from my main SQL query. I want to add up all the results, but I'm getting a null value. I tried adding an operation to the subReport as a new returnValue and choosing Sum as the operation, but that also yielded a null.
<variable name="itemCount" class="java.lang.Integer" resetType="None"/>
<variable name="grandCount"
class="java.lang.Integer"
incrementType="Group"
incrementGroup="ITEM_BUNDLE">
<variableExpression><![CDATA[$V{itemCount}]]></variableExpression>
</variable>
...
<returnValue subreportVariable="countItems" toVariable="itemCount"/>

Add attribute calculation="Sum" to variable name="grandCount"
or pass grandCount to subreport as parameter
<subreportParameter name="grandCount">
<subreportParameterExpression><![CDATA[$P{grandCount}]]></subreportParameterExpression>
</subreportParameter>
in subreport declare variable countItems with initialValue of parameter grantCount
<variable name="countItems" .... >
<variableExpression><![CDATA[$P{itemCount} + $P{grandCount}]]></variableExpression>
<initialValueExpression><![CDATA[$P{grandCount}]]></initialValueExpression>
</variable>
and return
<returnValue subreportVariable="countItems" toVariable="grandCount" calculation="Sum"/>

Im not exactly shure how to write it in JRXML since i use iReport.
In iReport, i create a new Variable, with class type "Integer", and calculation type "System"
The calculation type is important here.
In the variable expression, you will need something like $V{grandCount} = $V{grandCount} + $V{itemCount}
NOTE: JasperReports render band by band, so you wont be able to use the grandCount variable in a band before the subreport band.
Hope im not too late

You might try to increment your variable (I named it totalSum) only when the band (group) is equal to the one on which the subreport is. For this you would need a field in the report to give you the current band (group).
<variable name="totalSum"
class="java.lang.Integer"
resetType="Report"
incrementType="Group"
incrementGroup="ITEM_BUNDLE"
calculation="Nothing">
<variableExpression>
<![CDATA[new Boolean($F{reportPart}.equals("The_band_with_the_subreport")).booleanValue() ? $V{returnValue} : $V{totalSum}]]>
</variableExpression>
<initialValueExpression>
<![CDATA[new Integer(0)]]>
</initialValueExpression>
</variable>
I'm not sure if this works, I don't have the context to test it. But you might also try a second solution - with three variables. For example, you keep the value returned from the subreport (let's say returnValue) in a variable and you use another two variables to hold the sum - one until the subreport is called (let's say partialSum) and the second to store the sum between the returnValue and the partialSum. Let's call it totalSum. Then you would have something like this for totalSum:
<variable name="totalSum"
class="java.lang.Integer"
resetType="Report"
incrementType="Group"
incrementGroup="ITEM_BUNDLE"
calculation="Nothing">
<variableExpression>
<![CDATA[$V{returnValue} + $V{partialSum}]]>
</variableExpression>
<initialValueExpression>
<![CDATA[new Integer(0)]]>
</initialValueExpression>
</variable>
For partialSum, you'll have something like this:
<variable name="partialSum"
class="java.lang.Integer"
resetType="Report"
calculation="Sum"
incrementType="None">
<variableExpression>
<![CDATA[new Boolean($F{reportPart}.equals("The_band_with_the_subreport")).booleanValue() ? $V{returnValue} : new Integer(0)]]>
</variableExpression>
<initialValueExpression>
<![CDATA[new Integer(0)]]>
</initialValueExpression>
</variable>
I hope this helps a bit. It would be easier to make all these settings from iRport directly on the report you want to use.

Related

Variable value not getting printed in Detail band

I am working on a jasper report which uses following query:
select * from user_type
columns:
user_type
visit_date
sessions
user_type have values either "New Visitor" or "returning Visitor".
To get count of sessions of "New Visitor" I am creating a variable as:
<variable name="new_visitor" class="java.lang.Long" calculation="Sum">
<variableExpression><![CDATA[$F{user_type}.equals("New Visitor") ? $F{sessions} : 0]]></variableExpression>
</variable>
But when I print value of this variable in detail band or summary band its printing only zero.
Can someone please tell me what I am doing wrong here?

I want to create Variable count in JasperReport

In my report, I have two values of column "Status" are: Y/N.
I want to count "Y" in "Status".
I created a variable $V{count_y} with Variable Expression : String.valueOf($F{status})=="Y" but $V{count_y} count all record (include Y and N).
<variable name="count_y" class="java.lang.Integer" calculation="Count">
<variableExpression><![CDATA[String.valueOf($F{status})=="Y"]]></variableExpression>
</variable>
Now, how can i count?
Thanks !
Create variable like this
<field name="status" class="java.lang.String"/>
<variable name="countY" class="java.lang.Integer" calculation="Sum">
<variableExpression><![CDATA[$F{status}.equals("Y") ? 1 : 0]]></variableExpression>
</variable>
and put $V{countY} into Summary band

How to have a constant records from array in subreport?

How to do in order to have a constant limit records for each value in subreport ?
When you define the datasource expresionof your subreport you can apply the sublist function:
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{list}.subList(0,100))
in your xml, you will have something like:
<subreport>
<reportElement x="x" y="x" width="xx" height="xx" isPrintInFirstWholeBand="xx" uuid="xxx"/>
<dataSourceExpression><![CDATA[net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{list}.subList(0,100))]]></dataSourceExpression>
<subreportExpression>xxxxx</subreportExpression>
</subreport>

Jasper Reports: page x of y within one record

I have report with multiple records, where one record is consisting of 1-5 pages. How to display "page x of y", where x is a number of page for actual record and y is total pages for actual record ? I have something like below for x variable (reset on new record, incremet by page), but it doesn't work (on each page x have 1 value):
<variable name="x" class="java.lang.Integer" resetType="Group" resetGroup="report_count" incrementType="Page" calculation="Count">
<variableExpression><![CDATA[1]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(1)]]></initialValueExpression>
</variable>
<!-- group by record -->
<group name="report_count" isStartNewPage="true">
<groupExpression><![CDATA[$V{REPORT_COUNT}]]></groupExpression>
</group>
<textField evaluationTime="Now" evaluationGroup="report_count">
<reportElement x="141" y="5" width="156" height="20"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA["Page "+$V{x}+" of"]]></textFieldExpression>
</textField>
The problem is that calculation="count" does not do what you are expecting it to. It returns the count of non-null values that your variableExpression returns. As your variableExpression only returns a single value, the variable is always set to 1.
An easy solution is to set the calculation type to "Nothing", and the variableExpression to $V{x}+1
i.e:
<variable name="x" class="java.lang.Integer" resetType="Group" resetGroup="report_count" incrementType="Page" calculation="Nothing">
<variableExpression><![CDATA[$V{x} + 1]]></variableExpression>
<initialValueExpression><![CDATA[new Integer(1)]]></initialValueExpression>
</variable>
Edit: Alternative solution
The group tag can have the attribute isResetPageNumber. When set to true it will reset the built-in variable PAGE_NUMBER at the start of every group. As you are already grouping by each record, I think this should give you the effect you are looking for.

Conditional Sum (variable)

A report in iReport (4.0.1) with various fields includes: $F{value} (Integer) and $F{created_at}.
I'd like to calculate variables that would give:
the sum of $F{value} when $F{created_at} is before a given date
the sum of $F{value} when $F{created_at} is after a given date
Any idea how this could be done?
You will have to use two different variables to do this. For your variables, use something like this in the 'Variable Expression'. The Date class also has an after() function. If the expression evaluates to true $F{value} will be added, otherwise 0 will be added.
$F{created_at}.before($P{givenDate}) ? $F{value} : 0
To use a variable to sum, you need to change the calculation type to "Sum". The default reset type, report will sum values over the entire report. The other reset types work the same way just over different sections of the report (column, page or group).
Here is the XML for the "before" case:
<variable name="sumValueCreatedBefore" class="java.lang.Integer" calculation="Sum">
<variableExpression><![CDATA[F{created_at}.before($P{givenDate}) ? $F{value} : 0]]></variableExpression>
</variable>
there is another solution for that : write sub query in the select statment
like
Select
(select sum(Fieldname) from tablename where dategiven date) as aftersum
from tablename
where conditions