Category Archives: SSRS Reporting

Tips and Tricks on SSRS

SSRS provide a lots of properties to update the report according to any vague requirement given by Clients. Multiple properties and all changeable is the best feature of SSRS and gives it edge over all new reporting tools.

Over the time developers can learn many ways of manipulating reports. Few cool tricks are listed in this post and can help in exploring more ways of making desired changes in SSRS reports.

1. How to get Total page number in ribbon above report?

SSRS doesn’t calculate total page number and shows on top ribbon like 1 of 2 ? for page numebrs. Instead of “?”  it should be final number of page like 11. “2” represents next page as SSRS do not calculate total number of pages.

We will need to ask SSRS to calculate Total Page Number explicitly. To do so;

Pick the “Built in FieldTotal Pages (shown as =Globals!TotalPages) and drag it on header or anywhere in report (hide it if not needed by visibility property).

As shown below:


Reports rendering will be like:

Before After
 2  3


2. Get the data refresh time of Cube (last processing time)

I have seen most of the legendary system uses extra SSAS cube to store value of last processing time of main SSAS Cube.

Use following query to get refresh time of any cube and keep it as a new dataset in report.

SELECT TOP 1 LAST_DATA_UPDATE FROM $system.mdschema_cubes
WHERE CUBE_CAPTION = 'Adventure_Works'

Save as dataset “dsLastUpdatetime”. And in report create a Text Box and keep expression as:

="Data Refresh Time:  " & First(Fields!LAST_DATA_UPDATE.Value, "dsLastUpdatetime") & " UTC"


3. Based on rendering/export format, change properties.

SSRS provides multiple rendering format or Export format. With a property Globals!RenderFormat.Name we can make sure how final output in desired format (excel/pdf/csv etc.) should appear.

For example in my report I show Selected parameter values on top on SSRS view. But if user download the file he/she wants only report data. So I change visibility of text Box (of parameter values) as following:

=IIF(Globals!RenderFormat.Name = "EXCEL", FALSE, TRUE)

And SSRS and Excel have different appearance as final report.


4. If you are not using Tooltip, you are not using SSRS properly

Option for Tooltip is everywhere. If you are not using it you are missing out a big feature. Users of SSRS mostly expect interactive reports though SSRS but its not as fun as other tools. At least tool tips add a one more attribute of reporting objects (like bar values in charts, description of column header etc.). Use it under Chart properties, Series properties, Text Box properties etc. to add more details in report.


5. Use SWITCH function for expressions instead of nested IIF.

Its easy and fast. Don’t forget to use TRUE as a default value. Example given below:

=SWITCH(Fields!RegionShort.Value = "N", "North",
Fields!RegionShort.Value = "S", "South",
Fields!RegionShort.Value = "E", "East",
Fields!RegionShort.Value = "W", "West",
TRUE, "Unknown")


6. Do not need datasets for Parameters all the time (even in MDX reports)

Mostly we rely on datasets values for Available values in property of Parameters. Its not mandatory. Imagine All and Female are two values of Parameter. In MDX dataset lot of stuff will be needed to avoid Male values.

Someone will create a dataset with except for Male option for same case. Or provide a filter on parameter to avoid Male option (with All member including). Simply, provide static values, just like below:



7. Create simple dynamic members on Parameters instead of dataset.

On extension to above, we can create dynamic members as per requirement just using same method.

For example, an Adventure Works report is needed where Parameter Product Category should have 3 values ALL, Actual_Products(comprising Bikes and Components) and By_Products(comprising Accessories and Clothing). Not values from cube.

So either you can use following MDX as dataset to fill the values:

MEMBER [Product].[Category].[Actual_Products] AS
MEMBER [Product].[Category].[By_Products] AS
{[Product].[Category].[Actual_Products], [Product].[Category].[By_Products],
[Product].[Category].[(All)]} on 1
FROM [Adventure Works]

Or simply just get the parameter Available values as following:

ALL =”[Product].[Category].[(All)]”
Actual Products =”{[Product].[Category].[Bikes],[Product].[Category].[Components]}”
By Products =”{[Product].[Category].[Accessories],[Product].[Category].[Clothing]}”

Update MDX in SSRS Auto-generated datasets

Whole objective of this post is to write better/proper/optimized MDX for SSRS Reports datasets. Small fix in our SSRS Dataset Queries in SSRS reports can optimize report as well as MDX in report. The reports which grows in complexity and data, can be really grateful for your effort on this.

Most of the times we use auto-generated MDX queries in SSRS Report datasets. But I suggest use it, with a better eye on it. It can be fixed for many better changes. I always create my own MDXs for report and if I get already created SSRS report to work on, I open dataset queries and do some tweaks to make it better.

  • 1. Remove NON EMPTY where you don’t want them.. Auto generated query keeps NON EMPTY in rows and columns of MDX, but it can cause trouble when columns get disappeared from report. Sometimes your report will fail if a measure is empty (no value) for dimensions ON COLUMNS in MDX. I would suggest remove both NON EMPTY to avoid any column getting missed due to lack of data and use NONEMPTY function to better the query.If you don’t follow me here please read about NON EMPTY in msdn to avoid report breaks in case of lesser data in cube.
  • 2. Shiny CELL PROPERTIES should be removed from auto generated MDX. You see those in the end of any dataset MDX and are meant for result viewers such as SQL Server.Sometimes these properties can be useful (mostly DIMENSION properties), when taken as members and appear in results as columns. You should delete properties which usually comes with the auto generated MDX and delete the whole section, “DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME” and “CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS” no use.
    Read more on properties and figure out which can be useful. Or give me a call ;).
  • 3. Use CONSTRAINED with multiple value parameters while putting them in STRTOSET like STRTOSET(@LoadPort, CONSTRAINED). Read about keyword in msdn but still; it does help query processor to understand all the values passed, belongs to same attribute hierarchy. In turn it helps query to be parsed through compiler quick. We should not avoid using it.
  • 4. Make sure of using MEMBERS in place of ALLMEMBERS. Most of the times we don’t have calculated attribute members in cube. Which means using MEMBERS is appropriate than ALLMEMBERS.
  • 5. Use MEMBERS with correct level of attribute hierarchy. Basically you should know the difference between:
    [Dim Customer].[Customer].[Customer].MEMBERS
    [Dim Customer].[Customer].MEMBERS
    This means you get additional member in second query which is actually All member of attribute hierarchy of dimension customer.
    So, if only you want this additional member use second query else first. Important note: most of the times this All member doesn’t get a Label/Name in SSRS list of members.

I can think of few more good things to do in SSRS Reporting but will share with different post. I hope I don’t forget those. Catch you in new post.