C# Microsoft Reporting:在代码中设置子报表参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/456982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Microsoft Reporting: Setting subreport parameters in code
提问by Svish
How can I set a parameter of a sub-report? I have successfully hooked myself up to the SubreportProcessing event, I can find the correct sub-report through e.ReportPath, and I can add datasources through e.DataSources.Add. But I find no way of adding report parameters??
如何设置子报表的参数?我已经成功连接到 SubreportProcessing 事件,我可以通过 e.ReportPath 找到正确的子报表,并且我可以通过 e.DataSources.Add 添加数据源。但是我找不到添加报告参数的方法??
I have found people suggesting to add them to the master report, but I don't really want to do that, since the master report shouldn't have to be connected to the sub-report at all, other than that it is wrapping the sub-report.
我发现有人建议将它们添加到主报告中,但我真的不想这样做,因为主报告根本不必连接到子报告,除了它包装子报告。
I am using one report as a master template, printing name of the report, page numbers etc. And the subreport is going to be the report itself. And if I could only find a way to set those report parameters of the sub-report I would be good to go...
我使用一份报告作为主模板,打印报告的名称、页码等。子报告将成为报告本身。如果我只能找到一种方法来设置子报告的这些报告参数,我会很高兴……
Clarification:Creating/Defining the parameters is not the problem. The problem is to set their values. I thought the natural thing to do was to do it in the SubreportProcessing event. And the SubreportProcessingEventArgs do in fact have a Parameters property. But it is read only! So how do you use that? How can I set their value?
说明:创建/定义参数不是问题。问题是设置它们的值。我认为很自然的事情是在 SubreportProcessing 事件中进行。SubreportProcessingEventArgs 实际上有一个 Parameters 属性。但它是只读的!那么你如何使用它呢?如何设置它们的值?
采纳答案by Svish
After looking and looking, I have come to the conclusion that setting the parameters of a sub-report, in code, is not possible. Unless you do something fancy like start editing the xml of the report definition before you load it or something like that.
看了又看,我得出的结论是,在代码中设置子报表的参数是不可能的。除非你做一些特别的事情,比如在加载之前开始编辑报告定义的 xml 或类似的东西。
(But if someone else should know that I am wrong, please do answer, cause I am still very curious to know!)
(但如果其他人应该知道我错了,请回答,因为我仍然很想知道!)
回答by Dustin Brooks
You could add them via the xml definition. I use xml to create an entire report based on selected sub-reports and other options. I can paste some code in here come Monday if you would like to look at this as a possible solution.
您可以通过 xml 定义添加它们。我使用 xml 根据选定的子报告和其他选项创建整个报告。如果您想将其视为可能的解决方案,我可以在周一粘贴一些代码。
Edit: You can set values on the sub-report in the XML before you deploy the report. This is not very flexible and I am making the assumption that if you want to prompt for these values, you will most likely need them on the parent report.
编辑:您可以在部署报告之前在 XML 中的子报告上设置值。这不是很灵活,我假设如果您想提示输入这些值,您很可能在父报告中需要它们。
If you want to see what the XML looks like, add a sub-report, enter values for it in the sub-report properties > parameters, then do a view code.
如果要查看 XML 的外观,请添加子报表,在子报表属性 > 参数中为其输入值,然后执行查看代码。
<Subreport Name="subreport1">
<Parameters>
<Parameter Name="StartDate">
<Value>=Parameters!StartDate.Value</Value>
</Parameter>
<Parameter Name="EndDate">
<Value>1/1/2009</Value>
</Parameter>
Instead of using the =Parameters!StartDate.Value I'm guessing you would want to put an actual value like on the EndDate.
而不是使用 =Parameters!StartDate.Value 我猜你想在 EndDate 上放置一个实际值。
回答by Svish
It does work but it sure is persnickety.
它确实有效,但它肯定是挑剔的。
First thing I recommend is to develop your reports as .rdl. Much easier to test the reports this way. You can also get the subreport parameters set up and tested as rdl, making sure each parameter of the subreport is also defined as a parameter of the parent report. Once you get the reports - including the subreports - working that way you can rename the .rdl to rdlc and add the rdlc files to your ReportViewer Project. No further changes required. Use the names of the rdl datasources as the data source names in your code to provide data to the report in the SubreportProcessing event handler.
我建议的第一件事是将您的报告开发为 .rdl。以这种方式测试报告要容易得多。您还可以将子报表参数设置和测试为 rdl,确保子报表的每个参数也定义为父报表的参数。获得报告(包括子报告)后,您可以将 .rdl 重命名为 rdlc 并将 rdlc 文件添加到 ReportViewer 项目中。无需进一步更改。使用 rdl 数据源的名称作为代码中的数据源名称,以在 SubreportProcessing 事件处理程序中向报表提供数据。
You don't assign values to the passed parameter. The subreport will use them as is. (Sounds like the step you are missing is adding the parameters to the parent report as well as the the subreport as mentioned above.) You can evaluate the parameters and use them as query parameters to get the datasource you will add. You have to think about the datasource like its on an undiscovered dimension for a subreport. You will have to poke around while debugging in the event handler to see what I mean. Some of the values in your application will be readily available, others that you use easily elsewhere will throw object not found exceptions. For example I create a dataset in a instance of a class created on my applications main form. I use the data set throughout my application. In the SubreportProcessing event handler I cannot use the common dataset, so I must create a new instance of the table I need for the report and populate it. In the main report I would be able to access the common dataset. There are other limitations like this. Just have to wade your way through.
您不为传递的参数赋值。子报表将按原样使用它们。(听起来您缺少的步骤是将参数添加到父报表以及上面提到的子报表。)您可以评估参数并将它们用作查询参数来获取您将添加的数据源。您必须在子报表的未发现维度上考虑数据源。在事件处理程序中调试时,您将不得不四处看看我的意思。您的应用程序中的某些值将随时可用,您在其他地方轻松使用的其他值将抛出对象未找到异常。例如,我在我的应用程序主窗体上创建的类的实例中创建了一个数据集。我在整个应用程序中使用数据集。在 SubreportProcessing 事件处理程序中,我不能使用公共数据集,所以我必须为报告创建一个新的表实例并填充它。在主报告中,我将能够访问公共数据集。还有其他类似的限制。只需要涉水过去。
Here is the SubreportProcessing event handler from a working VB.NET ReportViewer application. Shows a few different ways to get the datasource for a subreport. subreport1 builds a one row datatable from application business objects, subreport2 provides data the report requires without a parameter, subreport3 is lie subreport2 but evaluates one of the parameters passed to the subreport for use in date value required by the query that creates the ReportDataSource.
下面是来自工作 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
回答by Svish
Svish - I'm not sure which side of the plumbing you're having trouble with.
Svish - 我不确定您在管道的哪一侧遇到了问题。
To add parameters to the parent report open it then right click on the subreport and select Properties > Parameters.
要将参数添加到父报表,请打开它,然后右键单击子报表并选择“属性”>“参数”。
You can then define parameter names and assign them a value, e.g.
然后您可以定义参数名称并为其分配一个值,例如
Parameter Name | Parameter Value
---------------+---------------------
MyParameter | =Fields!Params.Value
So on this side of the plumbing the parameters get their value from the parent report data source.
因此,在管道的这一侧,参数从父报表数据源获取它们的值。
To add parameters to a subreport open the subreport and from the toolbar select Report > Report Parameters
要将参数添加到子报表,请打开子报表并从工具栏中选择“报表”>“报表参数”
Here you define a parameter to receive the parameter from the parent report, e.g.
在这里你定义一个参数来接收来自父报表的参数,例如
Name | myParameter
----------+---------------------
Data Type | String
For what it sounds like you want to do can't you do away with a subreport and just have the one report anyway? The information you're trying to wrap around the report sounds ideal for just including in the headers and footers of the report.
对于听起来您想做的事情,难道您不能取消子报告而只拥有一份报告吗?您试图环绕报告的信息听起来非常适合仅包含在报告的页眉和页脚中。
回答by Dr. A
I had a similar problem in that I needed to pass a Properties.Settings.... value to prepend to the path in the database. To do this I had to set a property in the main report and use that property to set the second property in the subreport. Setting the main property then in turn sets the subreport property. YOU CAN set the main property in code as follows:
我有一个类似的问题,因为我需要传递一个 Properties.Settings.... 值来添加到数据库中的路径。为此,我必须在主报表中设置一个属性,并使用该属性在子报表中设置第二个属性。设置主属性然后依次设置子报表属性。您可以在代码中设置 main 属性,如下所示:
Suppose you have a ReportViewer name rv, then we would code:
假设您有一个名为 rv 的 ReportViewer,那么我们将编码:
var rp = new ReportParameter("MainReportParamName", Properties.Settings....);
rv.LocalReport.SetParameters(new ReportParameters[] { rp });
回答by VahidNaderi
Recently I had the same problem and with all the search I didn't find anything helpful but finally I came to a solution for this.
最近我遇到了同样的问题,经过所有搜索,我没有找到任何有用的东西,但最终我找到了解决方案。
I created a class having all the parameteres in the subreport as it's properties(we can call it a DTO)
我创建了一个类,其中包含子报表中的所有参数作为其属性(我们可以称其为 DTO)
public class MyDto
{
public string EmployeeFirstName{get; set;}
public string EmployeeLastName{get; set;}
// and so on
}
Then used a list of this type as another datasource in the main report and then in 'Subreport properties' added a parameter for each parameter in the actual subreport and chose the corresponding fields from the datasource as their values.
然后使用这种类型的列表作为主报表中的另一个数据源,然后在“子报表属性”中为实际子报表中的每个参数添加一个参数,并从数据源中选择相应的字段作为它们的值。
then when loading the report convert the input(list of Employees) to a list of MyDto and set it as the reports's datasource :
然后在加载报告时将输入(员工列表)转换为 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();
}
And...
和...
It did the trick for me :) I hope it helps somebody.
它对我有用:) 我希望它可以帮助某人。
回答by NCFireNerd
I know this is an old question which has been marked as answered, but since I was just searching for this today and I saw that it had been commented on within the last few months I thought I'd throw a follow up answer in.
我知道这是一个已被标记为已回答的老问题,但由于我今天只是在搜索这个问题,并且我看到它在过去几个月内被评论过,我想我会抛出一个后续答案。
In order to render the subreport in the context of each record on the main report, you need to declare a SubreportProcessingEventHandler
and then inside that handler load the DataSet for each instance of the subreport as it occurs. SubreportProcessingEventArgs
has a parameters collection which is passed from the parent report when the event fires.
为了在主报告的每条记录的上下文中呈现子报告,您需要声明一个SubreportProcessingEventHandler
,然后在该处理程序中为每个发生的子报告实例加载数据集。SubreportProcessingEventArgs
有一个参数集合,当事件触发时从父报告传递。
So if you have configured the subreport parameters on the main report with like named parameters bound to fields on the main report, the values are accessible as the subreport is rendered.
因此,如果您在主报告上配置了子报告参数,并使用绑定到主报告上的字段的类似命名参数,则可以在呈现子报告时访问这些值。
Hereis a very good write up that explains far more clearly.
这是一篇非常好的文章,解释得更清楚。