运行时绑定数据源

ActiceReport允许在运行时修改数据源。可以参考下面的代码学习如何在运行时给报表连接数据源。

OleDB数据源

运行时连接OleDB数据源

在运行时可以调用API设置数据源和数据集。前提是已经添加好页面报表模板并且已经在Windows窗体上放置好报表浏览器控件。详情请参考在工程中添加ActiveReports使用报表报表查看器控件章节。

注:下面的代码适用于SQL,Odbc,OleDB或者Oracle数据源绑定。只需要修改数据提供程序类型和连接字符串就可以适用于不同类型。

1.   在Visual Studio工具项的页面布局报表下选择Table控件并拖拽到报表的设计画面上。

2.   在Table控件上,选择下列单元格,在属性框中根据下面数据设置的Value属性

单元格

值属性

左单元格

=Fields!ProductID.Value

中间单元格

=Fields!InStock.Value

右单元格

=Fields!Price.Value

 

3.   然后到Visual Studio的报表菜单下,选择保存布局项。

4.   在弹出的另存为窗口输入要保存的文件路径,并保存页面布局文件(例如RuntimeBinding.rdlx)到bin/debug目录下。

5.   双击Windows窗体的标题栏会自动创建Form_Load事件。

6.   在Form_Load事件处理内添加如下代码,用于报表的连接数据源,添加数据集和展示数据。

 

Visual Basic.NET代码

        'create an empty page report

        Dim def As New PageReport

        'load the report layout

        def.Load(New System.IO.FileInfo(Application.StartupPath + "\RuntimeBinding.rdlx"))

        'create and setup the data source

        Dim myDataSource As New GrapeCity.ActiveReports.PageReportModel.DataSource

        myDataSource.Name = "Example Data Source"

        myDataSource.ConnectionProperties.DataProvider = "OLEDB"

        myDataSource.ConnectionProperties.ConnectString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=[User Documents folder]\GrapeCity\ActiveReports  9\Samples\Data\Reels.mdb"

        'setup the dataset

        Dim myDataSet As New GrapeCity.ActiveReports.PageReportModel.DataSet()

        Dim myQuery As New GrapeCity.ActiveReports.PageReportModel.Query()

        myDataSet.Name = "Example Data Set"

        myQuery.DataSourceName = "Example Data Source"

        myQuery.CommandType =

        GrapeCity.ActiveReports.PageReportModel.QueryCommandType.TableDirect

        myQuery.CommandText =

        GrapeCity.ActiveReports.Expressions.ExpressionInfo.FromString("Product")

        myDataSet.Query = myQuery

        ' add fields

        Dim _field As New GrapeCity.ActiveReports.PageReportModel.Field("ProductID",

        "ProductID", Nothing)

        myDataSet.Fields.Add(_field)

        _field = New GrapeCity.ActiveReports.PageReportModel.Field("InStock", "InStock",

        Nothing)

        myDataSet.Fields.Add(_field)

        _field = New GrapeCity.ActiveReports.PageReportModel.Field("Price", "Price",

        Nothing)

        myDataSet.Fields.Add(_field)

        'bind the data source and the dataset to the report

        def.Report.DataSources.Add(myDataSource)

        def.Report.DataSets.Add(myDataSet)

        def.Run(Viewer1.LoadDocument(def.Document))

C#代码

        //create an empty page report

        GrapeCity.ActiveReports.PageReport def = new GrapeCity.ActiveReports.PageReport();

        //load the report layout

        def.Load(new System.IO.FileInfo(Application.StartupPath +"\RuntimeBinding.rdlx"));

        //create and setup the data source

        GrapeCity.ActiveReports.PageReportModel.DataSource myDataSource = new GrapeCity.ActiveReports.PageReportModel.DataSource();

        myDataSource.Name = "Example Data Source";

        myDataSource.ConnectionProperties.DataProvider = "OLEDB";

        myDataSource.ConnectionProperties.ConnectString ="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=[User Documents folder]\\GrapeCity\\ActiveReports  9\\Samples\\Data\\Reels.mdb";

        //setup the dataset

        GrapeCity.ActiveReports.PageReportModel.DataSet myDataSet = new GrapeCity.ActiveReports.PageReportModel.DataSet();

        GrapeCity.ActiveReports.PageReportModel.Query myQuery = new GrapeCity.ActiveReports.PageReportModel.Query();

        myDataSet.Name = "Example Data Set";

        myQuery.DataSourceName = "Example Data Source";

        myQuery.CommandType =GrapeCity.ActiveReports.PageReportModel.QueryCommandType.TableDirect;

        myQuery.CommandText =GrapeCity.ActiveReports.Expressions.ExpressionInfo.FromString("Product");

        myDataSet.Query = myQuery;

        // add fields

        GrapeCity.ActiveReports.PageReportModel.Field _field = new GrapeCity.ActiveReports.PageReportModel.Field("ProductID", "ProductID", null);

        myDataSet.Fields.Add(_field);

        _field = new GrapeCity.ActiveReports.PageReportModel.Field("InStock", "InStock",null);

        myDataSet.Fields.Add(_field);

        _field = new GrapeCity.ActiveReports.PageReportModel.Field("Price", "Price",null);

        myDataSet.Fields.Add(_field);

        //bind the data source and the dataset to the report def.Report.DataSources.Add(myDataSource); def.Report.DataSets.Add(myDataSet);

        def.Run();

