Custom tablix filters in SSRS - sql-server-2008

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.

Related

SSRS Report -> Filtering dataset with parameter

I have a dataset which populates multi-choice dropdown. Lets call it "Company Chooser"
Since there are a lot of Companies I would like to add a parameter that would filter my Company Chooser.
I've added a parameter to report (with default value)
I've added Filter to my data set.
And I am getting an error
Is there something wrong with my approach or did I forget to add something that I should have ?
Second question would be - is there a way to set filter to something like "startswith"
Ps. Due to specification of project I can't filter thru query

SSRS Parameter select All with SSAS connection

I have a dimension in my SSAS model called Customer, I added the parameter to the report for "CustomerNumber", however, I don't want to have a drop down list of customer numbers (Over 5000 customers), So i set the available values to none and default values to none. and set the following into the Parameter Expression of the Dataset:
=IIF(Parameters!CustomerCustomerNumber.Value = "%",
"[Customer].[CustomerNumber].[All]",
"[Customer].[CustomerNumber].&[" &
Parameters!CustomerCustomerNumber.Value & "]")
So what I'm trying to achieve is either enter a single customer number into the parameter text box and receive all records for that customer from the dataset or if you want all customers data just enter %.
My expression above works when entering a customer number but it doesn't when I select all. I suspect the [All] doesn't work how I think. It shouldn't be too hard to do what I have mentioned. Will browse around for answers and post them up.
Cheers
Try this instead .All
[Customer].[CustomerNumber].ALLMEMBERS
If I understand correctly, .Allmembers gets the invidiviual members within the hierarchy whereas .All points to the collection.

Dynamic groupings using IIF with multiple datasources

I'm using report viewer and trying to create dynamic groupings on my table. Before the report is generated, I have a popup that ask if the report generated should be grouped by category or not.
I have two datasets, one called ReportParameterDTO and the second is called LoanDTO
The tablix is connected to the dataset LoanDTO. I want to create a parent grouping expression for that tablix such that if the first value of ReportParameterDTO.GroupByCategory is true, then it should group, otherwise do nothing.
What I tried
=IIF(First(Fields!GroupByCategory.Value, "ReportParameterDTO") = true, Fields!Category.Value, ""))
It gives me back and error around Fields!GroupByCategory.Value and the error within the error list states that A group expression for tablix includes an aggregate function.
The IIF Expression will compile if I use Field Values from LoanDTO but I don't want to do that.
Add a new parameter.
Set it to Internal.
Set the Available Values to pull from the ReportParameterDTO dataset and the Value field will be GroupByCategory.
Also set the Default Values to pull from the ReportParameterDTO query.
Now you can refer to this internal parameter in your grouping expression like so:
=IIf(Parameters!GroupByCategory.Value = True, Fields!Category.Value, Nothing)
You can create both table and whit your parameter show or hide the table visibility. So like this I think is going to be more easy for you to set up your table and groups.

Using "All" as a choice to get all the records from database in Crystal Report

My requirement is to provide All as a parameter in Crystal Report. And when user select All all record should get displayed without any filtering.
There are many solution available like:
If {parameter} = "All" then True else Table.Column = {parameter}
This works fine for a single parameter with All as an option.
But in my case I have multiple parameters and for each parameter I want to give All as an option and in that case using the above solution doesn't help.
Say for e.g. There are 3 params and I have used above solution with and clause.
While running user select All for two params and a value for 3rd param still all the records are displaying no filtering is happening.

Reporting Services Cscading Parameter refresh

