13

目前我已经厌倦了尝试在 Crystal Reports 中解决这个问题。我们有 3 个环境,开发、生产(共享)和本地计算机中的部署。如果我与开发中的生产环境不完全匹配,Crystal Reports 永远不会显示报告。我通过所有论坛进行了大量研究,并尝试了每一个解决方案。我尝试什么都没关系,当我尝试应用新的登录信息时它永远不会起作用,当我循环表以测试连接时它最终会失败:

foreach (CrystalDecisions.CrystalReports.Engine.Table table in document.Database.Tables)
{
    TableLogOnInfo tableLogOnInfo = table.LogOnInfo;

    tableLogOnInfo.ConnectionInfo = info.ConnectionInfo;
    table.ApplyLogOnInfo(tableLogOnInfo);
    if (!table.TestConnectivity())
    {
        string msg = ("Failed to apply log in info for Crystal Report");
        throw new ApplicationException(msg);
    }
}

如果我将用户或密码更改为无效用户或密码,则之前在 SetConnection 或 SetDatabaseLogon 中会失败。我知道存在无法从集成安全性更改为非集成安全性的错误,因此我将自己的数据库设置为使用常规用户和密码凭据。

我可以清楚地看到未设置连接,因为在我的开发计算机中我设置了无效密码,它失败了,但如果我继续,我会看到报告。在生产计算机中,它总是失败并且也不显示报告(出于调试目的跳过错误)。所以似乎连接是硬编码的,无法更改。

有任何想法吗?我可以发布所有代码来更改连接信息,但我认为这不值得,这是众所周知的。

解决方案

就像许多人告诉我的那样,没有单一的解决方案。似乎取决于 Crystal Reports 版本,它的工作方式有所不同。在我的情况下,以下解决方案适用于 Crystal Reports 10.5.3700。

public static void CrystalReportLogOn(ReportDocument reportParameters, string serverName, string databaseName, string userName, string password)
{
    TableLogOnInfo logOnInfo;
    ReportDocument subRd;
    Sections sects;
    ReportObjects ros;
    SubreportObject sro;

    if (reportParameters == null)
    {
        throw new ArgumentNullException("reportParameters");
    }

    try
    {
        foreach (CrystalDecisions.CrystalReports.Engine.Table t in reportParameters.Database.Tables)
        {
            logOnInfo = t.LogOnInfo;
            logOnInfo.ReportName = reportParameters.Name;
            logOnInfo.ConnectionInfo.ServerName = serverName;
            logOnInfo.ConnectionInfo.DatabaseName = databaseName;
            logOnInfo.ConnectionInfo.UserID = userName;
            logOnInfo.ConnectionInfo.Password = password;
            logOnInfo.TableName = t.Name;
            t.ApplyLogOnInfo(logOnInfo);
            t.Location = t.Name;
        }
    }
    catch
    {
        throw;
    }

    sects = reportParameters.ReportDefinition.Sections;
    foreach (Section sect in sects)
    {
        ros = sect.ReportObjects;
        foreach (ReportObject ro in ros)
        {
            if (ro.Kind == ReportObjectKind.SubreportObject)
            {
                sro = (SubreportObject)ro;
                subRd = sro.OpenSubreport(sro.SubreportName);
                try
                {
                    foreach (CrystalDecisions.CrystalReports.Engine.Table t in subRd.Database.Tables)
                    {
                        logOnInfo = t.LogOnInfo;
                        logOnInfo.ReportName = reportParameters.Name;
                        logOnInfo.ConnectionInfo.ServerName = serverName;
                        logOnInfo.ConnectionInfo.DatabaseName = databaseName;
                        logOnInfo.ConnectionInfo.UserID = userName;
                        logOnInfo.ConnectionInfo.Password = password;
                        logOnInfo.TableName = t.Name;
                        t.ApplyLogOnInfo(logOnInfo);
                    }
                }
                catch
                {
                    throw;
                }
            }
        }
    }
}

我尝试过的所有其他解决方案都不起作用。

4

1 回答 1

3

我有类似的问题。您使用的是哪个版本的 Crystal 报表很重要。对于某些版本,如果您在 ApplyLogOnInfo 之外设置表格位置,则报告将起作用。

您是否尝试在运行时设置报告连接,或者您也有针对不同环境的单独报告?我们发现创建不同的报表环境更容易(但我们只有 2 个:开发和生产)。这允许我们设置一次连接信息——当我们将报告从开发转移到生产时。我们很少有内部开发的工具来处理不同的报告版本。现在我们正在使用这个第 3 方工具:http ://www.r-tag.com/Pages/CRDataSource.aspx它似乎可以正确处理所有版本,但每个报告仅适用于一个连接。

于 2013-09-12T23:50:43.543 回答