Crystal Reports调用Refresh方法时报数据库信息加载失败问题
Crystal Reports刷新后打印报"Failed to load database information"解决方法
问题复现
业务代码
Dim logoninfo As TableLogOnInfo Dim SaleInvPrint As New ReportDocument SaleInvPrint.Load(My.Settings.CrystalReportLocation & "\SalesInvoiceA5.rpt") For Each tbcurrent As CrystalDecisions.CrystalReports.Engine.Table In SaleInvPrint.Database.Tables logoninfo = tbcurrent.LogOnInfo() logoninfo.ConnectionInfo.DatabaseName = LocalDataAccessCon.ConnectionString ' logoninfo.ConnectionInfo.ServerName = "[server]" ' logoninfo.ConnectionInfo.UserID = "[user]" ' logoninfo.ConnectionInfo.Password = "[password]" tbcurrent.ApplyLogOnInfo(logoninfo) Next SaleInvPrint.Refresh() SaleInvPrint.PrintToPrinter(1, True, 0, 50)
异常信息
执行到PrintToPrinter语句时抛出以下异常:
CrystalDecisions.CrystalReports.Engine.DataSourceException: 'Error in File SalesInvoiceA5 13744_2344_{741BCC9A-4E81-4C98-8E3C-B5ECC6DAA5FA}.rpt: Failed to load database information.'
COMException: Error in File SalesInvoiceA5 13744_2344_{741BCC9A-4E81-4C98-8E3C-B5ECC6DAA5FA}.rpt: Failed to load database information.
特殊现象:删除SaleInvPrint.Refresh()语句后异常不再触发,但打印内容是报表文件内存储的历史缓存数据,无法读取数据库最新记录。
根因分析
报错本质是Refresh()触发报表重载数据源时,无法识别有效的数据库连接配置,常见触发点:
- 连接属性赋值错误:代码将完整数据库连接字符串直接赋值给
ConnectionInfo.DatabaseName属性,该属性仅接收数据库名称字段,不支持传入完整连接串,引擎解析连接参数时直接失败,这是当前代码最核心的问题。 - 未覆盖全量数据源:现有循环仅遍历主报表的普通表对象,如果报表包含子报表、自定义SQL命令、存储过程,这类对象的连接信息仍保留设计时的旧配置,刷新时无法正常连接数据库。
- 运行时位数不匹配:如果项目编译目标平台(x86/x64)和本地安装的Crystal Reports运行时位数不一致,刷新时加载对应数据库驱动会失败,抛出这个通用错误。
修复方案
按以下步骤逐一调整即可解决:
- 修正连接属性赋值逻辑:不要将完整连接串传给
DatabaseName,根据实际数据库类型分别配置ServerName、DatabaseName、UserID、Password、IntegratedSecurity属性。如果是Access、SQLite等文件型数据库,ServerName填写数据库文件的完整物理路径即可。 - 补充子报表连接配置逻辑:遍历所有子报表包含的表对象,和主报表一样逐一应用登录信息。
- 校验运行时匹配性:将项目目标平台固定为x86或x64,和已安装的Crystal Reports运行时位数保持一致,不要使用AnyCPU编译避免加载错位数的组件。
- 刷新前禁用报表自带缓存:关闭报表“随报表保存数据”的选项,避免旧缓存干扰数据加载。
- 如果报表包含参数,先给参数集合赋值再调用
Refresh(),避免引擎弹参数框中断流程。
修复后参考代码
Dim logoninfo As TableLogOnInfo Dim SaleInvPrint As New ReportDocument ' 禁用报表内置数据缓存,强制每次从数据源拉取最新数据 SaleInvPrint.ReportOptions.EnableSaveDataWithReport = False SaleInvPrint.Load(My.Settings.CrystalReportLocation & "\SalesInvoiceA5.rpt") ' 配置主报表所有表的连接信息 For Each tbcurrent As CrystalDecisions.CrystalReports.Engine.Table In SaleInvPrint.Database.Tables logoninfo = tbcurrent.LogOnInfo() With logoninfo.ConnectionInfo ' 按实际环境替换以下参数 .ServerName = "你的数据库服务地址" .DatabaseName = "你的数据库名称" .UserID = "数据库登录账号" .Password = "数据库登录密码" ' 采用Windows集成认证时打开以下配置,注释掉上面的UserID和Password ' .IntegratedSecurity = True End With tbcurrent.ApplyLogOnInfo(logoninfo) Next ' 配置所有子报表的连接信息 For Each subReport As ReportDocument In SaleInvPrint.Subreports For Each tbcurrent As CrystalDecisions.CrystalReports.Engine.Table In subReport.Database.Tables logoninfo = tbcurrent.LogOnInfo() With logoninfo.ConnectionInfo .ServerName = "你的数据库服务地址" .DatabaseName = "你的数据库名称" .UserID = "数据库登录账号" .Password = "数据库登录密码" End With tbcurrent.ApplyLogOnInfo(logoninfo) Next Next ' 若有报表参数,在此处给SaleInvPrint.ParameterFieldValues赋值后再刷新 SaleInvPrint.Refresh() SaleInvPrint.PrintToPrinter(1, True, 0, 50)
内容的提问来源于stack exchange,提问作者Khalid Kagzi
相关产品推荐
相关产品推荐

