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}

我有一个Java应用程序,它通过Java库调用Crystal Reports。其中一个报告的记录选择器中包含以下子句:

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);
}