0

我正在编写一个应用程序来更改报表文件中的Crystal Reports数据库访问参数。我在.NET Windows 窗体应用程序中打开报告并应用 SDK 功能来更改驱动程序类型 (ODBC/OLEDB)、服务器名称、数据库名称、用户、密码、身份验证类型等。我遇到了数据库名称问题。我的代码确实更改了表 ConnectionInfo 的特定属性(也在子报表中),但未能更新报表中的一般 SQL 查询。这会导致报表仍在访问旧数据库。

因此,如果原始报表被配置为访问 database_1 并且我将其更改为 database_2,它将所有表属性正确更改为 database_2(可在设计器中验证)。尽管如此,它仍然会在查询中包含 database_1 。SDK RowsetController.GetSQLStatement() 结果和 Crystal Reports Developer 查询视图(Database->Show SQL Query...)中的数据库名称保持不变。

此外,在进行转换时,我必须让两个数据库(database_1 和 database_2)都在线,否则我会在 GetSQLStatement(当 database_1 脱机时;因为它仍然引用它)或 SetTableLocation(当 database_2 脱机时——这是预期的)出现异常和可接受的行为)。如果两个数据库都在线,则没有错误。

这正是我正在使用的:

1) CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(filePath, OpenReportMethod.OpenReportByTempCopy) (...)

2) 制作并填写 CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag

3) 遍历 CrystalDecisions.ReportAppServer.DataDefModel.Tables 并使用 SetTableLocaiton() 为每个属性应用所有属性。

4) 对每个子报表重复

5) RowsetController.GetSQLStatement() 查看报表的sql查询。

有没有办法根据新表 ConnectionInfos (似乎设置正确)更新查询?我什至看不到手动更新查询(GET、搜索和替换、SET)的任何可能性。

我正在使用:

.NET 4.5、Visual Studio 2012、CR for VS 13.0.5、Crystal Reports Developer 9.2.2.693 用于结果验证(源报表也是用它创建的)

4

1 回答 1

1

答:为每个表设置propper QualifiedName。QualifiedName 是表的全名,包括 DbName。这稍后会出现在报告的 SQL 查询中。通过限定名称,我们理解:

myDatabase.mySchema.myTableName

代码示例:

CrystalDecisions.ReportAppServer.DataDefModel.Table boTable = new CrystalDecisions.ReportAppServer.DataDefModel.Table();
CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag boMainPropertyBag = new CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag();
CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag boInnerPropertyBag = new CrystalDecisions.ReportAppServer.DataDefModel.PropertyBag();

// Custom function to fill property bags with values which influence the table properties as seen in CR Developer
FillPropertyBags(boMainPropertyBag, boInnerPropertyBag);

CrystalDecisions.ReportAppServer.DataDefModel.ConnectionInfo boConnectionInfo = new CrystalDecisions.ReportAppServer.DataDefModel.ConnectionInfo();
boConnectionInfo.Attributes = boMainPropertyBag;
boConnectionInfo.Kind = CrystalDecisions.ReportAppServer.DataDefModel.CrConnectionInfoKindEnum.crConnectionInfoKindCRQE;

boTable.ConnectionInfo = boConnectionInfo;

CrystalDecisions.ReportAppServer.DataDefModel.Tables boTables = boReportDocument.ReportClientDocument.DatabaseController.Database.Tables;

for (int i = 0; i < boTables.Count; i++)
{
   boTable.Name = boTables[i].Name;
   // the QualifiedName is directly taken into the CR general query so this is a quick fix to change it
   boTable.QualifiedName = boTables[i].QualifiedName.Replace("oldDbName", "newDbName"); 
   boTable.Alias = boTables[i].Alias;
   boReportDocument.ReportClientDocument.DatabaseController.SetTableLocation(boTables[i], boTable);
}

呃……研究了一整天,在 SO 上发布问题后找到了答案。

于 2013-09-26T07:48:26.657 回答