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

Microsoft Reporting Services(子报表、图表、参数、表达式编辑器等)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (54投票s)

2009 年 6 月 1 日

CPOL

6分钟阅读

viewsIcon

230158

downloadIcon

7672

本文展示了创建报表、在运行时定义数据源、使用参数、插入图像、使用表达式编辑器以及如何向子报表和图表提供数据的基本步骤。最后,它将演示ReportViewer的一些简单自定义。

ReportViewerDemo

Microsoft 报表基于报表定义,报表定义是一个 XML 文件,描述了报表的数据和布局,具有不同的扩展名。您可以使用 Visual Studio 创建客户端报表定义语言 (*.rdlc) 文件,并为您的应用程序构建出色的报表。报表可以包含表格、聚合和多维数据,此外还可以包含图表,并可用于 Winform 或 ASP.NET。

这篇“操作指南”文章的目的是展示创建报表、在运行时定义数据源、使用参数、包含图像、使用表达式编辑器以及如何向子报表和图表提供数据的基本步骤。最后,它还将演示一些自定义ReportViewer控件的简单方法。

引言

首先,我为这个例子创建了一个简单的 SQL 表,其中包含一些数据。它是一个电子设备列表,如 PDA、台式机等。从该表中,您需要创建包含两个不同DataTableDataSet。将其命名为“dsReport.xsd”。

MicrosoftReports/rpt002.png

第一个DataTableproducts”包含表中所有产品的列表。第二个“groupTotal”是一个聚合 (Group By) 查询,其中包含将在子报表和图表中使用的组和数量总和。

之后,您需要向应用程序添加一个报表。只需选择它并给它一个合适的名称。例如,我选择了“rptProducts”。

MicrosoftReports/rpt003.png

报表创建并打开后,菜单栏中会有一个新菜单,名为“Report”。选择“页面页眉”和“页面页脚”以在报表中显示这些部分。之后,只需从工具箱中将一个表格拖到报表的正文部分。

DataSource

现在是时候定义DataSource了。从“报表”菜单中,选择“数据源”。它将打开一个窗口,您可以在其中选择应用程序中可用的数据源。选择已创建的DataSet

MicrosoftReports/rpt004.png

注意:“报表数据源”的名称可以重命名,并且将在后续代码中使用,您将看到!

为报表定义数据源后,您将在“数据源资源管理器”(通常在“解决方案资源管理器”窗口中可用)中看到可用的DataTable。现在,从“Products”表中,将列拖到已添加到正文部分的Table对象中。

MicrosoftReports/rpt005.png

Table对象的工作方式类似于 Excel 电子表格。您可以合并单元格、格式化单元格、更改背景颜色等。本示例使用货币字段。为了向您展示格式化单元格有多容易,右键单击字段单元格并选择“属性”。在“属性”窗口中,转到“格式”选项卡并为该单元格定义货币格式。

MicrosoftReports/rpt006.png

您还可以更改其他字段的格式,例如粗体、颜色、标题等,以获得专业外观。

图像

要在应用程序中包含图像,您可以嵌入它们,然后将其用作徽标(例如)。如果它们以二进制数据存储,您也可以从数据库中获取它们。

要将图像嵌入到报表中,您只需转到菜单“报表”并选择“嵌入图像”。在新窗口中,选择“新建图像”按钮并浏览您的图像。

MicrosoftReports/rpt007.png

关闭窗口。然后,从工具箱中,将图像控件添加到报表。在图像属性中,从“值”属性中可用的组合框中选择图像名称。

表达式编辑器

Visual Studio 2008 Microsoft Reporting Services 表达式编辑器的一大优点是,在您需要创建某些公式时,它提供了智能感知功能。

在页脚部分,您可以添加两个文本框。其中一个可以包含页码和总页数。为此,您已经在“全局”类别中有一些内置公式。

MicrosoftReports/rpt008.png

如下图所示,您可以在表达式编辑器中使用 VB 公式(大部分)。智能感知大大有助于防止错误和记住公式语法。

MicrosoftReports/rpt009.png

参数

您可以将参数用于许多不同的事情。对于本示例,我将仅用于将信息从应用程序传递到报表。

在“报表”菜单中,选择“报表参数”。定义两个类型为String的参数:“ApplicationUser”和“ApplicationLevel”。

