65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ReportViewer 在 ASP.NET 2.0 中创建钻取报表

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.53/5 (9投票s)

2006年12月12日

4分钟阅读

viewsIcon

43657

本文提供了使用 SQL Server 2005、Microsoft Application Blocks 和 ASP.NET 2.0 中的 ReportViewer 控件在本地模式下创建钻取报表的循序渐进的演示。

引言

本文提供了使用 SQL Server 2005、Microsoft Application Blocks 和 ReportViewer 控件在 ASP.NET 2.0 的本地模式下创建钻取报表的循序渐进的演示。

场景

我们将创建一个父报表,列出每个客户下的所有订单。当用户单击ReportViewer上的[订单 ID]字段时,将显示一个钻取报表,以显示构成父级订单摘要的行项目。当用户单击每个行项目上的[产品 ID]字段时,我们的演示将显示另一个钻取级别,显示产品详细信息。

步骤 1:创建一个存储过程,用于列出每个客户的所有订单及其总金额。在此演示中,我将显示的记录数量限制为两个客户。

ALTER PROCEDURE List_Customers_OrderTotal
AS
SELECT Customers.CompanyName,
Orders.OrderID, 
Orders.OrderDate, 
SUM([Order Details].Quantity * [Order Details].UnitPrice) AS TotalDollars
FROM Orders INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID
INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID
WHERE Orders.CustomerID IN ('THEBI', 'THECR')
GROUP BY CompanyName, Orders.OrderID, OrderDate
ORDER BY CompanyName, Orders.OrderID, OrderDate
RETURN

步骤 2:创建一个存储过程来显示订单详细信息。此存储过程的结果为我们的第 1 级钻取报表提供数据。

ALTER PROCEDURE Show_OrderDetails ( @OrderID int )
AS
SELECT [Order Details].OrderID,
Products.ProductID,
Products.ProductName, 
[Order Details].UnitPrice, 
[Order Details].Quantity 
FROM [Order Details] INNER JOIN Products 
  ON [Order Details].ProductID = Products.ProductID
WHERE [Order Details].OrderID = @OrderID
RETURN

步骤 3:创建一个存储过程来显示产品详细信息。此存储过程的结果为我们的第 2 级钻取报表提供数据。

ALTER PROCEDURE Show_Products ( @ProductID int )
AS
SELECT Products.ProductID,
Products.ProductName As Product,
Categories.CategoryName As Category,
Categories.Description,
Suppliers.CompanyName AS Supplier,
Suppliers.Phone AS SupplierPhone
FROM Products INNER JOIN Suppliers ON Products.SupplierID = Suppliers.SupplierID
INNER JOIN Categories ON Products.CategoryID = Categories.CategoryID
WHERE ProductID=@ProductID
RETURN

步骤 4:在App_Code文件夹下的数据集(.xsd)中创建数据表。此.xsd用于存储从每个存储过程检索的数据。每个数据表将作为单个.rdlc的数据源。我们将在接下来的几步中创建三个.rdlc