viewer1.LoadDocument(def.Document);

  

7.   按F5执行程序

未绑定数据源

要在运行时连接未绑定的数据源,需要在LocateDateSource事件中使用数据集提供程序或者对象提供程序进行连接。报表引擎会在需要输入数据使用时触发LocateDateSource事件。

数据集提供程序

使用数据集提供程序时,设置连接字符串和查询字符串的方法取决如何连接数据。在LocateDataSource事件中给报表连接数据时,连接字符串设置为空白。

l 若LocateDataSource事件返回DataSet,则查询字符串设置为DataSet中的表名称

l 若LocateDataSource事件返回DataTable或者DataView类型,则查询字符串设置为空

若要给报表绑定的DataSet保存在文件中,则设置连接字符串为文件的路径,然后设置查询字符串为DataSet中表名称。

数据集提供程序缺陷

l 不支持关系名称中包含“.”字符

l 访问字段时是只能从最外层的关系开始(例FK_Order_Details_Orders.FK_Orders_Customers.CompanyName)

父数据表字段

访问父数据表的字段时,字段的前缀应该为合适的数据表的关系名称,使用“.”进行分割。

举例说明,有一个数据表OrderDetails作为子表关联到数据表Orders,两个数据表之间的关系名称为Orders_OrderDetails。可以使用下面的语法访问父数据表的字段OrderDateOrders_OrderDetails.OrderDate

使用同样的语法可以访问嵌套多层的数据表字段。举例说明,上例中的数据表Orders也存在父数据表Customers,关系名称为Customers_orders。命令行文本中指定数据表OrderDetails为主表,使用下面的语法访问父数据表的字段CustomerName

Customers_Orders.Orders_OrderDetails.CustomerName

注:当字段名称和关系使用相同名称时会发生错误,暂时不支持。

 

使用数据集提供程序

可以在报表运行时调用API设置数据集。

当数据集提供程序返回数据表实体(DataTable)时,数据表中的所有字段都是可访问的。要使用数据集提供程序作为报表的数据源,需要定义一个PageReport对象和一个Document对象,并且处理Document对象的LocateDataSource事件。

下面的步骤假设已经在Visual Studio工程中添加了页面报表模板和在Windows窗体上放置好报表浏览器控件,详情请参考在工程中添加ActiveReports使用报表查看器控件章节

1.    在报表资源管理器中,找到数据源节点,右键点击选择添加数据源

2.    当报表数据源对话框中,设置类型为DataSet Provider然后确定关闭对话框。新添加的数据源报表资源管理器中。

3.    右键点击新添加的数据源节点然后选择添加数据集。

4.    在数据集对话框中选择字段页。

5.    在字段页中添加字段=Fields!ProductID.Value=Fields!InStock.Value

6.    点击确定关闭对话框。字段名称会出现在新添加的数据集名称下面。

7.    在Visual Studio的ActiveReports 9页面布局报表工具箱中,拖拽Table控件到报表的设计页面上。

8.    使用报表资源管理器,将新添加的字段设置到Table控件的明细行的单元格上然后保存报表。

9.    在Visual Studio的解决方案资源管理器下,右键工程名称选择添加->类。

10.  当添加新项对话框中,设置名称为DataLayer.cs或者DataLayer.vb

11.  在解决方案资源管理器下,双击DataLayer.cs或者DataLayer.vb打开代码视图,将下面的代码粘贴进去。

Visual Basic.NET代码

Imports GrapeCity.ActiveReports.Expressions.ExpressionObjectModel

Imports System.Globalization

Imports System.Data.OleDb

Friend NotInheritable Class DataLayer

    Private _datasetData As System.Data.DataSet

    Public Sub New()

        LoadDataToDataSet()

    End Sub

    Public ReadOnly Property DataSetData() As System.Data.DataSet

        Get

            Return _datasetData

        End Get

    End Property

    Private Sub LoadDataToDataSet()

        Dim connStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;Data Source=[User Documents folder]\\GrapeCity\\ActiveReports 9\\Samples\\Data\\Reels.mdb"

        Dim productSql As String = "SELECT top 100 * FROM Product"

        _datasetData = New DataSet()

        Dim conn As New OleDbConnection(connStr)

        Dim cmd As OleDbCommand = Nothing

        Dim adapter As New OleDbDataAdapter

        cmd = New OleDbCommand(productSql, conn)

        adapter.SelectCommand = cmd

        adapter.Fill(_datasetData, "Products")

    End Sub

