Tuesday, 26 October 2010

Exporting to Excel and renaming sheets in 2008 R2

In Reporting Services 2008 R2 Microsoft has added functionality to rename multiple sheets, so if your report is more than one page and you want to rename the worksheets this will work automatically out of the box.

You can either rename the sheets for a group, if each group has a page break between them or you can rename sheets if there is page break between objects.

To rename sheets in a table with groups all you have to do is select the group as shown below and then in the properties window (press F4 if the properties window is not shown) change the setting for pagename under the Group section to the value you want. This could be text or a field from your dataset.

The export to excel will rename the sheets with the group name.

Exporting to Excel and renaming sheets in 2005

In Reporting Services 2005 there was no functionality to rename sheets when your report was more than one page. You had to either use custom code to rename the sheets or use a macro.

We created a field in one of the cells in the report and then changed the font colour to white, then we created a macro to copy the value in the cell and rename the sheets. The macro is shown below:

Sub RenameSheets()
' Renames all the sheets based on the contents of the cell A1
' If the cell A1 is empty the sheet will be renamed and there is a limit of 31 characters if this is exceeded then only the first 31 are used
' If the following characters are used then an error will be returned:
' []?*/\:

Dim i As Integer

For i = 1 To Sheets.Count

If (Len(Worksheets(i).Range("A2").Value) < 32) Then
If (Len(Worksheets(i).Range("A2").Value) > 0) Then
Sheets(i).Name = Worksheets(i).Range("A2").Value
End If
Sheets(i).Name = Left(Worksheets(i).Range("A2").Value, 31)
End If
End Sub

Monday, 25 October 2010

New Line in a Text Box

In a text box field you can use the following code to force reporting services to start a next line.

'This the first line'+ VBCRLF +
'This is the second line'+ VBCRLF +
'This is the third'

Subscriptions SQL query

Due to the fact the reporting services allows you to query the tables you can easily write SQL which will allow you to return data from the reportserver database.

The script below specifically looks at the subscriptions table which can be created into a report with filters. It is quite handy when you have hundreds of subscriptions to easily find the one you are looking for.

Also as some developers will chose to create specific report subscriptions rather than use shared schedules it can be difficult to work out when they will be sent.

The way that the fields for the report specific times are stored is basically
1,2,4,8,16 etc for example for the day of the week field
1 is Sunday, 2 is Monday, 4 is Tuesday, 8 is Wednesday etc

All the fields are coded like this so it may be best to look at all the distinct values and then work out all the coding in your case statements.

The script will work for both reporting services 2005 and 2008 R2


