Varible incrementing incorrectly

I am using JasperReports 1.2.4 and iReport 1.2.4.

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.
dcherk's picture
484
Joined: Jul 18 2006 - 11:13pm
Last seen: 17 years 2 months ago

6 Answers:

Full file attached (had to change the extension to allow upload) [file name=renewal.txt size=25287]http://www.jasperforge.org/components/com_joomlaboard/uploaded/files/ren...
dcherk's picture
484
Joined: Jul 18 2006 - 11:13pm
Last seen: 17 years 2 months ago
Hi,

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
teodord's picture
53238
Joined: Jun 30 2006 - 9:00am
Last seen: 48 min 10 sec ago
Thanks, 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.
dcherk's picture
484
Joined: Jul 18 2006 - 11:13pm
Last seen: 17 years 2 months ago
Hi,

Yes, the default JR incrementer does not know what Sum means for Strings. You have to teach it with a custom incrementer.
To see how to implement incrementers, you could take a look at those found in JR itself.

I hope this helps.
Teodor
teodord's picture
53238
Joined: Jun 30 2006 - 9:00am
Last seen: 48 min 10 sec ago
Yes, that worked.

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
dcherk's picture
484
Joined: Jul 18 2006 - 11:13pm
Last seen: 17 years 2 months ago

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

 
meet_adnan04's picture
Joined: Apr 1 2014 - 1:38am
Last seen: 2 years 2 months ago
Feedback
randomness