步骤 5:创建父报表(Parent.rdlc

步骤 6:创建钻取报表 #1(Level1.rdlc

步骤 7:为报表 #1(Level1.rdlc)定义报表参数。当用户单击parent.rdlc中的OrderID字段时,OrderID值将传递给Level1.rdlc。OrderID值用于检索正确的订单详细行项目。

点击 Level1.rdlc 的正文。点击菜单选项“报表”。选择“报表参数”。点击“添加”将 OrderID 添加到报表参数列表中。

步骤 8:创建钻取报表 #2(Level2.rdlc

步骤 9:为报表 #2(Level2.rdlc)定义报表参数。当用户点击 Level1.rdlc 中的 ProductID 字段时,ProductID 值将被传递给 Level2.rdlc 以提取正确的产品信息。

点击 Level2.rdlc 的正文。点击菜单选项“报表”。选择“报表参数”。点击“添加”将 ProductID 添加到报表参数列表中。

步骤 10:确定当parent.rdlc中的OrderID被单击时要导航到的钻取报表。例如,当用户单击Parent.rdlc中的OrderID值时,我们的应用程序将显示带有正确订单详细信息的Level1.rdlc

打开 Parent.rdlc。右键点击 OrderID 的值。从上下文菜单中选择“属性”。选择“导航”选项卡。从“跳转到报表”中选择 Level1.rdlc

点击“参数”并打开下面的对话框。输入“OrderID”作为参数名称,并标识参数值的来源。点击“确定”。

当用户单击Level1.rdlc中的ProductID值时,我们的应用程序将显示带有正确产品信息的Level2.rdlc。打开Level1.rdlc。右键单击ProductID的值。从上下文菜单中选择“属性”。选择“导航”选项卡。从“跳转到报表”中选择Level2.rdlc

点击“参数”并打开下面的对话框。输入“ProductID”作为参数名称,并标识参数值的来源。

步骤 11:创建一个.aspx来容纳所有三个.rdlc。下面创建的DrillThroughReport_Parent.aspx用于显示初始报表“Parent.rdlc”,随后是“Level1.rdlc”和“Level2.rdlc”。无需为容纳“Level1.rdlc”或“Level2.rdlc”而创建单独的.aspx

确保在设计模式下将ReportViewer控件的Visible属性设置为falseVisible属性将在数据源填充后通过编程方式重新设置为true

步骤 12:向父报表的钻取事件(DrillThroughReport_Parent.aspx)添加源代码

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Microsoft.ApplicationBlocks.Data;
using Microsoft.Reporting.WebForms;

public partial class DrillThroughReport_Parent : System.Web.UI.Page
{
    public string thisConnectionString = 
      ConfigurationManager.ConnectionStrings
      ["NorthwindConnectionString"].ConnectionString;
    public string thatConnectionString = 
      ConfigurationManager.ConnectionStrings
      ["NorthwindConnectionString"].ConnectionString;
    public SqlParameter[] Level1SearchValue = new SqlParameter[1];
    public SqlParameter[] Level2SearchValue = new SqlParameter[1];

    protected void RunReportButton_Click(object sender, EventArgs e)
    {
        ReportViewer1.Visible = true;

        SqlConnection thisConnection = new SqlConnection(thisConnectionString);
        System.Data.DataSet thisDataSet = new System.Data.DataSet();

        //Run the stored procedure  to fill dataset for Parent.rdlc
        thisDataSet = SqlHelper.ExecuteDataset(thisConnection, 
                     "List_Customers_OrderTotal");

        //Assign dataset to report datasource
        ReportDataSource datasource = 
          new ReportDataSource("DrillThroughDataSet_ListCustomersOrderTotal", 
          thisDataSet.Tables[0]);

        //Assign datasource to reportviewer control
        ReportViewer1.LocalReport.DataSources.Clear();
        ReportViewer1.LocalReport.DataSources.Add(datasource);
        ReportViewer1.LocalReport.Refresh();
    }

    protected void ReportViewer1_Drillthrough(object sender, 
              DrillthroughEventArgs e)
    {
        //Get OrderID that was clicked by 
        //user via e.Report.GetParameters()
        ReportParameterInfoCollection DrillThroughValues = 
                                 e.Report.GetParameters();    

        //This is just to show you how to iterate 
        //through the collection if you have
        //multiple parameters values instead of a single parameter value.
        //To process multiple parameters values, 
        //concatenate d.Values[0] into a string with a delimiter.
        //Use the Split() method to  separate values 
        //into an array. Assign indivdual array element to
        //corresponding parameter array element.
        foreach (ReportParameterInfo d in DrillThroughValues)
        {
            lblParameter.Text = d.Values[0].ToString().Trim();
        }
        LocalReport localreport = (LocalReport)e.Report;

        //Fill dataset for Level1.rdlc
        SqlConnection thisConnection = new SqlConnection(thisConnectionString);
        System.Data.DataSet Level1DataSet = new System.Data.DataSet();

        Level1SearchValue[0] = new SqlParameter("@OrderID", 
                               lblParameter.Text.Trim());
        Level1DataSet = SqlHelper.ExecuteDataset(thisConnection, 
                       "Show_OrderDetails", Level1SearchValue);

        ReportDataSource level1datasource = new 
          ReportDataSource("DrillThroughDataSet_ShowOrderDetails", 
          Level1DataSet.Tables[0]);
        localreport.DataSources.Clear();
        localreport.DataSources.Add(level1datasource);
        localreport.Refresh();

        //Fill dataset for Level2.rdlc.
        SqlConnection thatConnection = 
          new SqlConnection(thatConnectionString);
        System.Data.DataSet Level2DataSet = new System.Data.DataSet();

        Level2SearchValue[0] = 
          new SqlParameter("@ProductID", lblParameter.Text);
        Level2DataSet = SqlHelper.ExecuteDataset(thisConnection, 
                       "Show_Products", Level2SearchValue);

        ReportDataSource level2datasource = 
          new ReportDataSource("DrillThroughDataSet_ShowProducts", 
          Level2DataSet.Tables[0]);
        //No need to clear datasource again
        localreport.DataSources.Add(level2datasource);
        localreport.Refresh();
    }    
}

让我们运行应用程序:当用户点击“运行报表”按钮时,parent.rdlc 显示存储过程“List_Customers_OrderTotal”的结果。

当用户点击订单 ID “10310”时,Level1.rdlc 显示存储过程“Show_OrderDetails”返回的结果。

如果用户点击产品 ID “62”,Level2.rdlc 显示存储过程“Show_Products”返回的结果。

结论

我们使用Microsoft Application Blocks、SQL Server 2005和Visual Studio 2005在本地模式下创建了一个两级钻取报表。希望这个例子能让你对创建钻取报表的“如何做”有一些了解。如果你是第一次使用ReportViewer控件,你可能想查看我的另一篇文章“在本地模式下使用ASP.NET 2.0 ReportViewer”,以获取本地Web.config的安装提示以及服务器上所需的.exe

计算愉快!

© . All rights reserved.