SSRS Drilling through on dependent grouped parameters - reporting-services

I have been asked to add a group to a drill-through report depending on the parent report's multi-value parameter called Projects.
This group works perfectly on the parent chart however when drilling through into the child other parameters dependent on Projects are not being selected despite appearing in the list.
For instance the project parameter controls the available options for another multi-select Team parameter. When multiple projects are selected you can run the report across multiple teams, when selecting a single project from the grouped report this limits the team filter in the child, despite some of the original parameters from the main report being available in the child none are selected.
When passing the parameters to the drill-through report can I produce a sublist from the parent Team parameter filtered on the grouped Project parameter?
Pseudo-LINQ example:
=Parameters!TeamIds.Where(t => t.ProjectId == Fields!ProjectId.Value)
Alternatively is there any way to pass through the full list of teams to the child report and for the report to select the teams that match the selected project?
Edit
Available values for the Project parameter in both parent and child reports:
select id, header from projects
Available values for the Team parameter in both parent and child reports:
select t.id, t.header from teams t where t.ProjectId = #ProjectId
When running the report we display a lot of data in grouped grids with actions to run another report.
This Drillthrough passes the full list of teams. This stops the child report because some of the teams passed in are not valid values. Then the child report does not automatically run and forces the user to reselect the team.
Despite the Drillthrough implicitly setting the team from the main parameter.
I believe this is breaking due to the child report not being able to handle the multiple team projects originally selected in the main report.
My question is how do I:
a) Filter the team parameter to only include the project I have selected to drillthrough
or
b) Make the child report accept the full list of teams passed into it and only select the appropriate ones from the new filtered team list based on the single Project
Edit 2
Public Function GetTeamsForProject(ByVal ItemWithProjectInHeader as Parameter, ByVal ProjectHeader as String) as Collection
Dim s as new Collection
For i as integer = 0 to ItemWithProjectInHeader.Count-1
if ItemWithProjectInHeader.Label(i).Contains(ProjectHeader)
s.Add(ItemWithProjectInHeader.Value(i))
End If
Next
Return s
End Function
Started trying to put together some code to cherry pick the teams but I can't seem to get the collection return to work, for now i am calling it like
=Code.GetTeamsForProject(Parameters!TeamIds,CSTR(Parameters!ProjectId.Label(0)))
This just returns #Error in the text box i am using.
Hopefully someone could at least spot the 'deliberate' mistake on this.
Thanks
Edit 3
I am also trying something like this
Public Function GetItemsForProject(ByVal ItemWithProjectInHeader as Parameter, ByVal ProjectHeader as String) as Collection
Dim s as new Collection
For i as integer = 0 to ItemWithProjectInHeader.Count-1
if INSTR(1,ItemWithProjectInHeader.Label(i), ProjectHeader,1) > 0
s.Add(ItemWithProjectInHeader.Value(i))
End If
Next
Return s
End Function
and calling it like...
=Code.GetItemsForProject(Parameters!TeamIds,Fields!ProjectId.Value)