End Class

C#代码

using System;

using System.Data;

using System.Data.OleDb;

 

internal sealed class DataLayer

{

    private DataSet dataSetData;

    public DataLayer()

    {

        LoadDataToDataSet();

    }

    public DataSet DataSetData

    {

        get { return dataSetData; }

    }

    private void LoadDataToDataSet()

    {

        string connStr = @"Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;Data Source=[User Documents folder]\\GrapeCity\\ActiveReports 9\\Samples\\Data\\Reels.mdb";

        string productSql = "SELECT * From Product";

 

        dataSetData = new DataSet();

        OleDbConnection conn = new OleDbConnection(connStr);

        OleDbCommand cmd = new OleDbCommand(productSql, conn);

        OleDbDataAdapter adapter = new OleDbDataAdapter();

        adapter.SelectCommand = cmd;

        adapter.Fill(dataSetData, "Products");

    }

}

注:DataSetDataSource示例中提供了DataLayer类。DataSetDataSource示例程序放在了 [我的文档]\GrapeCity Samples\ActiveReports 9\Page Reports\RDL\API下。

 

12.  双击Windows窗体标题,将会创建Form_Load事件处理方法,在处理方法中添加如下代码。

Visual Basic.NET代码

Form_Load中添加如下代码

LoadReport()

窗体定义中添加如下代码

