Visual Studio 2019下Crystal Report SP26 SetDataSource()客户端执行失败求助
我正在使用Visual Studio 2019和Crystal Report Service Pack 26,通过以下VB.NET代码将ADO.NET DataSet设置为报表数据源:
Dim ds1 As New DataSet1() Dim myRep As New CrystalReport1 taAccArticleFields_TBL.Fill(ds1.AccArticleFields_TBL) myRep.SetDataSource(ds1) crvReport.ReportSource = myRep
在Visual Studio中运行完全正常,报表能正常显示;但在仅安装CR26运行时的客户端电脑上,调用SetDataSource方法时抛出如下错误:
System.Runtime.InteropServices.COMException (0x800002CD): Error in File temp_04020c6d-5b84-40d9-8558-bf87b6d5e554 4840_5464_{1C1D3ACF-9F25-45E2-B0EE-BB77F1DDA6B6}.rpt: Failed to load database information.
at CrystalDecisions.ReportAppServer.Controllers.DatabaseControllerClass.ReplaceConnection(Object oldConnection, Object newConnection, Object parameterFields, Object crDBOptionUseDefault)
at CrystalDecisions.CrystalReports.Engine.Table.SetDataSource(Object val, Type type)
at CrystalDecisions.CrystalReports.Engine.ReportDocument.SetDataSourceInternal(Object val, Type type)
所有编写的程序都出现这个问题,求解决方案。
我之前也碰到过几乎一模一样的问题,结合自己的排查经验和社区总结的方案,给你几个优先级从高到低的解决方向:
严格匹配CR运行时版本
这是最常见的原因!客户端安装的必须是Crystal Report Service Pack 26的对应版本,而且要注意x86/x64架构必须和你的程序一致——比如你程序是x86编译的,就不能装x64的CR26运行时。CR的不同SP版本兼容性很差,差一个版本都可能触发数据库加载失败的错误。验证DataSet与报表的表结构完全一致
有时候开发过程中DataSet的字段修改了,但报表里的数据源没同步更新,或者部署时DataSet的序列化文件(xsd)没跟上。你可以:- 在VS里打开
CrystalReport1,右键点击“数据库字段”→“设置数据源位置”,确认报表绑定的是DataSet1.AccArticleFields_TBL,且所有字段名、数据类型、长度和DataSet里的完全匹配,没有多余或缺失的字段。 - 部署前重新生成整个解决方案,确保DataSet的dll是最新版本,并且一起部署到客户端。
- 在VS里打开
手动遍历报表表绑定数据源(替代直接SetDataSource)
偶尔直接调用SetDataSource(ds1)会在COM层面出现连接替换的问题,你可以尝试手动遍历报表里的表,逐个绑定DataSet的表:Dim ds1 As New DataSet1() Dim myRep As New CrystalReport1 taAccArticleFields_TBL.Fill(ds1.AccArticleFields_TBL) ' 逐个处理报表中的表 For Each tbl As CrystalDecisions.CrystalReports.Engine.Table In myRep.Database.Tables Dim logOnInfo As CrystalDecisions.Shared.TableLogOnInfo = tbl.LogOnInfo ' DataSet数据源不需要服务器、用户名密码,留空即可 logOnInfo.ConnectionInfo.ServerName = "" logOnInfo.ConnectionInfo.DatabaseName = ds1.DataSetName logOnInfo.ConnectionInfo.UserID = "" logOnInfo.ConnectionInfo.Password = "" tbl.ApplyLogOnInfo(logOnInfo) ' 手动绑定对应的DataSet表 tbl.SetDataSource(ds1.Tables("AccArticleFields_TBL")) Next crvReport.ReportSource = myRep检查客户端临时目录权限
Crystal Reports会在用户临时目录生成缓存的报表文件(就是错误里的temp_xxxx.rpt),如果运行程序的用户没有这个目录的读写权限,就会加载失败。你可以:- 找到临时目录:一般是
C:\Users\[当前用户名]\AppData\Local\Temp或者系统的%TEMP%目录。 - 给运行程序的用户分配该目录的读写权限,如果是多人使用的电脑,可以考虑给Users组添加权限。
- 找到临时目录:一般是
确认部署时包含所有CR依赖文件
如果是手动部署程序,容易漏掉CR的附属组件。你可以打开VS输出目录(一般是bin\Debug或bin\Release),把所有以crystalreports13_0_26开头的dll和相关配置文件,还有DataSet的xsd文件,一起复制到客户端的程序目录下。如果用ClickOnce部署,要确保在项目属性里把CR的组件标记为“包含”。
内容的提问来源于stack exchange,提问作者Sajjad Pirahesh

