【问题标题】:Microsoft Reporting: Setting subreport parameters in codeMicrosoft Reporting:在代码中设置子报表参数
【发布时间】:2009-01-19 09:15:15
【问题描述】:

如何设置子报表的参数?我已经成功连接到 SubreportProcessing 事件,我可以通过 e.ReportPath 找到正确的子报表,我可以通过 e.DataSources.Add 添加数据源。但是找不到添加报表参数的方法??

我发现有人建议将它们添加到主报告中,但我真的不想这样做,因为主报告根本不需要连接到子报告,除了它正在包装子报告。

我使用一个报表作为主模板,打印报表名称、页码等。子报表将是报表本身。如果我只能找到一种方法来设置子报告的那些报告参数,我会很高兴......

澄清:创建/定义参数不是问题。问题是设置它们的值。我认为自然的做法是在 SubreportProcessing 事件中进行。而且 SubreportProcessingEventArgs 实际上有一个 Parameters 属性。但它是只读的!那么你如何使用它呢?如何设置它们的值?

【问题讨论】:

标签: c# reporting-services parameters reporting subreport


【解决方案1】:

它确实有效,但它确实很挑剔。

我建议的第一件事是将您的报告开发为 .rdl。以这种方式测试报告要容易得多。您还可以将子报表参数设置和测试为 rdl,确保子报表的每个参数也定义为父报表的参数。一旦您获得报告(包括子报告)以这种方式工作,您可以将 .rdl 重命名为 rdlc 并将 rdlc 文件添加到您的 ReportViewer 项目中。无需进一步更改。使用 rdl 数据源的名称作为代码中的数据源名称,以便在 SubreportProcessing 事件处理程序中向报表提供数据。

您不会为传递的参数赋值。子报表将按原样使用它们。 (听起来您缺少的步骤是将参数添加到父报表以及上面提到的子报表。)您可以评估参数并将它们用作查询参数来获取您将添加的数据源。 您必须考虑数据源,就像它在子报表的未发现维度上一样。在事件处理程序中调试时,您将不得不四处寻找以了解我的意思。您的应用程序中的某些值将很容易获得,而您在其他地方轻松使用的其他值将引发 object not found 异常。例如,我在应用程序主窗体上创建的类的实例中创建数据集。我在整个应用程序中使用数据集。在 SubreportProcessing 事件处理程序中,我无法使用公共数据集,因此我必须创建报表所需的表的新实例并填充它。在主报告中,我将能够访问公共数据集。还有其他类似的限制。只需要涉水而过。

这是来自工作中的 VB.NET ReportViewer 应用程序的 SubreportProcessing 事件处理程序。显示获取子报表数据源的几种不同方法。 subreport1 从应用程序业务对象构建单行数据表,subreport2 提供报表所需的数据,不带参数,subreport3 是 subreport2,但会评估传递给子报表的参数之一,以便在创建 ReportDataSource 的查询所需的日期值中使用。

    Public Sub SubreportProcessingEventHandler(ByVal sender As Object, _
                                               ByVal e As SubreportProcessingEventArgs)
    Select Case e.ReportPath
        Case "subreport1"
            Dim tbl As DataTable = New DataTable("TableName")
            Dim Status As DataColumn = New DataColumn
            Status.DataType = System.Type.GetType("System.String")
            Status.ColumnName = "Status"
            tbl.Columns.Add(Status)
            Dim Account As DataColumn = New DataColumn
            Account.DataType = System.Type.GetType("System.String")
            Account.ColumnName = "Account"
            tbl.Columns.Add(Account)
            Dim rw As DataRow = tbl.NewRow()
            rw("Status") = core.GetStatus
            rw("Account") = core.Account
            tbl.Rows.Add(rw)
            e.DataSources.Add(New ReportDataSource("ReportDatasourceName", tbl))
        Case "subreport2"
            core.DAL.cnStr = My.Settings.cnStr
            core.DAL.LoadSchedule()
            e.DataSources.Add(New ReportDataSource("ScheduledTasks", _
                                                   My.Forms.Mother.DAL.dsSQLCfg.tSchedule))
        Case "subreport3"
            core.DAL.cnStr = My.Settings.cnStr
            Dim dt As DataTable = core.DAL.GetNodesForDateRange(DateAdd("d", _
                                                                          -1 * CInt(e.Parameters("NumberOfDays").Values(0)), _
                                                                          Today), _
                                                                  Now)
            e.DataSources.Add(New ReportDataSource("Summary", dt))
    End Select
End Sub

【讨论】:

  • 是的,这就是我来看看我也必须做的事情。问题是,将所有这些参数添加到主报告中是不可能的。我们使用一份主要报告作为模板,在其中粘贴所有报告中应包含的所有内容。名称、参数、页面、logo等
  • 然后我们将“真实”报告粘贴在其中的子报告中。而且效果很好。除了那些参数。无论如何,想法是使用参数来翻译东西,但我现在创建了一个为我修复它的类:codeplex.com/rdlclocalizer
【解决方案2】:

最近我遇到了同样的问题,通过所有搜索我没有发现任何有用的东西,但最终我找到了解决方案。

我创建了一个类,其中包含子报表中的所有参数作为它的属性(我们可以称它为 DTO)

public class MyDto
{
    public string EmployeeFirstName{get; set;}
    public string EmployeeLastName{get; set;}
    // and so on
}