Dim WithEvents runtime As GrapeCity.ActiveReports.Document.PageDocument

    Private Sub LoadReport()

        Dim rptPath As New System.IO.FileInfo("..\..\YourReportName.rdlx")

        'Create a report definition that loads an existing report.

        Dim definition As New GrapeCity.ActiveReports.PageReport(rptPath)

        'Load the report definition into a new page document.

        runtime = New GrapeCity.ActiveReports.Document.PageDocument(definition)

        'Attach the runtime to an event. This line of code creates the event shell below.

        Viewer1.LoadDocument(runtime)

    End Sub

    'ActiveReports raises this event when it cannot locate a report's data source in the usual ways.

    Private Sub runtime_LocateDataSource(ByVal sender As Object, ByVal args As GrapeCity.ActiveReports.LocateDataSourceEventArgsHandles runtime.LocateDataSource()

        Dim dl = New DataLayer

        args.Data = dl.DataSetData.Tables("Products")

    End Sub

C#代码

Form_Load中添加如下代码

LoadReport()

 

窗体定义中添加如下代码

private void LoadReport()

        {

            System.IO.FileInfo rptPath = new

            System.IO.FileInfo("..\\..\\YourReportName.rdlx");

            //Create a report definition that loads an existing report.

            GrapeCity.ActiveReports.PageReport  definition = new GrapeCity.ActiveReports.PageReport(rptPath);

            //Load the report definition into a new page document.

            GrapeCity.ActiveReports.Document.PageDocument runtime = new GrapeCity.ActiveReports.Document.PageDocument(definition);

            //Attach the runtime to an event. This line of code creates the event shell below.

            runtime.LocateDataSource += new GrapeCity.ActiveReports.LocateDataSourceEventHandler(runtime_LocateDataSource);

            viewer1.LoadDocument(runtime);

        }

        //ActiveReports raises this event when it cannot locate a report's data source in the usual ways.

        private void runtime_LocateDataSource(object sender, GrapeCity.ActiveReports.LocateDataSourceEventArgs args)

        {

            DataLayer dl = new DataLayer();

            args.Data = dl.DataSetData.Tables["Products"];

        }

对象提供程序

可以调用API将对象集合绑定到报表数据源上。要绑定对象集合,需要定义一个PageReport对象和一个Document对象,并且处理Document对象的LocateDataSource事件。创建一个公共类,在其中定义要绑定的对象属性。

对象数据源需要将对象放到集合中,查询字符串设置为空,字段设置为对象的属性名称。这些字段需要在数据集对话框的字段页内手动添加。

当使用对象提供程序是,报表的连接字符串设置为空白,因为会在LocateDataSource事件中绑定对象。可以设置查询字符串为下面的其中一种:

使用对象提供程序

下面的步骤假设已经在Visual Studio工程中添加了页面报表模板和在Windows窗体上放置好报表浏览器控件,详情请参考在工程中添加ActiveReports使用报表查看器控件章节

1.    在报表资源管理器中,找到数据源节点,右键点击选择添加数据源

2.    当报表数据源对话框中,设置类型为Object Provider然后确定关闭对话框。新添加的数据源报表资源管理器中。

3.    右键点击新添加的数据源节点,弹出数据集对话框中选择字段页。

4.    在字段页,添加一个=Fields!name.Value字段,然后点击确定关闭对话框。字段会出现在数据集名称节点下。

5.    在Visual Studio的ActiveReports 9页面布局报表工具箱中,拖拽Table控件到报表的设计页面上。

6.    使用报表资源管理器,将新添加的字段设置到Table控件的明细行的单元格上然后保存报表。

7.    保存报表为DogReport.rdlx。

8.    在解决方法资源管理器中,右键点击窗体然后选择查看代码打开代码视图。

9.    在代码视图中粘帖下面的代码。

Visual Basic.NET代码

' Create a class from which to call a property.

    Public Class dog

        Private _name As String

        Public Property name() As String

            Get

                Return _name

            End Get

            Set(ByVal value As String)

                _name = Value

            End Set

        End Property

    End Class

    ' Create an array to contain the data.

    Dim dogArray As System.Collections.ArrayList

    ' Create a method to populate the data array.

    Private Sub LoadData()

        dogArray = New System.Collections.ArrayList()

        Dim dog1 As New dog()

        dog1.name = "border collie"

        dogArray.Add(dog1)

        dog1 = New dog()

        dog1.name = "cocker spaniel"

        dogArray.Add(dog1)

        dog1 = New dog()

        dog1.name = "golden retriever"

        dogArray.Add(dog1)

        dog1 = New dog()

        dog1.name = "shar pei"

        dogArray.Add(dog1)

    End Sub

C#代码

  // Create a class from which to call a property.

        public class dog

        {

            private string _name;

            public string name

            {

                get { return _name; }

                set { _name = value; }

            }

        }

        // Create an array to contain the data.

        System.Collections.ArrayList dogArray;

        // Create a method to populate the data array.

        private void LoadData()

        {

            dogArray = new System.Collections.ArrayList();

            dog dog1 = new dog();

            dog1.name = "border collie";

            dogArray.Add(dog1);

            dog1 = new dog();

            dog1.name = "cocker spaniel";

            dogArray.Add(dog1);

            dog1 = new dog();

            dog1.name = "golden retriever";

            dogArray.Add(dog1);

            dog1 = new dog();

            dog1.name = "shar pei";

            dogArray.Add(dog1);

        }

10.  创建报表并处理LocateDataSource事件,在Form_Load事件中添加如下代码。

Visual Basic.NET代码

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        '  Create file info with a path to the report in your project.

        Dim fi As New System.IO.FileInfo("..\\..\\DogReport.rdlx")

        '  Create a report definition using the file info.

        Dim repDef As New GrapeCity.ActiveReports.PageReport(fi)

        '  Create a page document using the report definition.

        Dim runt As New GrapeCity.ActiveReports.Document.PageDocument(repDef)

        '  Create a LocateDataSource event for the runtime.

        AddHandler runt.LocateDataSource, AddressOf runt_LocateDataSource

        ' Display the report in the viewer. The title can be any text.

        Viewer1.LoadDocument(runt)

    End Sub

C#代码

        private void Form1_Load(object sender, EventArgs e)

        {

            // Create file info with a path to the report in your project.

            System.IO.FileInfo fi = new System.IO.FileInfo("..\\..\\DogReport.rdlx");

            // Create a report definition using the file info.

            GrapeCity.ActiveReports.PageReport repDef = new GrapeCity.ActiveReports.PageReport(fi);

            // Create a page document using the report definition.

            GrapeCity.ActiveReports.Document.PageDocument runt = new GrapeCity.ActiveReports.Document.PageDocument(repDef);

            // Create a LocateDataSource event for the runtime.

            runt.LocateDataSource += new

            GrapeCity.ActiveReports.LocateDataSourceEventHandler(runt_LocateDataSource);

            // Display the report in the viewer. The title can be any text.

            viewer1.LoadDocument(runt);

        }

 

11.  在LoacateDataSource事件中,从对象集合中加载数据。

Visual Basic.NET代码

Private Sub runt_LocateDataSource(ByVal sender As Object, ByVal args As GrapeCity.ActiveReports.LocateDataSourceEventArgs)

        If dogArray Is Nothing Then LoadData()

        args.Data = dogArray

    End Sub

C#代码

void runt_LocateDataSource(object sender, GrapeCity.ActiveReports.LocateDataSourceEventArgs args)

        {

            if (dogArray == null)

            {

                LoadData();

            }

            args.Data = dogArray;

        }

12.  按F5启动程序。