10

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

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

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

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

4

7 回答 7

2

它确实有效,但它肯定是挑剔的。

我建议的第一件事是将您的报告开发为 .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
于 2009-01-25T02:32:30.010 回答
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();
}

和...

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

于 2013-05-25T13:20:18.897 回答
2

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

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

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

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

于 2016-04-01T21:31:20.273 回答
1

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

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

var rp = new ReportParameter("MainReportParamName", Properties.Settings....);
rv.LocalReport.SetParameters(new ReportParameters[] { rp });
于 2010-05-17T01:26:40.667 回答
0

您可以通过 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 上放置一个实际值。

于 2009-01-20T02:55:40.933 回答
0

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

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

于 2009-01-22T08:42:32.370 回答
-1

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

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

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

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

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

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

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

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

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

于 2009-03-11T16:23:07.507 回答