Crystal reports 在记录选择中使用报表参数
我有一个Java应用程序,它通过Java库调用Crystal Reports。其中一个报告的记录选择器中包含以下子句:Crystal reports 在记录选择中使用报表参数,crystal-reports,report,selection,record,in-clause,Crystal Reports,Report,Selection,Record,In Clause,我有一个Java应用程序,它通过Java库调用Crystal Reports。其中一个报告的记录选择器中包含以下子句: and ({DriverMotionView.GROUPID} = {?GroupID1Parameter} or {DriverMotionView.GROUPID} = {?GroupID2Parameter} or {DriverMotionView.GROUPID} = {?GroupID3Parameter} or {DriverMotionView.GROUPID}
and ({DriverMotionView.GROUPID} = {?GroupID1Parameter}
or {DriverMotionView.GROUPID} = {?GroupID2Parameter}
or {DriverMotionView.GROUPID} = {?GroupID3Parameter}
or {DriverMotionView.GROUPID} = {?GroupID4Parameter}
or {DriverMotionView.GROUPID} = {?GroupID5Parameter}
or {DriverMotionView.GROUPID} = {?GroupID6Parameter}
or {DriverMotionView.GROUPID} = {?GroupID7Parameter}
or {DriverMotionView.GROUPID} = {?GroupID8Parameter}
or {DriverMotionView.GROUPID} = {?GroupID9Parameter}
or {DriverMotionView.GROUPID} = {?GroupID10Parameter}
)
每个GroupIDnParameter都是一个整数groupID,通过从UI中的树结构中选择组名创建。UI将这些转换为GroupID并将其传递到报表中。现在,此记录选择器工作,但将选定组的数量限制为10个
我想取消这个限制。为了检查可能的解决方案的语法,我首先尝试了以下方法
and {DriverMotionView.GROUPID} in [-1, 1618, 1608, 1610, -1]
这确实选择了GroupID1618、1608和1610的记录
然后我尝试了类似的方法
and {DriverMotionView.GROUPID} in {?GroupIDListParameter}
其中,GroupIDListParameter作为字符串[-1161816081610,-1]传入。这将导致运行时Crystal Reports错误
我试过了
and {DriverMotionView.GROUPID} in [{?GroupIDListParameter}]
但该子句在语法上不正确,并导致语法检查中出现“array必须被订阅”错误
可能还有另一种方法可以解决这个问题,但我无法在在线帮助、阅读用户指南甚至谷歌搜索中找到它
如果您有任何建议,我们将不胜感激。您说过,{?GroupIDListParameter}是作为字符串传入的,其中包括值周围的括号([])。你是用密码输入的吗?无论您在做什么来获得括号,我都会删除它们,然后在{?GroupIDListParameter}中放置的NUMEBR的逗号分隔字符串周围进行尝试:
{DriverMotionView.GROUPID} in split({?GroupIDListParmeter},",")
您需要将
{?GroupIDListParameter}
设置为多值参数(参数本身的属性)。这将把它当作一个数组,这样您就可以像您已经尝试过的那样,在{?GroupIDListParameter}中使用一个简单的{DriverMotionView.GROUPID}来选择记录
无需对值进行分隔或使用方括号。答案如下。我换了
and ({DriverMotionView.GROUPID} = {?GroupID1Parameter}
or {DriverMotionView.GROUPID} = {?GroupID2Parameter}
or {DriverMotionView.GROUPID} = {?GroupID3Parameter}
or {DriverMotionView.GROUPID} = {?GroupID4Parameter}
or {DriverMotionView.GROUPID} = {?GroupID5Parameter}
or {DriverMotionView.GROUPID} = {?GroupID6Parameter}
or {DriverMotionView.GROUPID} = {?GroupID7Parameter}
or {DriverMotionView.GROUPID} = {?GroupID8Parameter}
or {DriverMotionView.GROUPID} = {?GroupID9Parameter}
or {DriverMotionView.GROUPID} = {?GroupID10Parameter}
)
与
其中,GroupIDArrayParameter声明为允许离散和多个值的数字参数。自定义值是允许的,但我认为这并不重要。关键是GroupIDArrayParameter(数字)的类型与DriverMotionView.GROUPID的类型匹配,后者也是一个数字
设置GroupIDArrayParameter的代码基本上如下所示:
Fields fields = new Fields ();
... //Set other parameters here
setDiscreteArrayParameter(fields, "GroupIDArrayParameter", "",
getIntGroupIDs(groups));
...
// Convert String groupIDs to Integers
private Integer[] getIntGroupIDs(String[] s) {
Integer[] result = new Integer[s.length];
for (int i = 0; i < s.length; i++) {
result[i] = Integer.parseInt(s[i]);
}
return result;
}
...
private void setDiscreteArrayParameter(Fields fields, String paramName,
String reportName, Object[] parameterValues) {
logger.debug("DescreteParameter - Name: " + paramName);
// Create parameter field
ParameterField parmeterField = new ParameterField();
// Set report name
parmeterField.setReportName(reportName);
// Set parameter name
parmeterField.setName(paramName);
// Create value
Values values = new Values();
for (int i = 0; i < parameterValues.length; i++) {
ParameterFieldDiscreteValue discreteValue = new ParameterFieldDiscreteValue();
discreteValue.setValue(parameterValues[i]);
values.add(discreteValue);
}
parmeterField.setCurrentValues(values);
fields.add(parmeterField);
}
Fields=新字段();
... //在此处设置其他参数
setDiscreteArrayParameter(字段,“GroupIDArrayParameter”,“”,
GetIntGroupId(组);
...
//将字符串GroupID转换为整数
私有整数[]GetIntGroupId(字符串[]s){
整数[]结果=新整数[s.length];
对于(int i=0;i
甚至可能有更干净的方法来做到这一点,但我只有这么多时间去调查
享受GroupIDListParameter}是用代码生成的,尽管我可以在预览报告时手动键入它。我知道它被传递到Crystal Reports中,因为我记录了生成的字符串,有时CR错误消息包含该字符串。此外,在子句中几乎任何函数的使用都会阻止该子句被传递到DB服务器。这大大增加了查询时间,从几秒增加到50秒以上,更不用说客户端过滤DB服务器返回的附加记录的时间了。我想我已经无意中发现了原始报告以t的方式编写的原因。我可能不得不做一些非常丑陋的事情,把离散参数的数量从10增加到100,这是我最初的方法。除非我遗漏了什么,否则通过JavaAPI传递的参数要么是离散的数量,比如布尔值、数字、字符串、货币以及日期/时间或其范围的变化。与正在使用的ParameterFieldDiscreteValue类不同,存在ParameterFieldRangeValue类,但范围不够通用。这就是为什么尝试使用字符串参数并使用上述建议的变体。我找不到这些API的JavaDocs或任何其他形式的文档,所以我很可能错过了一些东西。它只是证实了我的怀疑。显然没有办法通过JavaAPI将数组参数传递给报表。没有,但是可以使用可以分配给单个参数的值集合。据我所知,这基本上是一样的。如果在本例中打开.rpt,参数{?pfield1}被设置为允许多个值
,这就是您希望在这里使用的。这可能会起作用。我可以在报表设计器中生成正确的SQL。我只是想知道如何调整Java。敬请期待
Fields fields = new Fields ();
... //Set other parameters here
setDiscreteArrayParameter(fields, "GroupIDArrayParameter", "",
getIntGroupIDs(groups));
...
// Convert String groupIDs to Integers
private Integer[] getIntGroupIDs(String[] s) {
Integer[] result = new Integer[s.length];
for (int i = 0; i < s.length; i++) {
result[i] = Integer.parseInt(s[i]);
}
return result;
}
...
private void setDiscreteArrayParameter(Fields fields, String paramName,
String reportName, Object[] parameterValues) {
logger.debug("DescreteParameter - Name: " + paramName);
// Create parameter field
ParameterField parmeterField = new ParameterField();
// Set report name
parmeterField.setReportName(reportName);
// Set parameter name
parmeterField.setName(paramName);
// Create value
Values values = new Values();
for (int i = 0; i < parameterValues.length; i++) {
ParameterFieldDiscreteValue discreteValue = new ParameterFieldDiscreteValue();
discreteValue.setValue(parameterValues[i]);
values.add(discreteValue);
}
parmeterField.setCurrentValues(values);
fields.add(parmeterField);
}