Microsoft Reporting:在代码中设置子报表参数

时间:2009-01-19 09:15:15

标签: c# reporting-services parameters reporting subreport

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

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

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

澄清: 创建/定义参数不是问题。问题是设置它们的值。我认为自然要做的就是在SubreportProcessing事件中做到这一点。 SubreportProcessingEventArgs实际上有一个Parameters属性。但它是只读的!那你怎么用呢?我该如何设定价值?

7 个答案:

答案 0 :(得分:2)

它确实有效,但确实是安全的。

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

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

这是来自正在运行的VB.NET ReportViewer应用程序的SubreportProcessing事件处理程序。显示了几种获取子报表数据源的方法。 subreport1从应用程序业务对象构建一行数据表,subreport2提供报表所需的数据而不带参数,subreport3是谎言子报表2,但是计算传递给子报表的参数之一,以便在创建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

答案 1 :(得分:2)

最近我遇到了同样的问题,所有的搜索都没有找到任何帮助,但最后我找到了解决方案。

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

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

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

adding Subreport parameters

然后在加载报表时将输入(Employees列表)转换为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();
}

和...

它为我做了诀窍:)我希望它有所帮助。

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:1)

我知道这是一个老问题,已被标记为已回答,但由于我今天只是在搜索这个问题而且我看到它在过去几个月内被评论过,我以为我会提出跟进答案英寸

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

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

Here是一篇非常好的写作,更清楚地解释了这一点。

答案 4 :(得分:0)

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

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

如果要查看XML的外观,请添加子报告,在子报告属性&gt;中输入值。参数,然后做一个视图代码。

<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上放一个实际的值。

答案 5 :(得分:0)

在查看和查看之后,我得出的结论是,在代码中设置子报告的参数是不可能的。除非你做一些像开始编辑报表定义的xml之类的东西,然后再加载它或类似的东西。

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

答案 6 :(得分:-1)

Svish - 我不确定你遇到麻烦的哪一方。

要将参数添加到父报告,请打开它,然后右键单击子报告并选择“属性”&gt;参数。

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

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

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

要将参数添加到子报表,请打开子报表,然后从工具栏中选择“报告”&gt;报告参数

在此定义一个参数以从父报告中接收参数,例如

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

对于您想要做的事情,您不能取消子报告并且只有一个报告吗?您试图围绕报告的信息听起来非常适合包含在报告的页眉和页脚中。