case when parameters like '' then 'No Parameters' else
parameters end as Para,substring(path,2,50) as path_link,
recipients+' - '+cc+' - '+bcc as AllRecipients,
* from (

month as month2,

when recurrencetype = 1 then 'One off'
when recurrencetype = 2 then 'Hour'
when recurrencetype = 4 then 'daily'
when recurrencetype = 5 then 'monthly'
when recurrencetype = 6 then 'month Week'

end as Typ,

case when daysofmonth = 1 then '1'
when daysofmonth = 2 then '2'
when daysofmonth = 4 then '3'
when daysofmonth = 8 then '4'
when daysofmonth = 16 then '5'
when daysofmonth = 32 then '6'
when daysofmonth = 64 then '7'
when daysofmonth = 128 then '8'
when daysofmonth = 256 then '9'
when daysofmonth = 512 then '10'
when daysofmonth = 1024 then '11'
when daysofmonth = 2048 then '12'
when daysofmonth = 4096 then '13'
when daysofmonth = 8192 then '14'
when daysofmonth = 16384 then '15'
when daysofmonth = 32768 then '16'
when daysofmonth = 65536 then '17'
when daysofmonth = 131072 then '18'
when daysofmonth = 262144 then '19'
when daysofmonth = 524288 then '20'
when daysofmonth = 1048576 then '21'
when daysofmonth = 2097152 then '22'
when daysofmonth = 4194304 then '23'
when daysofmonth = 8388608 then '24'
when daysofmonth = 16777216 then '25'
when daysofmonth = 33554432 then '26'
when daysofmonth = 67108864 then '27'
when daysofmonth = 134217728 then '28'
when daysofmonth = 268435456 then '29'
when daysofmonth = 536870912 then '30'
when daysofmonth = 1073741824 then '31'
when daysofmonth = 8193 then '1st and 14th day'
end as daysofmonth,

when Month = 4095 then 'All Months'
when MONTH = 585 then 'Jan,April,July,October'
when Month = 1 then 'Jan'
when Month = 2 then 'Feb'
when Month = 4 then 'Mar'
when Month = 8 then 'Apr'
when Month = 16 then 'May'
when Month = 32 then 'Jun'
when Month = 64 then 'Jul'
when Month = 128 then 'Aug'
when Month = 256 then 'Sep'
when Month = 512 then 'Oct'
when Month = 1024 then 'Nov'
when Month = 2048 then 'Dec' end as Month,
isnull(MinutesInterval,0) AS MinutesInterval,
case when isnull(MinutesInterval,0) <60 --right="" 0="" alue="" ame="" and="" arametervalue="" arametervalues="" as="" at="" bcc="" c.description="" c.name="" c.path="" case="" cc="" createdby="" days="" daysofweek="" ed="" else="" end="" extensionsettings="" hours="" hu="" left="" len="" ll="" minutesinterval="" modifiedby="" on-fri="" on="" parameters="" query="" recipients="" replace="" report_description="" report_name="" ri="" right="" s1.eventtype="" subs.description="" subs.lastruntime="" subs.laststatus="" subs.modifieddate="" subs.subscriptionid="" then="" to="" u.username="" u1.username="" ue="" un="" varchar="" wed="" when="" xml="">'SharedSchedule' then 'ReportSpecific' else s1.Name end as Schedule_Name,
s1.startdate,s1.nextruntime,s1.eventtype,subs.description as [Subscription Description]
ReportServer.dbo.Subscriptions subs with(nolock)
join catalog c on c.itemid = subs.report_oid
join users u on u.userid = subs.modifiedbyid
join users u1 on u1.userid = subs.ownerid
join reportschedule rs on rs.subscriptionid = subs.subscriptionid
join schedule s1 on s1.scheduleid = rs.scheduleid
) as D

Thursday, 21 October 2010

Sending reports using SQL

Sometimes there may be a requirement to send a report using sql code or you may be fed up with having to change the time in report manager when you are develping a report.

1)The first step would be to create a shared schedule which is in the past
and give it a name eg My_schedule
see the screenshot for details.

In the reportserver database you will need to create a stored procedure which will allow you to do this but first you will need to create a Synonym to the schedule table. My understanding is that a synonym is normally used to save you time writing an object name if its on a different server, eg if you want to refer to a table called customers which was on a different server you would type
you can create a synoynm which will allow you to refer to this object without having to type the full name
2)create synonym dbo.mycutomers for [servername].[databasename].dbo.customers

So first create synonym for the schedule table on the reportserver database

create synonym dbo.runreportschedule for [servername].[databasename].dbo.schedule

Then create a store procedure which will fire the report schedule
CREATE PROC [dbo].Runreportschedule(@EventName AS NVARCHAR(1000))
dbo.dbo.runreportschedule AS s
NAME = @EventName
EXEC msdb..sp_start_job @job_name =@myScheduleID

You will need to give the system prcoedure sp_start_job permissions so that it can fire the report.

Everything is now set, All you need to do is create a subscription on report manager and then use the shared schedule you have created.

Then in query analyser execute the stored procedure

[dbo].Runreportschedule 'Myschedule'

This will then send the report immediately

T SQL Functions

T SQL Function which returns the date for the previous month, the date is required in 2 digits

select dbo.fnlastmonthdate(27)
2010-09-27 00:00:00

