You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SAP Crystal Report生产环境子报表Symptom/s无数据如何解决

水晶报表生产环境Symptom/s子报表无数据解决方案

问题描述

现有包含5个子报表的主报表,开发环境预览所有子报表数据正常,生产环境仅Symptom/s子报表无数据输出。
开发环境效果:
开发环境预览
生产环境效果:
生产环境预览
原报表加载代码:

private void loadReport(Int64 appointmentID)
{
    try
    {
        rd = new ReportDocument();
        //加载主报表患者数据
        SqlCommand cmd1 = new SqlCommand("st_getPatientBill", MainClass.con);
        cmd1.CommandType = CommandType.StoredProcedure;
        cmd1.Parameters.AddWithValue("@appID", appointmentID);
        SqlDataAdapter da1 = new SqlDataAdapter(cmd1);
        DataTable dt1 = new DataTable();
        da1.Fill(dt1);
        rd.Load(Application.StartupPath + "\\Reports\\PrescriptionReport.rpt");
        rd.SetDataSource(dt1);

        ConnectionInfo ci = new ConnectionInfo();
        ci.DatabaseName = "cms";
        ci.UserID = "sa";
        ci.Password = "12345";
        ci.ServerName = "DESKTOP-753VMJS";
        Tables tables = rd.Database.Tables;
      
        //加载内部用药数据
        SqlCommand cmd4 = new SqlCommand("st_getInternalMedicine", MainClass.con);
        cmd4.CommandType = CommandType.StoredProcedure;
        cmd4.Parameters.AddWithValue("@appID", appointmentID);
        SqlDataAdapter da4 = new SqlDataAdapter(cmd4);
        DataTable dt4 = new DataTable();
        da4.Fill(dt4);
        rd.Subreports[0].SetDataSource(dt4);

        //加载外部用药数据
        SqlCommand cmd3 = new SqlCommand("st_getExternalMedicine", MainClass.con);
        cmd3.CommandType = CommandType.StoredProcedure;
        cmd3.Parameters.AddWithValue("@appID", appointmentID);
        SqlDataAdapter da3 = new SqlDataAdapter(cmd3);
        DataTable dt3 = new DataTable();
        da3.Fill(dt3);
        rd.Subreports[0].SetDataSource(dt3);

        //加载疾病数据
        SqlCommand cmd5 = new SqlCommand("st_getPatientDiseaseWRTAppointment", MainClass.con);
        cmd5.CommandType = CommandType.StoredProcedure;
        cmd5.Parameters.AddWithValue("@appID", appointmentID);
        SqlDataAdapter da5 = new SqlDataAdapter(cmd5);
        DataTable dt5 = new DataTable();
        da5.Fill(dt5);
        rd.Subreports[0].SetDataSource(dt5);

        //加载症状数据
        SqlCommand cmd6 = new SqlCommand("st_getPatientSymptomsWRTAppointment", MainClass.con);
        cmd6.CommandType = CommandType.StoredProcedure;
        cmd6.Parameters.AddWithValue("@appID", appointmentID);
        SqlDataAdapter da6 = new SqlDataAdapter(cmd6);
        DataTable dt6 = new DataTable();
        da6.Fill(dt6);
        rd.Subreports[0].SetDataSource(dt6);

        //加载检验数据
        SqlCommand cmd7 = new SqlCommand("st_getPatientTestWRTAppointment", MainClass.con);
        cmd7.CommandType = CommandType.StoredProcedure;
        cmd7.Parameters.AddWithValue("@appID", appointmentID);
        SqlDataAdapter da7 = new SqlDataAdapter(cmd7);
        DataTable dt7 = new DataTable();
        da7.Fill(dt7);
        rd.Subreports[0].SetDataSource(dt7);

        //配置主报表数据库登录信息
        foreach (CrystalDecisions.CrystalReports.Engine.Table table in tables)
        {
            TableLogOnInfo tableLogonInfo = table.LogOnInfo;
            tableLogonInfo.ConnectionInfo = ci;
            table.ApplyLogOnInfo(tableLogonInfo);
        }
        crystalReportViewer1.ReportSource = rd;
        crystalReportViewer1.RefreshReport();

    }
    catch (Exception ex)
    {
        if (rd != null)
        {
            rd.Close();
        }
    }
}

核心问题

  1. 所有子报表的数据源都绑定到了Subreports[0],后赋值的数据源会覆盖之前的内容,最终只有最后一个绑定的检验子报表拿到了代码赋值的数据源,其余子报表相当于没有通过代码绑定数据。开发环境能正常显示是因为硬编码的数据库连接和本地环境匹配,子报表通过内置连接逻辑自动拉取了数据,生产环境服务器名、账号密码和开发环境不一致,子报表无法自主连库拉数,只能用代码绑定的数据源,所以症状子报表无数据。
  2. 仅配置了主报表的数据库登录信息,没有给子报表配置登录信息,生产环境子报表无法自主连接数据库。
  3. 数据库连接信息硬编码,无法适配生产环境的数据库配置。

修复步骤

  1. 打开主报表文件PrescriptionReport.rpt,确认5个子报表的排列顺序,记录每个子报表对应的索引(从0开始计数),常规顺序参考:内部用药对应0、外部用药对应1、疾病对应2、症状对应3、检验对应4。
  2. 修改每个子报表的数据源绑定逻辑,替换为对应索引:
// 内部用药
rd.Subreports[0].SetDataSource(dt4);
// 外部用药
rd.Subreports[1].SetDataSource(dt3);
// 疾病
rd.Subreports[2].SetDataSource(dt5);
// 症状
rd.Subreports[3].SetDataSource(dt6);
// 检验
rd.Subreports[4].SetDataSource(dt7);
  1. 新增子报表数据库登录配置,在主报表表遍历逻辑后添加如下代码:
// 配置所有子报表的数据库登录信息
foreach (ReportDocument subReport in rd.Subreports)
{
    foreach (CrystalDecisions.CrystalReports.Engine.Table table in subReport.Database.Tables)
    {
        TableLogOnInfo tableLogonInfo = table.LogOnInfo;
        tableLogonInfo.ConnectionInfo = ci;
        table.ApplyLogOnInfo(tableLogonInfo);
    }
}
  1. 将硬编码的数据库连接信息改为从配置文件读取,适配开发、生产不同环境的数据库配置。

验证方法

先在代码中给dt6加断点,确认dt6是否有数据:如果dt6有数据,修复绑定索引即可;如果dt6无数据,检查生产环境中存储过程st_getPatientSymptomsWRTAppointment的执行权限、入参是否正常。

内容的提问来源于stack exchange,提问作者Ali Raza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 02:54:10