问题由来:
公司换新系统,过渡期要和老系统共存,原报表使用odbc数据源,因只有一台服务器,所有新系统报表不能再使用odbc数据源了,(两个系统的报表不能使用同一服务器odbc数据源)
解决方案:方案一,修改新系统水晶报表的数据源,改为oledb方式。
方案二,修改水晶报表数据源为推模式,在程序中动态设置数据源。
部分报表使用了方案一,适用于数据量大,页数多的报表。(财务报表)
因为方案一需要修改每个报表的数据源,设置过于麻烦,而公司的报表文件过多,每个系统近百个报表。有5、6个系统,而且方案一太不灵活。所以针对数据量小的使用方案二。
经过几天查找资料测试,终于运行通过。
大概分两种方式:ReportDocument对象,Report数据源控件。
Report数据源控件适用于预览,ReportDocument对象更加灵活,但是为什么不能动态设置数据源?出现未将对象引用设置到对象的实例。
Report数据源控件CrystalReportSource1.ReportDocument作为参数发邮件等偶尔会出现莫名其妙错误。
以下:
ReportDocument rd = new ReportDocument()
case "Manifest":
//加载报表文件
rd.FileName = MapPath("Manifest_A4.rpt");
CrystalReportSource1.ReportDocument.Load(Server.MapPath("Manifest_A4.rpt"));
//第一步:设置数据源
DataSet ds = getrdDataMainfest(siteID, kid);
SetDataSource(ds, rd);
SetDataSource(ds, CrystalReportSource1.ReportDocument);
//第二步:设置参数,这个一定要在设置数据源后面,否则出现缺少参数值错误。
rd.SetParameterValue("show", isshow);
CrystalReportSource1.ReportDocument.SetParameterValue("show", isshow);
ReportName = "Manifest Manifest# " + li[0];
//第三部:选择公式
strRptDBkey = "{view_manifest_all.Manifest_Num}";
strRptDBSite = "{view_manifest_all.SiteID}";
rd.RecordSelectionFormula = sb.ToString();
CrystalReportSource1.ReportDocument.RecordSelectionFormula = sb.ToString();
//第四步:绑定控件
CrystalReportViewer1.ReportSource = CrystalReportSource1;
//CrystalReportViewer1.ReportSource = rd;//未将对象引用设置到对象的实例。
// CrystalReportViewer1.DataBind();
Me.ShowPDFReport(CrystalReportSource1.ReportDocument);
// Me.ShowPDFReport(rd);
public DataSet getrdDataMainfest(string siteID, string kid)
{
//sql语句见笑了
string strSQL = "SELECT * FROM ATP_MASTER.dbo.site where siteID=‘" + siteID + "‘; ";
strSQL += "SELECT * FROM view_mawb_hawb_coload_rpt where siteID=‘" + siteID + "‘ and Manifest_Num= ‘" + kid + "‘ ; ";
strSQL += " SELECT * FROM view_mawb_all where siteid= ‘" + siteID + "‘ and Manifest_Num=‘" + kid + "‘;";
strSQL += "SELECT * FROM view_mawb_hawb_rpt where siteid= ‘" + siteID + "‘ and Manifest_Num=‘" + kid + "‘; ";
strSQL += "SELECT * FROM MAWB_LOADING_INFO where siteid= ‘" + siteID + "‘ and Manifest_Num=‘" + kid + "‘; ";
Response.Write(strSQL);
string connStr = Logistic.Common.Common.GetAeConnectionString();
DataSet ds = Logistic.SqlConn.SqlHelper.ExecuteDataset(connStr, CommandType.Text, strSQL);
ds.Tables[0].TableName = "SITE";
ds.Tables[1].TableName = "view_man_coload_rpt";
ds.Tables[2].TableName = "view_manifest_all";
ds.Tables[3].TableName = "view_manifest_hawb";
ds.Tables[4].TableName = "manifesT_LOADING_INFO";
//一定要设置table名字
return ds;
}
//对主报表和子报表追加数据源。
public void SetDataSource(DataSet ds, ReportDocument rd)
{
foreach (CrystalDecisions.CrystalReports.Engine.Table tbl in rd.Database.Tables)
{
tbl.SetDataSource(ds.Tables[tbl.Name]);
}
foreach (ReportDocument subRd in rd.Subreports)
{
foreach (CrystalDecisions.CrystalReports.Engine.Table tbl in subRd.Database.Tables)
{
tbl.SetDataSource(ds.Tables[tbl.Name]);
}
}
}
补充,对于子报表参数添加,后面会用到时再来更新。