create FUNCTION [dbo].[fnlastmonthdate] (@day int)
returns smalldatetime

cast (
convert(char(4),case when datepart(mm,getdate())=12 then datepart(yy,getdate())-1 else datepart(yy,getdate()) end)
CASE WHEN len (case when datepart(mm,getdate())=12 then 1 else datepart(mm,getdate())-1 end) = 1 THEN
'0'+convert(char(1),case when datepart(mm,getdate())=12 then 1 else datepart(mm,getdate())-1 end) ELSE
convert(char(2),case when datepart(mm,getdate())=12 then 1 else datepart(mm,getdate())-1 end)
'-'+convert(char(2),@day)+ ' 00:00:00.000'
as smalldatetime)



Wednesday, 12 May 2010

SSRS Expressions

To Alternate colours for a group:
=iif(RunningValue(Fields!MYFIELD.Value,countdistinct,nothing) mod 2,"silver","white")

To Concatenate a String with a date value:
="Today is the day "+FormatDateTime(fields!MYDATE.Value)

To create a 'Page N of M' Expression:
="Page " & Globals.PageNumber & " of " & Globals.TotalPages

Concatenating a string with a currency value and removing the decimal places
="The current price of bread is : "+cstr(FormatCurrency(Fields!MYFIELD.Value,0))

Switch Expression Example works like a case statement in sql

=SWITCH(Fields!status_code.Value = "OPEN", "chartreuse",
fields!status_code.Value = "OPENA", "chartresuse",
fields!status_code.Value = "OPENC", "chartreuse",
fields!status_code.Value = "CLOSE","Gainsboro",
fields!status_code.Value = "ARCHI","Gainsboro",

Monday, 25 January 2010

Custom Colours in Pie Charts

I created a number of pie charts which compared the data for a number of clients in different years. As some of the clients did not have any data in some of the years the default colours were mixed up.

To remedy this you can use the code below to specify the colours you want.

The code below is inserted in the report properties window under the code tab.

Private colorPalette As String() = { "purple","blue","darkgreen","lightgreen","pink","teal","yellow","gray","black"}
Private count As Integer = 0

Private mapping As New System.Collections.Hashtable()

Public Function GetColor(ByVal groupingValue As String) As String
If mapping.ContainsKey(groupingValue) Then
Return mapping(groupingValue)
End If
Dim c As String = colorPalette(count Mod colorPalette.Length)
count = count + 1
mapping.Add(groupingValue, c)
Return c
End Function

You can choose the colours you want in between the brackets the order is from let to right.
{ "purple","blue","darkgreen","lightgreen","pink","teal","yellow","gray","black"}

When you have entered the code you can use this in your pie chart.
Edit the value in the data tab of your chart properties then edit the value, appearance,series style, fill, color and then click on the expression box and enter the following expression

Page Layout in Landscape Mode

I have quite a few requests to create reports in landscape format.
In the report properties window change the page width to 29.6cm
and the page height to 21cm and set the margins to 1cm.

Alternating colours

How to use alternating colours in a table created in ssrs

Highlight the row or the cell in the details section of your report and then in the properties window in background (under Appearance). Select the Expression and in the Expression box
type in the following code.

=iif(RowNumber(Nothing) Mod 2, "silver", "White")
=iif(RowNumber(Nothing) Mod 2, "White","#fff4cb")
=iif(RowNumber(Nothing) Mod 2, "White","aliceblue")

You can use custom clours as well.

To use the custom colours create a custom colour in the expression window then double click the colour and the code will appear in the text box.

For alternate colours in a matrix row group use :

=IIf( RunningValue (Fields!FIELDNAME.Value, CountDistinct, Nothing) MOD 2, "Transparent", "aliceblue")

Reporting Services Tips n Tricks

Hi, I have started this blog so I could keep all my reporting services tips in one place.

Keep SSRS (SSRS2016) report manager awake

When running a report for the first time in report manager it takes a while to run, after this initial run reports run fine.  There are a ...