This post explains a method of enhancing Reporting Services reports to make them more user friendly. I have been quizzed many times by end users who want reports to remember the parameter selections so that next time they run the report they haven’t got to re-select the same parameters. This is especially useful if there are a lot of long parameter lists, and each user tends to run the same selection frequently.
This process is made possible by the User!UserID global variable within SSRS. It contains the domain and username of the user running the report (DOMAIN\USER).
There are a number of stages required to get this to work :-
– New SQL table to store users’ selections
– New stored procedures to save and load selections
– Two new datasets within the report
Firstly create a database table to store the selections
CREATE TABLE tblUserSetting( ID int IDENTITY(1,1) NOT NULL, UserID varchar(100) NULL, Report varchar(100) NULL, Setting varchar(100) NULL, Val varchar(max) NULL )
Then add a couple of stored procedures, one to save the default and one to retrieve it.
CREATE PROC spu_SetUserSetting ( @UserID varchar(100), @Report varchar(100), @Setting varchar(100), @Value varchar(max) ) AS BEGIN --Firstly delete any old settings for this parameter DELETE FROM tblUserSetting WHERE UserID=@UserID AND Report=@Report AND Setting=@Setting --Now add the new setting INSERT INTO tblUserSetting (UserID, Report, Setting, Val) VALUES (@UserID, @Report, @Setting, @Value) --Return the new setting SELECT @Value AS Val END CREATE PROC spr_GetUserSetting ( @UserID varchar(100), @Report varchar(100), @Setting varchar(100), @Default varchar(max)=NULL ) AS BEGIN DECLARE @Val varchar(max) SET @Val = ISNULL((SELECT Val FROM tblUserSetting WHERE UserID=@UserID AND Report=@Report AND Setting=@Setting ),ISNULL(@Default,'')) SELECT @Val AS Val END
Now on to the report.
Lets say that we have a parameter called ‘TestParam’. The first thing we need to do is create a new dataset that will be used to retrieve the default value if one exists.
Name the new dataset dsTestParamDefault, the CommandType should be StoredProcedure, the query string should be spr_GetUserSetting.
Edit the Dataset and select the parameters tab. SSRS has already created report parameters for each of the proc’s parameters. We need to replace these with our own values.
@UserID =User!UserID @Report =Globals!ReportName @Setting ="TestParam" @Default =Nothing
(if you want to you can specify a default value here for when the user runs the report for the first time)
Set the default value of your TestParam parameter to be the Val field of the dsTestParamDefault dataset.
The parameter will now load the default from the appropriate database record for that user.
Now we need to add the ability to save the users selection for next time.
Create a new dataset named dsTestParamSave, the CommandType should be StoredProcedure, the query string should be spu_SetUserSetting.
Edit the Dataset and select the parameters tab. SSRS has already created report parameters for each of the proc’s parameters. Again, we need to replace these with our own values.
@UserID =User!UserID @Report =Globals!ReportName @Setting ="TestParam" @Value =Parameters!TestParam.Value
You will then need to delete the four report parameters SSRS created for you (UserID, Report, Setting and Default).
And that’s it! When the user first executes the report, it will ask them for the parameter value (or use the default if you specified one). However the next time they run it it will automatically remember what value they last used. As it is stored by username, it doesn’t matter whether they use the same PC or not.
The example above is for a simple single-valued parameter, however this technique can also be used for more complex parameters. The parameter could have a list of available values, and can even be multi-valued. If you want to use a multi-valued parameter, then you only need to make a couple of minor changes…
The spr_GetUserSetting will need changing to
BEGIN DECLARE @Val varchar(max) SET @Val = ISNULL((SELECT Val FROM tblUserSetting WHERE UserID=@UserID AND Report=@Report AND Setting=@Setting ),ISNULL(@Default,'')) SELECT Val FROM dbo.Split(',', @Val) END
For this to work you will need to find yourself a suitable Split function. (Search Google for ‘SQL Server Split’ to find hundreds that are suitable, or I’ve put one in the linked sample file)Then change the @Value parameter of the dsTestParamSave dataset to
This will store a comma delimited value containing all values selected. If you use commas in your data then choose a suitable alternative as a delimiter.
I have put some working examples of all of this in the link here along with copies of all relevant SQL script…
Hope this is of some use!
My preferred method is to wrap this up into a custom code function such as
Function OpenURL(ByVal URL As String) As String
In your report, you can then just set the navigation property to jump to a URL of a website:
Or to the path of a the drillthrough report:
If you have parameters that you need to pass in, you can add these into the URL either fixed or dynamic:
=Code.OpenURL(“http://[Your Server]/ReportServer?/Folder/ReportName&rs:Command=Render &MyFirstParam=Value1&MySecondParam=” & Fields!MyField.Value)
Please note that this will not work in the BIDS development environment, it will only work once you have deployed the report to the Report Server.
For any users of Analysis Services, if you haven’t already downloaded the Excel (2002/2003) addin you’re missing out.
It’s a free download from Microsoft which significantly expands Excel’s cube querying ability. Well recommended!
A number of our customers have reporting systems that use both MDX and SQL, retrieving data from both OLAP and SQL Server databases. This generates the problem of converting an MDX field ([Dimension].[Hierarchy].&[Attribute]) into SQL Server field value (Attribute). The following code is a Reporting Services custom code section that will rip off the MDX and leave you with the value.
Public Function MDXParamToSQL(Parameter As String, All As String) As String
Dim Val As String
Val = Parameter
If Val.Contains(“[“) Then
If Val.ToLower().Contains(“].[all]”) Then
Val = Val.Substring(1, Val.LastIndexOf(“]”) – 1)
Val = Val.Substring(Val.LastIndexOf(“[“) + 1)
Lets say that you have a report using an MDX dataset, if you want to call a drillthrough report based on SQL Server you will need to pass at least one attribute through as a parameter to filter the second report. If you add the code above to the custom code section, you can set the parameter value of the second report to
The second report will then just receive the member name, not the full MDX unique identifier.
It really wouldn’t be fair to kick off the Frog-Blog without a shout out to Chris Hays and his superb ‘Sleazy Hacks’ site. If you want to push SQL Server Reporting Services further than anyone else, then Chris will definately have something of use to you. He designed the RDL report language – the guy knows what he’s talking about.
Well, what can I say – the very first Frog-Blog post.
Keep checking back often for new and (hopefully) useful info…