如何动态和正确地更改Crystal Reports文件的命令表中的查询?

时间:2017-06-02 22:30:24

标签: crystal-reports

我有很多rpt文件。我想使用C#更改每个报告的查询。有几种方法可以进行此更改。

第一种方式:

private void button_Test_Click(object sender, EventArgs e)
{
    ReportDocument rptDoc = new ReportDocument();
    rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
    rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
    CrystalDecisions.Shared.ConnectionInfo ConnInf;
    ConnInf = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo;
    String strSQLQuery = "SELECT TOP(123) * FROM sys.all_objects";
    String strTableName = rptDoc.Database.Tables[0].Name;
    try
    {
        rptDoc.SetSQLCommandTable(ConnInf, strTableName, strSQLQuery);
        rptDoc.VerifyDatabase();
    }
    catch (Exception ex) { rptDoc.Close(); }
    rptDoc.SaveAs("D:\\Temp_02\\Report2_Test.rpt");
    rptDoc.Close();
}

这不是最好的方式。当查询具有任何参数时,方法SetSQLCommand不起作用。即使您为每个参数设置了值,SetSQLCommand也不起作用。参数不起作用的示例:

private void button_Test_Click(object sender, EventArgs e)
{
    ReportDocument rptDoc = new ReportDocument();
    rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
    rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
    CrystalDecisions.Shared.ConnectionInfo ConnInf;
    ConnInf = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo;
    String strSQLQuery = "SELECT TOP(1) * FROM sys.all_objects WHERE name = {?strName}";
    String strTableName = rptDoc.Database.Tables[0].Name;
    try
    {
        rptDoc.SetParameterValue("strName", "Text");
        rptDoc.SetSQLCommandTable(ConnInf, strTableName, strSQLQuery);
        rptDoc.VerifyDatabase();
    }
    catch (Exception ex) { rptDoc.Close(); }
    rptDoc.SaveAs("D:\\Temp_02\\Report2_Test.rpt");
    rptDoc.Close();
}

它返回错误。此方法不适用于参数!

第二种方式:

private void button_Test_Click(object sender, EventArgs e)
{
    ReportDocument rptDoc = new ReportDocument();
    rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
    rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
    ISCDReportClientDocument rcd = null;
    rcd = rptDoc.ReportClientDocument as ISCDReportClientDocument;
    CommandTable rTblOld;
    CommandTable rTblNew;
    rTblOld = rcd.Database.Tables[0] as CommandTable;
    rTblNew = rcd.Database.Tables[0].Clone(true) as CommandTable;
    rTblNew.CommandText = "SELECT TOP(1) * FROM sys.all_objects";
    try
    {
        rcd.DatabaseController.SetTableLocationEx(rTblOld, rTblNew);
        rcd.VerifyDatabase();
    }
    catch (Exception ex) { rcd.Close(); }
    rcd.SaveAs(rcd.DisplayName, "D:\\Temp_02\\", 1);
    rcd.Close();
}

这也不是最好的方法。方法SetLocalTableEx做报告的结构是坏的。运行SetLocalTableEx后,属性ConnectionInf.UserId的值为NULL也是连接名称

在SetTableLocationEx之后:

rcd.DatabaseController.SetTableLocationEx(rTblOld, rTblNew);
String UserID;
UserID = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo.UserID;
if (UserID == null) MessageBox.Show("UserID has NULL");

UserId的值为NULL

此外,在运行SetTableLocationEx之前,连接名称为MSODBCSQL11 enter image description here

运行SetTableLocationEx后,连接名称为Command enter image description here

所以, 如何在CommandTable中为Crystal Reports文件动态更正地更改查询?

谢谢, 阿尔乔姆

1 个答案:

答案 0 :(得分:0)

您正在使用Crystal Report中的命令,这是执行和显示databasecrystal report的数据的最佳方式,但遗憾的是您在代码隐藏中执行此操作。

我的问题是:

  

为什么不在Crystal Report命令中执行此操作?

请参阅此link了解详情。