MicrosoftReports/rpt010.png

然后,在报表中,您可以使用表达式编辑器为文本框定义参数(它们将在代码中定义)。它们将在参数类别中可用。

MicrosoftReports/rpt011.png

图表

您可以在报表中使用许多图表,它们非常容易自定义和提供数据。从工具箱中将一个图表控件添加到报表的正文部分。双击它,它将显示“数据字段”和“类别字段”区域。从“数据源资源管理器”中拖动“组”和“总计”字段。

MicrosoftReports/rpt012.png

您也可以在“图表属性”窗口的“数据”选项卡中执行此操作。在此窗口中,您可以自定义系列颜色、图例、3D 效果、过滤器、轴等。

Using the Code

在前面的步骤中,您在报表中使用了一些数据源。现在您将添加新的数据源,无论是否过滤,那将是您将看到的数据。

Imports System.Data.SqlClient
Imports Microsoft.Reporting.WinForms

Public Class Form1

    ' Connection string definition
    Private connString As String = _
            "Data Source=.\SQLEXPRESS;AttachDbFilename='|DataDirectory|\myDatabase.mdf';_
		Integrated Security=True;User Instance=True"

    '''  <summary>
    ''' Form load event
    '''  </summary>
    Private Sub Form1_Load(ByVal sender As Object, _
		ByVal e As System.EventArgs) Handles Me.Load

        Try

            ' Call the customization method
            Call customizeReportViewer(Me.ReportViewer1)

            ' Add a button to the ReportViewer
            Call AddReportViewerButton()

            With Me.ReportViewer1.LocalReport

                ' Report path
                .ReportPath = Application.StartupPath & "\..\..\rptProducts.rdlc"
                .DataSources.Clear()

                ' Set the parameters
                Dim parameters(1) As ReportParameter
                parameters(0) = New ReportParameter("ApplicationUser", "jpaulino")
                parameters(1) = New ReportParameter("ApplicationLevel", "Administrator")
                .SetParameters(parameters)

            End With

            ' ----------------------------------------------------
            ' Datasource for the main report (where price > 200)
            ' ----------------------------------------------------
            Dim SQL As String = "SELECT * FROM products WHERE price > @price"
            Using da As New SqlDataAdapter(SQL, connString)
                da.SelectCommand.Parameters.Add("@price", SqlDbType.Int).Value = 200

                Using ds As New DataSet
                    da.Fill(ds, "products")

                    ' You must use the same name as defined in the report 
		  ' Data Source Definition
                    Dim rptDataSource As New ReportDataSource_
			("dsReport_products", ds.Tables("products"))
                    Me.ReportViewer1.LocalReport.DataSources.Add(rptDataSource)

                End Using

            End Using

            ' ----------------------------------------------------
            ' Datasource for the Chart
            ' ----------------------------------------------------
            Dim SQL_Chart As String = "SELECT [group], SUM(quantity) AS _
					Total FROM products GROUP BY [group]"
            Using da As New SqlDataAdapter(SQL_Chart, connString)
                Using ds As New DataSet
                    da.Fill(ds, "groupTotal")

                    Dim rptDataSource As New ReportDataSource("dsReport_groupTotal", _
				ds.Tables("groupTotal"))
                    Me.ReportViewer1.LocalReport.DataSources.Add(rptDataSource)

                End Using
            End Using


            ' Refresh the report
            ReportViewer1.RefreshReport()


        Catch ex As Exception
            MessageBox.Show(ex.Message, My.Application.Info.Title, _
			MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub

子报表

您可以在报表中使用一个或多个子报表。为此,您需要为每个子报表填充数据源。由于您无法直接访问子报表的数据源,因此您必须为SubreportProcessing定义一个处理程序,然后当子报表加载时,您可以从数据库中检索数据,并设置其数据源。

它可能看起来很难,但很容易完成!

定义子报表的数据源并使用Table对象,就像在主报表中一样。将字段添加到Table对象。在主报表中,从工具箱添加一个子报表对象,并选择“报表名称”属性,以命名子报表。

然后在主报表的表单加载事件中,为SubreportProcessing添加一个处理程序。

AddHandler ReportViewer1.LocalReport.SubreportProcessing, _
				AddressOf SubreportProcessingEvent

最后,在SubreportProcessingEvent中,您只需以相同的方式定义新的datasource

    '''  <summary>
    ''' When the subreport is being processed/loaded, fills the datasource
    '''  </summary>
    Sub SubreportProcessingEvent(ByVal sender As Object, _
			ByVal e As SubreportProcessingEventArgs)

        Try

            Dim SQL As String = "SELECT [group], SUM(quantity) AS _
				Total FROM products GROUP BY [group]"
            Using da As New SqlDataAdapter(SQL, connString)
                Using ds As New DataSet
                    da.Fill(ds, "groupTotal")
                    Dim rptDataSource As New ReportDataSource_
			("dsReport_groupTotal", ds.Tables("groupTotal"))
                    e.DataSources.Add(rptDataSource)
                End Using
            End Using

        Catch ex As Exception
            MessageBox.Show(ex.Message, My.Application.Info.Title, _
			MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub

ReportViewer 自定义

ReportViewer是一个控件,用于在您的表单或网页中显示 Microsoft 报表。您可以自定义大多数控件以根据需要改进和自定义它。

在本文中,我将展示两种简单的自定义方法。

首先,您可以更改控件中的标题。您还可以做其他事情,例如禁用项目、重命名工具提示等。如果您需要更改控件的语言,这尤其有用,因为您只有英语可用。

为此,我创建了这个递归子例程,它将遍历ReportViewer中的所有控件并进行一些更改。

    '''  <summary>
    ''' Loops through all of ReportViewer controls and customize them
    '''  </summary>
    '''  <remarks></remarks>
    Sub customizeReportViewer(ByVal ctrl As Control)

        For Each c As Control In ctrl.Controls

            ' ----------------------------------------------------
            ' Check the text of the available labels
            ' ----------------------------------------------------
            If TypeOf c Is Label Then
                Dim lbl As Label = DirectCast(c, Label)
                Select Case lbl.Name
                    Case "LblGeneratingReport"
                        lbl.Text = "My report is loading now ... "
                    Case Else
                        ' You can add more customizations
                End Select
            End If

            ' ----------------------------------------------------
            ' Change the text in the ToolStrip to Portuguese
            ' ----------------------------------------------------
            If TypeOf c Is ToolStrip Then
                Dim ts As ToolStrip = DirectCast(c, ToolStrip)
                For Each item As ToolStripItem In ts.Items

                    Select Case item.Text
                        Case "Find"
                            item.Text = "Pesquisar"
                        Case "Next"
                            item.Text = "Próximo"
                        Case "of"
                            item.Text = "de"
                        Case Else
                            ' You can add more customizations
                    End Select
                Next
            End If

            ' If the control has child controls
            If c.HasChildren Then
                customizeReportViewer(c)
            End If

        Next

    End Sub

最后,您只需从表单加载事件中调用它,您在其中拥有ReportViewer

        ' Call the customization method
        Call customizeReportViewer(Me.ReportViewer1)

第二个自定义显示了如何在ToolStrip中包含一个新按钮。它将找到主toolstrip并在右侧添加一个新按钮。

    '''  <summary>
    ''' Find the main ToolStrip and add a new button on the right side
    '''  </summary>
    Sub AddReportViewerButton()

        Dim ts() As Control = Me.ReportViewer1.Controls.Find("toolStrip1", True)
        If ts IsNot Nothing Then
            Dim tsItem As ToolStrip = DirectCast(ts(0), ToolStrip)
            Dim item As New ToolStripButton
            item.Name = "newButton"
            item.Text = "New Button"
            item.BackColor = Color.Green
            item.ForeColor = Color.White
            item.Alignment = ToolStripItemAlignment.Right

            tsItem.Items.Add(item)

            AddHandler item.Click, AddressOf newButtonClick
        End If

    End Sub

当按钮按下时

    '''  <summary>
    ''' Shows a messagebox when the new button of 
    ''' the Reportviewer is pressed
    '''  </summary>
    Sub newButtonClick()
        MessageBox.Show("This is my new button!")
    End Sub

关注点

本文展示了使用 Microsoft Reports 的第一步,也是最重要的一步,以及如何处理一些代码。我希望这能帮助您开始使用它,并帮助您理解使用它们是多么容易。

希望对您有所帮助!

历史

  • 2009 年 6 月 1 日:初始帖子
© . All rights reserved.