As you suggest, It looks like the core problem is that a parameter is being passed into the child report that the child report considers invalid.
Seems like two directions to solve this: one, Filter down what you send pass as the parameter value from the parent, or two, allow all the values that are coming in. Not knowing the structure of the report it seems like the second of these is easier. If you accepted extra teams into the child report will it cause the report to display incorrect values?
That is, if you change the possible values for the Team parameter in the child report to:
select t.id, t.header from teams t
That would certainly limit the usefulness of the child report when used directly, but do users go straight to the child report?
Another option would be to create two parameters in the child report. PassthroughTeams would be a hidden parameter that is passed in by the parent.
Teams would stay as it is, but have some default value (maybe all possible teams)
Then change the core data query of the child report to something like:
SELECT mydata.*
FROM mydata
WHERE mydata.teamId IN (#TeamIds)
AND mydata.teamId IN (#PassthroughTeams)

Finally got a working solution, I added the Project header to the team parameter so that I can use the team's label in the pass through.
Some problems with the original code:
Missing the 'Then' from the ifs
Potential that the instr or contains were missing references so moved to using the startsWith function
Public Function startsWith(str As String, prefix As String) As Boolean
startsWith = Left(str, Len(prefix)) = prefix
End Function
Public Function GetItemsForProject(ByVal ItemWithProjectInHeader as Parameter, ByVal ProjectHeader as String) as Collection
Dim s as new Collection
If ItemWithProjectInHeader.IsMultiValue Then
For i as integer = 0 to ItemWithProjectInHeader.Count-1
If startsWith(ItemWithProjectInHeader.Label(i), ProjectHeader) Or startsWith(ItemWithProjectInHeader.Label(i), "(Not") Then
s.Add(ItemWithProjectInHeader.Value(i))
End If
Next
Else
If startsWith(ItemWithProjectInHeader.Label(0), ProjectHeader) Then
s.Add(ItemWithProjectInHeader.Value(0))
End If
End If
Return s
End Function

Related

SSRS report pass multiple VALUES to drill through report parameter

I created a report with 5 fields in a hierarchical order:
Order Date
Time of Day (AM/PM)
Parent Name (aka customer)
Product Line
BIC Part Number (aka Item)
Each field expands down to the next level, so order date expands to time of day, etc.
I want to create a drill through report so that the user can click on each level of the hierarchy and see the detail.
This works fine at the lowest level - Item - because only 1 values from each field has to be passed to the drill through report parameter. However, when I try, for example, to drill through based on Product Line, there will usually be 3 or 4 Items within this product line. In the Go To action, I have the drill through parameter "bic_part" set to the main report FIELD value "BIC Part Number".
I have the tablix on the drill through report set where "BIC Part Number" IN [#bic_part].
I just want to be clear, I am passing a set of report field values to the drill through report parameter, not parameter to parameter.
I have tried using expressions with =Split(Join(field value),","),",") and all variations on that. I can't seem to get the child report filters to accept multiple values from the BIC Part Number field from the parent report.
I also tried omitting the BIC Part Number value in the go to report section, but it would not let me.
All of the parameters in the child report are set to accept multiple values. My data source for both reports is the same stored proc, so I can add a query filter. I would appreciate any help.
I think each sub report link needs to be slightly different.
In the subreport, each parameter needs to accept null and your query needs to look for
(FieldName = #FieldNameParameter or #FieldNameParameter is null)
This will allow you to pass the lowest possible solid value, then null for all child values.
If we're looking at the Parent_Number level, on that subreport link you would pass Fields!Parent_Number.Value and then Nothing for each of the lower parameters (Product_Line, BIC_Part_Number).
This will allow you to filter on the lower common denominator in your sub report - Part_Number for this link, Product_Line for the next one down, etc.
I've used this logic in reports before, so it does work. Let me know if my explanation needs clarification - it's Friday afternoon..

passing multi valued parameter to sub report in SSRS

I have built a report which lists all the loans that are available for a specified date range(below is the screen shot of the report).There are a number of filters and data logic involved in pulling this report.The numbers high-lighted in yellow are the total no of loans in each bucket.When the user clicks on the totals I need to open a sub report with all loans falling in that bucket.I have created a sub report which accepts loan numbers as a parameter and set it to allow multiple values. Set the text box properties on the main report to go to the subreport when clicked on the totals.But I am unaware of how to pass multiple loan numbers from the main report to sub report.
Any help would be much appreciated.
What I am currently doing is passing required filters/details to the sub report , so that it can reevaluate. Reevaluating the report takes a lot of of time as there are many condition that need to be evaluated. It would be quicker if I could send the list of loan numbers.
Rather than pass a list, you'll need to pass in enough detail so your subreport can reevaluate and come back with the same set of loans.
This might be a little simplistic but base on your screen show you would pass in the Date Range column value. I'll assume for now (as I have no more information on your data) that the column is just a text column as it appears above.
So you sub-report would accept a daterange parameter and you would pass this as =Fields!DateRange.Value. The subreport would then do something like..
SELECT * FROM myLoansTable WHERE DateRange = #daterange
If there are more parameters set in the main report, you may need to pass those too so your subreport gives the same set of loans as displayed in the main report.
Hope that makes sense.

SSRS Pull Variables Or Values From Sub Report Into Main Report

I have a main report with several sub reports, each of these with slightly different queries and different ways to show the data.
So, in my situation, I have a textbox that needs to compile data from a few different reports with varying criteria. E.G.
MainReportTextbox =(Sum(columnA, "Main Dataset"))-(SubReportTextBox))
OR
MainReportTextbox =(Sum(columnA, "Main Dataset"))-(subReportVariable))
I saw a few suggested solutions, such as this. Which uses the =[Reports]!MainReport!SubReport!Textbox scheme. The problem is that [Reports] is not a recognized identifier.
I did consider to scrap sub reports and just have everything run on the same main report, but we lose the functionality of being able to use the reports individually, without maintaining the same thing in two places.
So I guess my question is, can you pull variables or element(particularly textboxes in a table) values from sub reports?
If the answer is simply no, please show me some information about why it is no or how it is no from MSDN or a valid source and give some valid counter suggestions.
The links in the question and comments sometimes refer to non-SSRS reports: the syntax [subreport].[Report]![MyFieldName] or [Reports]![YourReportName]![YourSubReportName]![TheValueFromTheSubReportYouWantToReference] are not used in SSRS. It is, however, used in designing MS Access reports, as ojeffrey points out in the discussion you link to.
There is no common method to access data in a subreport. The SSRS model is that parent report data is processed, subreport data is processed, the subreports are rendered, results go back to the parent, then parent is rendered, including the subreport as appropriate. The only data passed between the two is parameters are passed into the the subreport, and rendered output is passed back to the parent. You'll see the that data passed in from the parent must be as report parameters here: http://technet.microsoft.com/en-us/library/ms160348(v=sql.100).aspx
All parameters that are required by the subreport must be included in
the Parameters list. If a required parameter is missing, the subreport
is not displayed correctly in the main report.
For citing authoritative sources:
This discussion sums it up:
No, referring to a report item in a subreport is not allowed.
But that is a bit old, there is also this more recent discussion of work-arounds, provided by Microsoft employee and a MS BI MVP:
You are going to need to replace the subreport item with a data region
like list, table, or matrix to be able to get the proper reference you
are looking for.
[Skipping down to another post]...
Now, it seems you want to calculate the
difference between main report and the subreport. Also, because they
have the different data source, so you cannot use nest
table/matrix/list, right? If so, one workaround I can think of is
pass parameter to the sub report and calculate the total/subtotal in
sub report. I mean, create several hidden/ internal parameters, pass
the values from main report to sub report through parameters and then
calculate the total/subtotal there.
Jeroen's answer to the linked question point towards the direction I would go: use a "Shared Dataset" and enable caching if the dataset is slow to execute. The same dataset execution can then be used for the parent and subreports. This can change the use of parameters: they usually get moved from the SQL query to the filter of the Dataset in the report.
But with the Lookup function introduced in SSRS 2008R2, you can get very flexible with report level joins between datasets.
The details of how I'd design this depend a lot on how much other data needs to get passed back and forth, and how neatly the queries for the reports can be knit together.
Create variable in main report and update it in sub report so you can get value back to main report
ex:
Create formula in main report with name {#Total} place flowing in it
WhilePrintingRecords;
shared Numbervar myTotal := 0;
NOTE : placing ; will not print value and without ; will print value in above example value will not be printed if you want to print value of formula just remove ; from second line ex
WhilePrintingRecords;
shared Numbervar myTotal := 0
now place {#Total} in report header of your main report
now create second formula in sub report where you want to add subtotal to main report formula with name {#addTotal} place following lines in it
WhilePrintingRecords;
shared Numbervar myTotal;
myTotal := myTotal + 200; //or any formula or field
add this formula to place in sub report where you want to add value to total
now create formula in main report to show grand total with name {#showTotal} and place following lines in it
WhilePrintingRecords;
shared Numbervar myTotal;
myTotal
place {#showTotal} in your main report where you want to show this value in report but remember one thing you should place this formula after sub-report.
NOTE : to assign value to variable use := operator

Custom tablix filters in SSRS

I have a report which displays a table full of raw data.
Prior to entering this report, the parent report asks you to select a 'Service' & 'Department'
Depending on which Service/Department you select from the parent report, this RAW data will be filtered to show the relating data.
Straight forward enough, and it works, great.
I have a new requirement now.
If the chosen Service is equal to 'Service X' I need the data to be filtered again on that Service, department, but also to add aditional filter, on their 'team'.
so that the data will also be filtered where the team matches the user running the report's team.
I have a dataset already created which returns the user running the reports 'team'
And also a new parameter called 'team' which defaults to the user running the reports AD number'
The new requirement is, if the Service = X, then filter the data on the department but also on THAT users 'team', if the Service is not equal to X, do nothing.
I think I need to alter the Filters section of the Tablix Properties but am not sure what I need to put in the Expression, Operator, Value
So far I have tried =IIf(Fields!Service.Value = "Service X", Fields!Team.Value, nothing) in the Expression, set the Operator to In and tried filtering on the 'team' from my new dataset which stores the current users 'team' but it is not working.
Does anyone have any suggestions?
For these sorts of conditional filters I've had best results with using the IIf statement (or whatever) to return a string and filtering based on that, e.g. something like:
=IIf(Parameters!Service.Value <> "Service X" or Parameters!Team.Value = Fields!Team.Value
, "Include"
, "Exclude")
Then you can set the Operator to = and the filter value to Include. Just seems to a bit more robust in my experience.
Reading over this, you could even set the IIf statement up as a Calculated Column in the dataset and filter on that.

How to loop rows of dataset in Reporting services rdl custom code

How can I loop through the rows of a dataset in the custom code?
I have a report containing a dataset. I pass the dataset as a parameter to the custom code function. But what then? Where is a reference about the available members etc.?
Here is my dummy sample code so far:
Public Function ShowParameterValues(ByVal ds as DataSet) as object()
Dim codes() As Object
Array.Resize(codes,dc.???.Count)
codes(0)=ds??(field???)(row??)
return codes
End Function
Please note: this will be a very simple script (if it'll work), so I don't want to go into custom assemblies etc.
I think you got your answer at:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/a7d59224-0ee5-491e-883b-2e5fcb3edeab/iterate-through-rows-of-dataset-in-reports-custom-code?forum=sqlreportingservices
There were two important pieces of information I was able to grasp from the above link:
First, A dataset in Reporting Services is not the same type of object as an ADO.Net dataset. A report dataset is an internal object managed by the SSRS runtime (it's actually derived from a DataReader object) and not an XML structure containing datatables, etc. and cannot be passed into the report's custom code.
Second, There was a solution posted as to how one can Iterate through rows of dataset in report's custom code by "transforming" the data set into a multivalued parameter (or if several fields are needed, transforming it in multiple multivalued parameters):
The multivalued Report Parameter must have the following characteristics:
Hidden = True, Allow Multiple Values = True
Available Values tab: Choose the desired dataset. Select the searchable id as Value id, and the field you want to expose as Label Field.
Default Values Tab: Get Values from a Query.
Choose the same Dataset as choosen in the available Values Tab.
Value Field the same you choose for value id.
Set the parameter to never refresh (or it will be loading the data from each iteraction of another parameter).
Now, the idea is make this Parameter "searchable". From this point you exposed the Dataset as an array in the Multi valued Parameter.
Now in a custom code insert the following code:
function GetDataSetLabelFromValue( id as integer) as String
dim i as integer
i = 0
for i = 1 to Report.Parameters!YourParameter.Count()
if Report.Parameters!YourParameter.Value(i) = id then
GetDataSetLabelFromValue = Report.YourParameter!ReportParameter1.Label(i)
Exit For
End if
next i
End Function
Were you able to do what you wanted?