【问题标题】:How can I increment a variable with value of another variable in JasperReports?如何在 JasperReports 中使用另一个变量的值来增加一个变量?
【发布时间】:2016-06-18 19:49:39
【问题描述】:

我需要汇总我在子报表中计数的项目。为此,我认为我需要将该变量的值添加到每次迭代的另一个变量中,或者按该值“增加”它。为每个组调用 subReport,我得到该组的总数。我需要添加变量值,而不是数据库列/字段。

我从subReport 收到一个整数returnValue,它本身就是子报告中的行数。我想得到总计,因为从我的主 SQL 查询中多次调用 subReport 以获得不同的结果(每个结果都用于一个 GROUP)。我想将所有结果相加,但我得到了 null 值。我尝试将操作添加到subReport 作为新的returnValue 并选择Sum 作为操作,但这也产生了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"/>

【问题讨论】:

  • 我认为这个问题对于有 Jasper 经验的人来说应该很简单......不是吗?

标签: jasper-reports


【解决方案1】:

将属性calculation="Sum"添加到variable name="grandCount"

或将grandCount 作为参数传递给子报表

<subreportParameter name="grandCount">
<subreportParameterExpression><![CDATA[$P{grandCount}]]></subreportParameterExpression>
</subreportParameter>

在子报告中声明变量 countItems 与参数的初始值 grantCount

<variable name="countItems" .... >
   <variableExpression><![CDATA[$P{itemCount} + $P{grandCount}]]></variableExpression>
   <initialValueExpression><![CDATA[$P{grandCount}]]></initialValueExpression>
</variable>

然后返回

<returnValue subreportVariable="countItems" toVariable="grandCount" calculation="Sum"/>

【讨论】:

  • 谢谢!我最初是沿着这条路开始的,但是每当我添加初始值时,iReport 都会给我一个虚假错误——它说 initialValueExpression 的类与变量的类不兼容(当它们是“新整数(0)”时)和'java.lang.Integer')——诀窍是编译报告,关闭它,然后重新打开它。我闻到了虫子的味道。 :-)
【解决方案2】:

由于我使用 iReport,我并不完全确定如何在 JRXML 中编写它。 在 iReport 中,我创建了一个新变量,类类型为“整数”,计算类型为“系统” 计算类型在这里很重要。

在变量表达式中,您需要 $V{grandCount} = $V{grandCount} + $V{itemCount}

注意:JasperReports 逐个波段呈现,因此您不能在子报告波段之前的波段中使用 grandCount 变量。

希望我不会太迟

【讨论】:

  • 感谢您的回复,medopal。主要问题是你不能简单地添加像 $V{a} = $V{a} + $V{b} 这样的变量,因为 $V{a} 实际上是像 variable_a.value() 所以它是只读的。我只想在报告末尾的报告摘要带中获得总计。第二个问题是我似乎无法初始化变量(使用 Initial Value Expression 为 0 — 甚至使用“new Integer(0)”
  • 我很确定我在 iReport 中使用 new Integer(0) 进行了初始化,但不确定 $V = $V1 + $V2。无论如何,我建议两种方法: 1- 在您的 sql 查询或返回 bean 中找到总计并将其作为参数传递。老实说,我从不相信 Jasper 如何处理返回变量。 2- 在 Jasper 中,您始终可以链接到您自己代码的 Java 方法。使用静态标识符创建一个方法。假设 public static void myReportRecordCount(int i){ staticGrandTotal+=i; } 从子报表详细信息部分调用此方法。在摘要带中,放置一个读取静态变量的方法。
  • Re: 1- 是的,在主报表中执行子报表重新执行的操作的更复杂的 SQL 查询可能是可能的,但是生成此报表已经需要 5 分钟,所以我不想推它。如果运行时间过长,它会使我的产品无法使用。回复:2- 我从标准 JDBC 数据库连接报告,我真的希望我的客户能够使用 iReport 使用和修改报告,而无需将我的自定义代码添加到他们的 CLASSPATH。
  • 5 分钟?我做了很少的统计报告,它们非常复杂,打印在A3纸上,有100多页,查询从来没有花5分钟!您可能想要调整您的查询。关于我的第一个建议,我提出了类似 select count(x) from table1 where group_one,group_two.... 条件的建议。然后将此变量发送到报告。选择计数不应该产生很多开销,它是一个轻量级的查询。
  • 您对“new Integer(0)”的保证非常有价值。事实证明这是 iReport 3.6.0 中的一个脆弱/错误问题。至于生成报告所需的时间,我一直在处理的数据集非常大(>300,000 行,大约 30 列)并且运行着一个调整不佳的 Microsloth SQL Server 2000 实例。
【解决方案3】:

只有当波段(组)等于子报告所在的波段时,您才可以尝试增加变量(我将其命名为 totalSum)。为此,您需要报告中的一个字段来为您提供当前乐队(组)。

<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>

我不确定这是否有效,我没有上下文来测试它。但您也可以尝试第二种解决方案 - 使用三个变量。例如,您将子报表返回的值(比如说 returnValue)保存在一个变量中,并使用另外两个变量来保存总和 - 一个直到子报表被调用(比如说 partialSum ) 和第二个存储 returnValue 和 partialSum 之间的和。我们称之为总和。那么你会有这样的总和:

<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>

对于 partialSum,你会得到这样的结果:

<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>

我希望这会有所帮助。直接在您要使用的报告上从 iRport 进行所有这些设置会更容易。

【讨论】:

  • 这是一个很酷的想法,但对于我正在尝试做的事情来说,它并不像我想要的那样直截了当。感谢您的贡献!它帮助我以不同的方式思考问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
  • 1970-01-01
相关资源
最近更新 更多