I have googled it a lot and found that usually it cannot be done. I came across one of the hacks here:
http://www.bp-msbi.com/2011/04/ssrs-cascading-parameters-refresh-solved/
But its not working for me in ssrs 2005. Just wondering if anyone else tried it in 2005.
Or is there any other hacks that can be tried.
As per this article the dependent parameter gets refreshed only when its values are invalidated by the selection in the first parameter. If we can invalidate the dependent parameter every time a parameter changes we will enforce a complete refresh. An easy way to do this is to attach a value such as a GUID obtained with the NEWID() T-SQL function.
So basically we want to introduce a fake parameter in between two real parameters. This fake parameter is supposed to return new values everytime as the storedproc behind it will add a guid to the resultset everytime that proc is called. So it forces complete refresh of the other parameters.
Now the main issue I am facing is :
Setting the default value of this fake parameter.
For the available values the storedproc behind the fake param runs and it returns data in the format say : result1,result2_GUIDFROMSQL
Now it looks like the same storedproc is called again to set the defult value if i ask it to get the default value from query. But as the storedproc is run again new guid comes and so the old value cannot be found so its not being set as desired.
I just need to figure out a mechanism to pass this guid from introduced param to the next param.
Thats where I am failing.
My issue can simply be replicated by creating a param whose datasource is this querystring.
select getdate() id, #name nid
So in this case how to set a default value for this param.
Below I'm going to present a detailed scenario and then I'll show the example implementation based on Visser and Abbi's answers.
Imagine that I have a report where each row is a project. A project has a Status column with values "In Progress" or "Complete" and a Project Manager column whose values are a person's name. Here are the rows in the table:
Project A (Status = In Progress, Project Manager = Bob)
Project B (Status = In Progress, Project Manager = Tom)
Project C (Status = Complete, Project Manager = Jack)
Project D (Status = Complete, Project Manager = Tom)
Project E (Status = Complete, Project Manager = Jill)
I want to have 2 parameters on my report
Show Completed Projects? - This is a boolean parameter
When false will only show "In Progress" projects A & B
When true will show "In Progress" projects A & B in addition to "Complete" projects C, D, & E.
Project Manager - This is a multi-value text parameter whose options and default values will need to change based on the Show Completed Projects? parameter upon which it is dependent.
If Show Completed Projects? is set to false then only "Bob" and "Tom" options will show up because they are the project managers for the in progress projects Project A & B respectively.
If Show Completed Projects? is set to true then in addition to "Bob" and "Tom" you will also have "Jack" and "Jill" show up as options because they are project managers for the inactive projects Project C & Project E respectively.
Now for the implementation:
Show Completed Projects? parameter
Project Managers dataset query (See Visser and Abbi's answers for details on how this generates a key that will change based on the independent parameter and will force SSRS to reload the default values)
SELECT
[ProjectManager_Key] =
pOuterAlias.[ProjectManager_Key] + '_' +
CAST(ROW_NUMBER() OVER(ORDER BY pOuterAlias.[ProjectManager_Key] DESC) AS NVARCHAR(MAX)),
[ProjectManager] = pOuterAlias.[ProjectManager]
FROM
(
SELECT
[ProjectManager_Key] =
pInnerAlias.ProjectManager + '_' +
CAST(ROW_NUMBER() OVER(ORDER BY pInnerAlias.ProjectManager ASC) AS NVARCHAR(MAX)),
[ProjectManager] = pInnerAlias.ProjectManager
FROM
(
SELECT
[ProjectManager]
FROM
[dbo].[Project]
WHERE
Status = 'In Progress' OR
#ShowCompletedProjects = 1
) pInnerAlias
) pOuterAlias
ORDER BY
pOuterAlias.[ProjectManager]
Project Manager parameter
General
Available Values
Default Values
Projects dataset
Query
SELECT
*
FROM
[dbo].[Project]
WHERE
(
Status = 'In Progress' OR
#ShowCompletedProjects = 1
) AND
Project Manager IN (#ProjectManager)
Parameters (Make sure to note the [#ProjectManager.Label] portion which will make it match the project on the actual project manager value from the database and not the key that we generated.
Finally I was able to resolve this. This link was a helpful start.
http://www.optimusbi.com/2012/07/16/multilevel-cascading-select/
Basically what it does is : Writing parameter query in a manner so that the dependent parameter changes its value every time you change its parent parameter.
The query adds rownumber with a "_" preceeding it. So every time user selects other values the rownumber changes and hence the query resultset.
Then when using the resultset remove the text after the underscore to get the real codes.
There is a workaround to fix this issue for all situations.
Note that the previous answer provided, writing parameter the query in a manner so that the dependent parameter changes its value every time you change its parent parameter, works for some cases but not all cases. If the dependent parameter's "Available" values change as a result of another parameter AND the dependent parameter is visible, it works, If the dependent parameter is hidden or internal, or if the "Available" values do not change as a result of the other parameter, it will not work.
The foolproof workaround is to define a custom function in the report and call it in an expression for the dependent parameter. The custom function takes the parameter's (the parameter that the dependent parameter depends upon) value as an argument, and simply returns its value. Even though function is simply taking the value and returning it, SSRS does not inspect the code and assumes that the code could do anything (generate a random number, pull files from disk, etc ...). So SSRS calls the function every single time the value changes regardless of whether the dependent parameter's "Available" values change, and regardless of whether the dependent parameter is visible, hidden, or internal.
Something like this:
public function returnArg(ByVal TheArg As String) As String
return TheArg
end function
Assume you have two parameters:
Parameter1
Parameter2
And that Parameter2 depends upon Parameter1.
Set Parameter2's value as an expression that includes the call to Parameter1 with the function, like:
=CODE.returnArg(Parameters!Parameter1.Value)
Now in this case Parameter2 simply displays the value in Parameter1, but this logic can be extended to more complex expressions and more than one parameter. As long as there is a CODE.returnArg(...) function call for each parameter in the expression, SSRS will always refresh the value.
#Abbi's second link is no longer valid. The article can now be found at:
http://www.optimusinfo.com/multilevel-cascading-select/
Unfortunately the images are broken and the article is a little incomplete without them. There is one image I was able to locate in its moved location (I could not find the others even with trying appropriate variations): http://www.optimusinfo.com/wp-content/uploads/2012/07/Multilevel-Cascading-with-Select-All-18.jpeg
This gave me the last clue I needed to get the technique working: when you're setting up the dataset parameter properties, you need to manually specify the parameter value as e.g. [#City.Label] rather than the usual plain old [#City] (which corresponds to [#City.Value].
This is because the technique alters the "Value" to a custom value which can no longer be looked up in the DB! So you need to use the user-friendly, db-existing "Label" as the parameter. (Probably should be obvious but...) The rest is all pretty standard if you understand report builder.
Also note that this link as it stands doesn't work with multi value cascading parameters. However it can easily be modified to do so: just alter the parameter stored procs to join to a value splitting function. I adapted mine from the udf_splitvarible function given at SQL Server - In clause with a declared variable
The modification is fairly simple but I'll give an example. This is from the article (with terrible formatting fixed).
SELECT
l11.CompanyName1+'_'+ CAST(row_number() over( order by l11.CompanyName1 desc) AS VARCHAR(50) )as CompanyName11
,l11.CompanyName
FROM
(
SELECT
l1.CompanyName+'_'+ CAST(row_number() over( order by l1.CompanyName asc) AS VARCHAR(50) )as CompanyName1
,l1.CompanyName
FROM
(
SELECT DISTINCT CompanyName
FROM Customers
WHERE City IN(#City)
)l1
)l11
ORDER BY l11.CompanyName ASC
Change:
SELECT DISTINCT CompanyName
FROM Customers
WHERE City IN(#City)
to:
SELECT DISTINCT CompanyName
FROM Customers
INNER JOIN udf_SplitVariable(#City,',') v ON City = v.Value
This all applies to SQL Server 2008/Report Builder 3 also.
I wasn't able to understand/apply #borkmark's answer. The limitations don't seem to apply to my case.