之前有人问到怎么在代码中动态添加子报表,或者其他对象。我的答复一般是这个是做不到的,但是可以通过预置对象的显示与隐藏来模拟此效果。
这是因为现在大多数朋友用的都是微软VS200X自带的水晶报表,这个版本是个简化版本,所以有很多东西是实现不了的。
前几天有人问到了 BO XI 的问题,我也很高兴终于能在这个层面上做一些讨论。后面如果有必要,我会写一些BOE SDK层面的编程。
这个前提是,开发机器上需要安装了BO或CrystalReports Server(或其客户端、 SDK)
然后我们就可以使用RAS SDK在动态添加对象了。
当然也可以使用水晶报表开发版的RDC来实现这个功能,但是代码上还是有不少差别的。
关于RAS我在这里做过一些说明
http://www.cnblogs.com/babyt/archive/2008/05/17/1201418.html
也可参考MSDN
http://msdn.microsoft.com/zh-cn/library/ms225325(VS.80).aspx
本文的代码用以演示一个简单的子报表动态添加。
新建立一个水晶报表WinForm工程(VB.Net),默认会增加一个报表CrystalReport1.rpt,再增加一个forSub1.rpt
因本代码只演示子报表的动态添加,所以两个报表里都只放了些文本,均未链接数据库
Imports
CrystalDecisions.Shared
Imports CrystalDecisions.Windows.Forms
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.ReportAppServer.ClientDoc
Imports CrystalDecisions.ReportAppServer.Controllers
Public Class Form1
Private Sub Form1_Load( ByVal sender As Object , ByVal e As System.EventArgs) Handles Me .Load
Dim boReportDocument As ReportDocument
Dim boReportClientDocument As ISCDReportClientDocument
Dim boSubreportClientDocument As CrystalDecisions.ReportAppServer.Controllers.SubreportClientDocument
Dim boArea As CrystalDecisions.ReportAppServer.ReportDefModel.Area
Dim boSection As CrystalDecisions.ReportAppServer.ReportDefModel.Section
Dim strSubRptFile As String
boReportDocument = New ReportDocument()
' 加载主报表
boReportDocument.Load( " E:/CRQuestions/AddSubReportRunTime/Crystalreport1.rpt " )
' ----------------------------------------
' 如果要进行数据、参数、公式操作,请在此处对主报表boReportDocument进行操作
' ----------------------------------------
boReportClientDocument = New ReportClientDocumentClass()
' 由主报表返回待RAS操作的ReportClientDocument
boReportClientDocument = boReportDocument.ReportClientDocument
' 设置待处理的报表区域(此处使用了报表页眉)
boArea = boReportClientDocument.ReportDefController.ReportDefinition.ReportHeaderArea
' 创建一个新的section,用来放置子报表
boSection = New CrystalDecisions.ReportAppServer.ReportDefModel.Section
' 设置新节的名称
boSection.Kind = CrystalDecisions.ReportAppServer.ReportDefModel.CrAreaSectionKindEnum.crAreaSectionKindReportHeader
boSection.Name = " ReportHeaderForSub1 "
' 设置节对象宽度。注意1cm=567缇,可自行调整,此处为20cm
boSection.Width = 567 * 20
' 待加载的子报表
strSubRptFile = " E:/CRQuestions/AddSubReportRunTime/forSub1.rpt "
' 将section加到ReportClientDocument
boReportClientDocument.ReportDefController.ReportSectionController.Add(boSection,boArea, - 1 )
' 导入子报表,ss1是子报表对象在主报表上的名称
boSubreportClientDocument = boReportClientDocument.SubreportController.ImportSubreport( " ss1 " ,strSubRptFile,boSection)
' ----------------------------------------
' 如果要进行数据、参数、公式操作,请在此处对子报表boSubreportClientDocument进行操作
' ----------------------------------------
' 刷新Viewer
CrystalReportViewer1.ReportSource = boReportDocument
EndSub
EndClass
Imports CrystalDecisions.Windows.Forms
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.ReportAppServer.ClientDoc
Imports CrystalDecisions.ReportAppServer.Controllers
Public Class Form1
Private Sub Form1_Load( ByVal sender As Object , ByVal e As System.EventArgs) Handles Me .Load
Dim boReportDocument As ReportDocument
Dim boReportClientDocument As ISCDReportClientDocument
Dim boSubreportClientDocument As CrystalDecisions.ReportAppServer.Controllers.SubreportClientDocument
Dim boArea As CrystalDecisions.ReportAppServer.ReportDefModel.Area
Dim boSection As CrystalDecisions.ReportAppServer.ReportDefModel.Section
Dim strSubRptFile As String
boReportDocument = New ReportDocument()
' 加载主报表
boReportDocument.Load( " E:/CRQuestions/AddSubReportRunTime/Crystalreport1.rpt " )
' ----------------------------------------
' 如果要进行数据、参数、公式操作,请在此处对主报表boReportDocument进行操作
' ----------------------------------------
boReportClientDocument = New ReportClientDocumentClass()
' 由主报表返回待RAS操作的ReportClientDocument
boReportClientDocument = boReportDocument.ReportClientDocument
' 设置待处理的报表区域(此处使用了报表页眉)
boArea = boReportClientDocument.ReportDefController.ReportDefinition.ReportHeaderArea
' 创建一个新的section,用来放置子报表
boSection = New CrystalDecisions.ReportAppServer.ReportDefModel.Section
' 设置新节的名称
boSection.Kind = CrystalDecisions.ReportAppServer.ReportDefModel.CrAreaSectionKindEnum.crAreaSectionKindReportHeader
boSection.Name = " ReportHeaderForSub1 "
' 设置节对象宽度。注意1cm=567缇,可自行调整,此处为20cm
boSection.Width = 567 * 20
' 待加载的子报表
strSubRptFile = " E:/CRQuestions/AddSubReportRunTime/forSub1.rpt "
' 将section加到ReportClientDocument
boReportClientDocument.ReportDefController.ReportSectionController.Add(boSection,boArea, - 1 )
' 导入子报表,ss1是子报表对象在主报表上的名称
boSubreportClientDocument = boReportClientDocument.SubreportController.ImportSubreport( " ss1 " ,strSubRptFile,boSection)
' ----------------------------------------
' 如果要进行数据、参数、公式操作,请在此处对子报表boSubreportClientDocument进行操作
' ----------------------------------------
' 刷新Viewer
CrystalReportViewer1.ReportSource = boReportDocument
EndSub
EndClass
C#版本(WinForm):
using
System;
using System.Windows.Forms;
using CrystalDecisions.Shared;
using CrystalDecisions.Windows.Forms;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.ReportAppServer.ClientDoc;
using CrystalDecisions.ReportAppServer.Controllers;
namespace CS_APP_AddSubReportRuntime
{
public partial class Form1:Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load( object sender,EventArgse)
{
ReportDocumentboReportDocument = new ReportDocument();
ISCDReportClientDocumentboReportClientDocument;
CrystalDecisions.ReportAppServer.Controllers.SubreportClientDocumentboSubreportClientDocument;
CrystalDecisions.ReportAppServer.ReportDefModel.SectionboSection;
StringstrSubRptFile = "" ;
// 加载主报表
boReportDocument.Load( @" E:/CRQuestions/CS_APP_AddSubReportRuntime/Crystalreport1.rpt " );
/* ----------------------------------------
如果要进行数据、参数、公式操作,请在此处对主报表boReportDocument进行操作
---------------------------------------- */
boReportClientDocument = new ReportClientDocumentClass();
// 由主报表返回待RAS操作的ReportClientDocument
boReportClientDocument = boReportDocument.ReportClientDocument;
// 获取到第一个section,用来放置子报表
boSection = boReportClientDocument.ReportDefController.ReportDefinition.PageHeaderArea.Sections[ 0 ];
// 待加载的子报表
strSubRptFile = @" E:/CRQuestions/CS_APP_AddSubReportRuntime/sub1.rpt " ;
// 导入子报表,boSection);
/* ----------------------------------------
如果要进行数据、参数、公式操作,请在此处对子报表boSubreportClientDocument进行操作
---------------------------------------- */
// 刷新Viewer
crystalReportViewer1.ReportSource = boReportDocument; } } }
using System.Windows.Forms;
using CrystalDecisions.Shared;
using CrystalDecisions.Windows.Forms;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.ReportAppServer.ClientDoc;
using CrystalDecisions.ReportAppServer.Controllers;
namespace CS_APP_AddSubReportRuntime
{
public partial class Form1:Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load( object sender,EventArgse)
{
ReportDocumentboReportDocument = new ReportDocument();
ISCDReportClientDocumentboReportClientDocument;
CrystalDecisions.ReportAppServer.Controllers.SubreportClientDocumentboSubreportClientDocument;
CrystalDecisions.ReportAppServer.ReportDefModel.SectionboSection;
StringstrSubRptFile = "" ;
// 加载主报表
boReportDocument.Load( @" E:/CRQuestions/CS_APP_AddSubReportRuntime/Crystalreport1.rpt " );
/* ----------------------------------------
如果要进行数据、参数、公式操作,请在此处对主报表boReportDocument进行操作
---------------------------------------- */
boReportClientDocument = new ReportClientDocumentClass();
// 由主报表返回待RAS操作的ReportClientDocument
boReportClientDocument = boReportDocument.ReportClientDocument;
// 获取到第一个section,用来放置子报表
boSection = boReportClientDocument.ReportDefController.ReportDefinition.PageHeaderArea.Sections[ 0 ];
// 待加载的子报表
strSubRptFile = @" E:/CRQuestions/CS_APP_AddSubReportRuntime/sub1.rpt " ;
// 导入子报表,boSection);
/* ----------------------------------------
如果要进行数据、参数、公式操作,请在此处对子报表boSubreportClientDocument进行操作
---------------------------------------- */
// 刷新Viewer
crystalReportViewer1.ReportSource = boReportDocument; } } }