I am trying to create a variable "public_notes" that is incremented every time the group "coverageTypeCode" changes.
I have added such a variable using iReport, and this is what I got (added line breaks for formatting):
Code: |
<variable name="public_notes" <br /> class="java.lang.String" <br /> resetType="Group" <br /> incrementType="Group" <br /> incrementGroup="coverageTypeCode" <br /> resetGroup="applicationId" <br /> calculation="Nothing"><br /> <variableExpression><br /> <![CDATA[$V{public_notes} + ( $P{public_notes}.containsKey( $F{coverage_type_code} ) ? ($V{public_notes}.length() > 0 ? "<BR/>" : "" ) + $P{public_notes}.get( $F{coverage_type_code} ) : "" )]]><br /> </variableExpression><br /> <initialValueExpression><br /> <![CDATA[""]]><br /> </initialValueExpression><br /> </variable><br /> </td></tr></tbody></table><br /> I had assumed that since incrementType="Group" and incrementGroup="coverageTypeCode", the variableExpression would only be evaluated when the group changed. But I am finding that it is being evaluated with every record change instead.<br /> <br /> Am I missing something obvious? I am attaching the entire file for reference.<br /> <br /> Thanks,<br /> Dave Cherkassky<br /> DJiNN Software Inc. |
6 Answers:
You should not reference the variable inside its own expression.
The variable expression is called with every row in order to make group break estimations.
What you need is to implement a variable incrementer (JRIncrementer and JRIncrementerFactory interfaces) and associate it to your variable using the incrementerFactoryClass attribute.
Or, you could use a scriptlet to increment the variable.
Basically it is about teaching the JR engine to sum up String values. You'll probably use calculation="Sum" for your variable with custom incrementer, instead of "Nothing".
Our /demo/samples/scriptlet sample shows a similar String concatenation.
I hope this helps.
Teodor
You've given me something to think about. Just a quick follow-up. I changed the variable not to refer to itself and to use calculation="Sum":
Code: |
<variable name="public_notes" <br /> class="java.lang.String" <br /> resetType="Group" <br /> incrementType="Group" <br /> incrementGroup="coverageTypeCode" <br /> resetGroup="applicationId" <br /> calculation="Sum"><br /> <variableExpression><br /> <![CDATA[( $P{public_notes}.containsKey( $F{coverage_type_code} ) ? "<BR/>" + $P{public_notes}.get( $F{coverage_type_code} ) : "" )]]><br /> </variableExpression><br /> <initialValueExpression><br /> <![CDATA[""]]><br /> </initialValueExpression><br /> </variable><br /> <br /> </td></tr></tbody></table>With this expression the report does not work properly either: only the value from the last group is used (i.e. there is no string concatenation).<br /> <br /> Would I be correct in saying that's the case because calculation="Sum" can't apply to Strings? Or should that work, and I have something else wrong...<br /> <br /> (It would be great if I could avoid writing a scriptlet or making this any more complicated than it has to be).<br /> <br /> <br /> All the best,<br /> Dave Cherkassky. |
For completeness, here is the final answer:
Code: |
<variable name="public_notes" <br /> class="java.lang.String" resetType="Group" <br /> incrementerFactoryClass="com.aimcompanies.website.reports.RenewalPublicNotesIncrementorFactory" <br /> incrementType="Group" <br /> incrementGroup="coverageTypeCode" <br /> resetGroup="applicationId" <br /> calculation="Sum"><br /> <variableExpression><br /> <![CDATA[( $P{public_notes}.containsKey( $F{coverage_type_code} ) ? ( String )$P{public_notes}.get( $F{coverage_type_code} ) : null )]]><br /> </variableExpression><br /> <initialValueExpression><br /> <![CDATA[""]]><br /> </initialValueExpression><br /> </variable><br /> </td></tr></tbody></table><br /> <br /> and the RenewalPublicNotesIncrementorFactory is:<br /> <br /> <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>public class RenewalPublicNotesIncrementorFactory extends JRAbstractExtendedIncrementerFactory {<br /> <br /> public static JRExtendedIncrementer INCREMENTOR = new JRAbstractExtendedIncrementer() {<br /> public Object increment( JRCalculable variablePublicNotes, Object publicNote,<br /> AbstractValueProvider abstractValueProvider ) throws JRException {<br /> <br /> String publicNotes = ( String )variablePublicNotes.getIncrementedValue();<br /> if( publicNotes == null ) {<br /> publicNotes = ( String )initialValue();<br /> }<br /> <br /> if( publicNote != null && publicNote.trim().length() > 0 ) ) {<br /> if( publicNotes.length() == 0 ) {<br /> publicNotes = ( String )publicNote;<br /> } else {<br /> publicNotes = publicNotes + "<BR/>" + publicNote;<br /> }<br /> }<br /> <br /> return publicNotes;<br /> }<br /> <br /> public Object initialValue() {<br /> return "";<br /> }<br /> };<br /> <br /> public JRExtendedIncrementer getExtendedIncrementer( byte calculation ) {<br /> if ( calculation == JRVariable.CALCULATION_SUM ) {<br /> return INCREMENTOR;<br /> } else {<br /> throw new UnsupportedOperationException(<br /> "RenewalPublicNotesIncrementorFactory can only do Sum calculations" );<br /> }<br /> }<br /> }</td></tr></tbody></table><br /> <br /> Many thanks,<br /> Dave Cherkassky |
Hi,
I have one question about Matrix/Crosstab reports in JasperReports. I would like to show Departmentwise, which Salesmen, Clerks, Analysts and Managers are working. For example, see below table. There are multiple values in Measure column. Since, I am beginner and have no idea how to print multiple values in Measure field.
I am getting single value means only name of one employee. Not all clerks and salemen are displayed. Even though I choosed 'Nothing' option in the wizard for Measure Field.
I have got an idea somehow that need to implement custom incrementer class and that will be used inside property 'Incrementer Factory class'. But unfortunately, no idea how to start and write that custom class using 'JRAbstractExtendedIncrementer' and 'JRExtendedIncrementer' interfaces.
Does anyone have any report sample using them or any other idea to display such information ??
Looking forward to your replies.
CLERK | MANAGER | PRESIDENT | ANALYST | SALESMAN | |
ACCOUNTING | MILLER | CLARK | KING | JAMES | Null |
RESEARCH | ADAMS SMITH PETER |
JONES | Null | Null | Null |
SALES | JAMES | BLAKE | Null | Null | ALLEN MARTIN TURNER WARD |
Thank you.
Regards,
Eddie