SSRS Making a filter optional - reporting-services

I've got a report I am moving to SSRS from another reporting system. It has a multi-select filter that the user can select one or more branches to filter the report by. However, the branches presented to the user are limited to currently active branches. The existing report had a second boolean parameter to fetch every branch - including inactive branches (which are not shown in the multi-select list).
Ideally, I would use an OR filter -- which SSRS strangely doesn't support.
Alternately, I tried to use a function in the filter as follows:
Created a dataset AllBranches with a list of all branches
Parameters used: Parameters!GetAllBranches = boolean and Parameters!Branch = user selected branches
Attempted filter: BRANCH in fx where fx = IIF(true= Parameters!GetAllBranches.Value, return the list from the AllBranches query, Parameters!Branch.Value)
I was unable to figure out how to return the list from the AllBranches query to make this strategy work.
How can I filter my data so that logically it returns every row were BRANCH in Parameters!Branch.Value -OR- user has set Parameters!GetAllBranches = true?

Related

SSRS Drilling through on dependent grouped parameters

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

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..

How to create a custom SSRS user warning?

I have a report that can be VERY expansive - potentially returning hundreds of thousands of rows and taking 15+ minutes to render. The users have four inputs including two dates indicating the report range and two filters that default to (All). What I'd like to do is throw up a warning to the user if they try to run the report without selecting a single entity from either of the two filters, or if the user attempts to bring up more than one week's worth of data at a time.
Is there any kind of checking I can do at runtime in the report (short of coding it in the procedure) to warn the user that they are about to get more data than they can handle?
I would add a Hidden Parameter e.g. Accept_Run_Time_Warnings, with Static values e.g. Yes or No. The Default value would be set by an expression, based on the prior Parameters and your criteria e.g. entities selected, date ranges etc. If those conditions are met, Default = No, otherwise Default = Yes.
Then I would add a textbox to the top of the report body with the warning text to show the users, finishing with something like "Click here to continue with these parameters". This textbox would be hidden if Accept_Run_Time_Warnings = Yes. This textbox would have an Action to run the same report, passing the same paramters, but with the Accept_Run_Time_Warnings = Yes.
I would hide all other report body tables charts etc if Accept_Run_Time_Warnings = No.
I would edit the parameters for the main datasets to test Accept_Run_Time_Warnings - if No then they can pass non-existent values (to speed the dataset execution), e.g.
=Iif ( Parameters!Accept_Run_Time_Warnings.Value = "No" , "DUMMMY" , Parameters!Customer.Value)
Thanks for the ideas. We decided instead to break the report into two reports and removed the "All" option from either one of the two selection drop-downs on each report. The titles on the individual reports give a clue to the user about which one to use and clue them into the need for a selection.

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.

SSRS: How to add All option to SSRS dropdown filter?

I'm using SQL Server Reporting Services for SQL 2008 R2. My reports are filtered by two drop-down menus that are populated from a table, one of them displays a build number. I'd like to give users the option to choose "All" and so return data for all build numbers and not just one.
How do I add this option to my drop-down filter and make it work correctly?
Thanks very much for any help provided.
J.
I'm assuming you don't want to use a multi-value parameter here, you only want users to run against all builds or just one, not a selection of builds. Otherwise you'd just use a standard multi-value parameter.
One way to do this is to return an extra row for all builds in your parameter dataset, e.g. something like:
select buildId as null, build = 'All'
union all
select buildId = build, build
from builds
I'm returning two columns here so we can pass a NULL value parameter but still have a user-friendly description to display in the report.
Set this up as your parameter dataset. In the report code you can then use the parameter to do something like:
select *
from builds
where (#build is null or #build = build)
Which will return all builds when #build is null and a specified build if #build is not null.
Would it be correct to simply change the where clause in the stored procedure to
Where [field] LIKE #variable
Then in SSRS under the Available Values have the "ALL" parameter value be % (the percent symbol) ?
Is there an error in logic here. It seems to have the desired result