Hi,
We are using web report designer, in datasource there is a parent collection (which actually contains one item) and a child collection. In main report properties of main collection are shown, in secondary report there should be items from child collection filtered based on some property of parent item.
Seems to be simple enough, but is it possible to do? I see no obvious way. In some other thread I've seen suggestions to use parameters - seems to be impossible in my case - I already have one parameter - item id, using this parameter calculated field are created in parent entity (by selecting a certain max element from child collection using item id parameter). Now then I need to use that calculated field of parent to filter out it's child collection.
I tried to use cascading parameters by creating a second parameter and filter it's items based of the first parameter, so that only one option remains. This works, but the problem is that this report will sometimes be generated in code without UI, so if I only pass first parameter, second one does not receive any value. The same picture if I make the second parameter hidden.
I also tried adding calculated field to each child item that would receive the value of that parent calculated field, but It also doesn't seem possible, is it?
Could you suggest a simple way of doing this, would be good not to resort to writing scripts on before print or something. If there is no other way, what should the script be?
Thank you in advance.
Hi Taras,
I see that you set the "Report Server" Product for this ticket. In any case, from your question it looks like you are talking about a regular ASP.NET reporting application. So, would you please clarify whether you use our Report Server product or not?
Also please clarify if you have tried to use the approach described in the Master-Detail Report help topic to create the desired structure? We look forward to hearing from you.
Hi Vasily,
It is about ASP.NET reporting - ASP.NET web report designer and viewer, I wasn't sure what to select because you have MVC Dashboards in Business Intelligence category, I thought it should be in that category as well.
I've looked through the article you wrote about. We are currently trying to do this using details report band to display child collection items - in this case we don't know how to filter that details band report based on parent property
As for the subreport control - parameter binding there could work, but we need to specify Report Source URL, which we don't have since it is all one report, and even if we split it in two, our reports are stored in database, so I have no Idea how this approach can work.
What exactly would you suggest to do?
Hi Taras,
Thank you for the clarification. Let me comment on some of your statements:
>>We are currently trying to do this using details report band to display child collection items
Do I understand it correctly that we're talking about the Object Binding approach here? If so, any collection property exposed at the level of your 'Parent' business object will be treated as a master-detail relationship. To construct such a master-detail report, you may proceed with using XRSubreports as Vasily suggested above, but regular DetailReportBands should do just fine, too.
>>I also tried adding calculated field to each child item that would receive the value of that parent calculated field, but It also doesn't seem possible, is it?
You're right, there is no such a CalcultedField Expression that would allow you to receive this value - not unless your 'Child' object "knows" about its 'Parent'.
>> in this case we don't know how to filter that details band report based on parent property
>> would be good not to resort to writing scripts on before print or something. If there is no other way, what should the script be?
I understand your intention not to use report scripts (or any custom code in general), but yet I don't see a possible way of doing that otherwise. So, what you need to do is to subscribe to the DetailReportBand's BeforePrint script (or a regular event) and get the 'Parent' object of the root report by calling the XtraReport.GetCurrentColumnValue method. The rest is rather straightforward - construct a valid filter expression value for your embedded child report (DetailReportBand.FilterString) that will involve this obtained value.
P.S. Note that by default, all scripts are disabled in the Web Report Designer: see Scripting Security for more details.
Hi Yaroslav,
Thank you for the response. Yes, we are binding to object data source. XRSubreports approach probably will not work for us, since we have our custom logic to store and load reports and generating datasource for them dynamically
As for your suggestion about using scripts - can you provide more details and some code? Can I access calculated property of a parent object? If I can, how can I use it to filter child collection? I assume I would need to have a property on a child object that would receive value from calculated field of the parent. I don't really see the way to do that. Can you provide more details please?
I also had idea to add a calculated field to the child e ntity and use a script to get its value, can parent object (namely it's calculated field) be accessed in that script?
Another idea is to add another parameter to report, and somehow in script calculate it's value based on the first parameter, is it possible? If yes, how exactly?
Thank you.
>> XRSubreports approach probably will not work for us, since we have our custom logic to store and load reports and generating datasource for them dynamically
This might be true, Taras, but nevertheless, take a look at our custom report storage concept that was specially designed as a centralized report storage for all documents being produced. In any case, let's for a moment concentrate on the DetailReportBand class.
>>As for your suggestion about using scripts - can you provide more details and some code?
First, I'd like to clarify that "scripts" are just regular C# or VB.NET code that we compile at runtime during the report execution. Therefore, anything you can do in regular event handlers you can do in report scripts. See Scripts Overview for more.
>>Can I access calculated property of a parent object?
Any bound field value, including calculated fields, can be obtained by calling the GetCurrentColumnValue method of the target report (either the root XtraReport or its child DetailReportBands). For example, you may call this method from the DetailReportBand.BeforePrint script(event) handler, and this will give you the parent object of the current child section which is about to be printed. So, right here, you get to call some data storage methods you may have. Let's say you're working with Entity Framework:
private void DetailReport_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) { DetailReportBand drb = (DetailReportBand)sender; int categoryID = Convert.ToInt32(GetCurrentColumnValue("CategoryID")); DBContext context = new DbContext(); ObjectDataSource ods = (drb.DataSource) as ObjectDataSource; var products = from c in context.Products where c.CategoryID == categoryID select c; ods.DataSource = products.ToList<Products>(); }
Alternatively, you may load this child collection all at ones and then filter it out using a report parameter:
DetailReportBand.FilterString = "[ACCOUNT_ID] = ?paramCategoryID".
Of course, in order for this code to be effective, we need to change this parameter value each time the detail section is about to be printed:
private void DetailReport_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) { DetailReportBand drb = (DetailReportBand)sender; this.Parameters["paramCategoryID"].Value = Convert.ToInt32(GetCurrentColumnValue("CategoryID")); }
Here is an example that illustrates a similar technique with an ADO.NET DataSet: How to implement a master-detail report using Subreports (XRSubreport) without parameter bindings
Let me know if my explanation clarifies the situation.