点击此处---> 群内免费提供SAP练习系统(在群公告中)加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)我一直在努力找出与各种Cryst...
点击此处---> 群内免费提供SAP练习系统(在群公告中)加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)我一直在努力找出与各种Cryst...
加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)
我一直在努力找出与各种Crystal Reports Java API所出现的不一致之处,并且在线帮助在寻找明确的解决方案方面相当模糊或不确定。 所以我想在这里问
请原谅,但要有一些背景知识……
我们的BOE 4.1 FP11服务器管理着约1500个左右的Crystal Reports,这些服务器针对我们的数据仓库。 由于正在进行仓库迁移到另一个供应商的平台,我们需要使用新的DSN更新这些报告,并且一部分报告将需要对其CommandTable对象进行一些SQL调整。 我正在尝试使用您的Java SDK之一来自动执行此过程。 请记住,无论如何我都不是BOE或Crystal用户或专家,我只是一个在使用SDK和API进行集成/自动化方面具有丰富经验的编码人员。
仓库供应商正在协助我们进行此迁移,他们要求从受影响的报告中转储所有自定义SQL(CommandTable.CommandText),以便他们可以对其进行检查并进行任何必需的更改。 我能够使用Crystal Reports for Eclipse(CR4E)API并直接在BOE文件系统上的.RPT文件之后轻松提供此功能。 即使这些是托管报告,也可以直接查询RPT文件。 我能够遍历文件系统以收集所有RPT文件,识别受影响的文件,并将包括CommandTable自定义SQL在内的报告元数据转储到提供给供应商的文本文件中。 到目前为止很好...
然后,供应商获取了此文本转储,并对其运行了工具以验证SQL并进行任何必需的更新。 他们向我们返回了更新的文件,现在我应该阅读这些文件,然后为这些报告更新DSN和修改后的SQL(CommantTable.CommandText)。
所以现在我们可以解决当前的困境:
我意识到CR4E SDK不适用于托管报告,但是我认为我已经抓取了其中一些托管RPT并将其作为本地副本删除,只是为了尝试使用更新代码,然后再尝试远程访问它们 通过托管的API。 我编写了一些非常简单的代码来计算更新动态,并且代码运行无误。 但是,当我调用ReportClientDocument.save()和.close()时,实际上没有任何更改被写回到文件中。 文件时间戳确实发生更改,表明文件已更新,但是文件大小相同,表明内容未更改。 我还尝试了使用不同文件名的ReportClientDocument.saveAs()-也写入了新文件,但再次与原始文件相同。
在逐步调试时,我可以在内存的CommandTable.CommandText字段中看到SQL更改,因此我知道CommandTable.setCommandText()调用正在工作。 但是为什么它从不进入目标文件?该文件不是只读的,因为我检查ReportClientDocument.isReadOnly()会返回false。 再一次,saveAs()写入一个文件,但包含原始内容。
是因为CR4E SDK知道这实际上是一个托管报告并且拒绝更改它吗? 如果是这样,为什么不抛出异常而不是默默地失败并暗示成功?我希望保持这种过程既快速,简单又可行,因此首先尝试使用与我相同的CR4E API。 我还提供了RAS SDK和BIP41 SDK,可以尝试通过托管API,大约一半的人希望我必须这样做以确保正确更新元数据数据库。 但是在我再次追尾之前,我有什么想念的地方吗?
下面的代码片段显示了一个非常快速且肮脏的示例,该示例使用具有3个CommandTable对象的本地硬编码报告文件,并且我尝试将第一个CommandTable.CommandText更改为虚拟SQL字符串。
File rptFile = new File(" test/update_test1.rpt"); ReportClientDocument clientDoc = ReportClientDocument.openReport(rptFile); 如果(clientDoc.isReadOnly()) 抛出新的异常("报告是只读的!"); IDatabase数据库= clientDoc.getDatabaseController()。getDatabase(); 字符串cmdName = null; CommandTable cmdTable = null; 对于(ITable t:database.getTables()) { if(t instanceof CommandTable) { cmdTable =(CommandTable)t; cmdName = cmdTable.getAlias(); cmdTable.setCommandText(" SELECT * FROM TEST_CRYSTAL_UPDATE;"); 打破; } } clientDoc.save(); System.out.println("更改了命令'"的SQL'+报告中的cmdName +"'+ clientDoc.displayName()+"')); clientDoc.close();
上面的代码中没有显示它,但是周围有一个try/catch块可以捕获所有异常。 不会抛出任何异常,并且文件时间戳会再次更新,就像写了 something 。 这是调试器的前后截图,显示.setCommandText()调用实际上更改了CommandTable对象中的SQL。
之前:
之后:
感谢您提供的任何帮助。 我想接下来我将开始深入研究RAS API ...
(10.0 kB)
嗨,大卫,
首先要做的是首先在报告中进行所有这些操作。 打开设计器,打开您的报告之一,单击"数据库"菜单选项,然后单击"设置位置.....
选择客户端,填写登录信息,建立连接后,单击新数据源,然后单击旧数据源,然后单击"地图"按钮。 如果检测到任何字段类型映射问题,则会弹出一个Mapping UI,您需要单独映射该字段。
如果有子报表,请为列出的每个数据源设置位置。
现在单击"数据库...",然后单击"验证",这将使用选定的新表信息更新报告中的表信息。
现在在SDK中使用相同的工作流程。 在这种情况下,您将需要使用ReplaceConnection(OldConn,NewConn,DoNotVerify),以便即使使用Command,数据库信息也会得到相应更新。
这两个调用都是全局设置,因此它会验证集合中的每个表,因此您不必在循环中调用它来设置位置,一旦该循环完成,则仅进行一次调用,需要设置子报表连接 进行设置,然后拨打这些电话。
您实际上需要连接到数据库,您不能简单地调用它们并期望连接可以工作或验证表信息。
工作流程为:
打开报告
从Command对象获取SQL
更改SQL并将其设置为主报表和子报表
现在设置用于登录的连接属性。
如果reprot正在使用存储过程,则在登录之前首先设置SP的参数。
如果没有,则设置任何需要更改或未保存默认值的CR参数值
现在登录到数据库
在此处检查连接性,它实际上并不检查报告数据信息,只是测试连接信息是否有效。
根据需要设置参数默认值。
现在SetLocation()
现在验证数据库。
现在您可以保存报表,如果使用RAS更新任何部分,则在保存时需要使用ReportClientDocument对象。 它具有更新的信息。 ClientDocument可能无法保存某些基本属性,但是要更改数据库源,您需要使用RCD对象。
请注意,您使用的是Java还是.NET?
我没有任何示例,但是您可以在此处找到一些示例:
https://wiki.scn.sap.com/wiki/display/BOBJ/Java+%28Crystal+Reports+for+Eclipse%29+SDK
还有更多内容:
https://wiki.scn.sap.com/wiki/ display/BOBJ/Java + SDK
在.NET示例中,我编写了2个测试应用程序,其中一个用于参数/登录,另一个用于打印:
https: //wiki.scn.sap.com/wiki/display/BOBJ/Crystal+Reports%2C+Developer+for+Visual+Studio+Downloads
唐
一周热门 更多>