然后在主报表中使用此类型的列表作为另一个数据源,然后在“子报表属性”中为实际子报表中的每个参数添加一个参数,并从数据源中选择相应的字段作为它们的值。

然后在加载报告时将输入(员工列表)转换为 MyDto 列表并将其设置为报告的数据源:

private void LoadReport(List<Employee> employees)
{
    reportviewerMain.ProcessingMode = ProcessingMode.Local;
    reportviewerMain.LocalReport.ReportPath = Application.StartupPath + "\\Reports\\PayChecksReport.rdlc";

    List<MyDto> employeesDataSource = employees.ConvertAll<MyDto>(emp => new MyDto { EmployeeFirstName = emp.FirstName, EmployeeLastName = emp.LastName}).ToList();
    reportviewerMain.LocalReport.DataSources.Add(new ReportDataSource("EmployeesDataSet", employeesDataSource));

    Organization myOrganization = new OranizationFacade().GetOrganizationInfo();
    reportviewerMain.LocalReport.SetParameters(new ReportParameter("OrganizationName", myOrganization.Name));

    this.reportviewerMain.RefreshReport();
}

还有……

它对我有用 :) 我希望它对某人有所帮助。

【讨论】:

    【解决方案3】:

    我知道这是一个已被标记为已回答的老问题,但由于我今天只是在搜索这个问题,并且我看到它在过去几个月内已被评论过,我想我会提出一个后续答案在。

    为了在主报表上的每条记录的上下文中呈现子报表,您需要声明一个SubreportProcessingEventHandler,然后在该处理程序中为子报表的每个实例加载数据集。 SubreportProcessingEventArgs 有一个参数集合,该集合在事件触发时从父报表传递。

    因此,如果您在主报表上配置了子报表参数,并在主报表上的字段上绑定了类似的命名参数,则在呈现子报表时可以访问这些值。

    Here 是一篇非常好的文章,解释得更清楚。

    【讨论】:

    • 似乎不起作用。 SubReportProcessing 来不及设置参数。
    【解决方案4】:

    我有一个类似的问题,我需要传递一个 Properties.Settings.... 值来添加到数据库中的路径。为此,我必须在主报表中设置一个属性,并使用该属性在子报表中设置第二个属性。设置主属性,然后依次设置子报表属性。您可以在代码中设置 main 属性如下:

    假设您有一个名为 rv 的 ReportViewer,那么我们将编码:

    var rp = new ReportParameter("MainReportParamName", Properties.Settings....);
    rv.LocalReport.SetParameters(new ReportParameters[] { rp });
    

    【讨论】:

      【解决方案5】:

      您可以通过 xml 定义添加它们。我使用 xml 根据选定的子报告和其他选项创建整个报告。如果您想将其视为可能的解决方案,我可以在星期一在这里粘贴一些代码。

      编辑:您可以在部署报表之前在 XML 中设置子报表的值。这不是很灵活,我假设如果您想提示输入这些值,您很可能在父报表中需要它们。

      如果您想查看 XML 的样子,请添加一个子报表,在子报表属性 > 参数中为其输入值,然后查看代码。

      <Subreport Name="subreport1">
          <Parameters>
            <Parameter Name="StartDate">
              <Value>=Parameters!StartDate.Value</Value>
            </Parameter>
            <Parameter Name="EndDate">
              <Value>1/1/2009</Value>
            </Parameter>
      

      而不是使用 =Parameters!StartDate.Value 我猜你想在 EndDate 上放置一个实际值。

      【讨论】:

      • 这有什么帮助? xml定义只是报告的“大纲”,不是吗?那里没有实际数据?我可以在报告编辑器中定义参数。我需要做的是设置它们的值。
      • 您可以在部署报表之前设置 XML 中的值。如果您需要提示这些值,我很确定您必须将它们包含在父报告中。
      【解决方案6】:

      看了又看,得出的结论是,在代码中设置子报表的参数是不可能的。除非你做一些花哨的事情,比如在加载之前开始编辑报告定义的 xml 或类似的东西。

      (但如果其他人知道我错了,请回答,因为我仍然很想知道!)

      【讨论】:

      • 我尝试使用具有单行的 DataTable,而不是参数列表,但这似乎不受支持。或者它不喜欢子报表有页眉和页脚。
      【解决方案7】:

      Svish - 我不确定您在管道的哪一侧遇到问题。

      要向父报表添加参数,请打开它,然后右键单击子报表并选择“属性”>“参数”。

      然后您可以定义参数名称并为其分配一个值,例如

      Parameter Name | Parameter Value
      ---------------+---------------------
      MyParameter    | =Fields!Params.Value
      

      因此,在管道的这一侧,参数从父报表数据源获取它们的值。

      要向子报表添加参数,请打开子报表并从工具栏中选择报表 > 报表参数

      这里定义一个参数来接收来自父报表的参数,例如

      Name      | myParameter
      ----------+---------------------
      Data Type | String
      

      对于听起来您想做的事情,您难道不能取消子报表而只拥有一份报表吗?您试图在报告中包含的信息听起来非常适合仅包含在报告的页眉和页脚中。

      【讨论】:

      • 我无法设置子报表的参数,然后像使用数据源和报表定义一样通过代码设置它们。我不能也不想删除子报告,因为顶部包装不仅仅包含简单的页眉和页脚。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多