student Box Office

Learn more from here.

student Box Office

We will prepare the best articles for you to acquire knowledge.

student Box Office

We will help you always. Just follow our guidelines.

student Box Office

Come and join here to share the knowledge in latest Technologies.

student Box Office

Share your views with us. And update your knowledge.

Showing posts with label SSRS. Show all posts
Showing posts with label SSRS. Show all posts

Oct 28, 2011

Beginning SQL Server 2005 Reporting Services Part 2


We will investigate:
  • Use of expressions that allow you to dynamically control nearly every aspect of reporting from control properties to data binding
  • Common functions that allow run calculations and manipulate data within the report itself
  • Custom code, used to build your own library of functions within the report.
We'll also set up a Matrix control and create a sub-report. Lastly, we will add some flair to the report by adding dynamic drills and sorting.

Getting started

In order to follow my examples, you will need to have SQL Server 2005, SQL Server 2005 Reporting Services, and Visual Studio 2005 correctly installed and configured. If you need some help with this, please refer back to the links in Part 1 of this series. Next, download the code file for this article (see the Code Download link in the speech bubble to the right of the article title). The code file contains a sample Visual Studio project and a SQL Script for creating the ReportDemo database. If you've not done so already, go ahead and create the database using theReportingDemoDatabaseScript.sql script or, alternatively, by restoring the provided ReportingDemo.bak file.
Now start a new Business Intelligence project in Visual Studio 2005 (or using BIDS, which installs with SQL Server 2005). Select Project Add Existing Item function to add to the project the shared datasource (ReportDb.rds) and the sample report, FirstReportMan.rdl. Next, open up the shared datasource and set the server, database, login and password to point to your copy of the database. We will start with the FirstReportMan.rdl report, so double-click on it in the solution explorer to load it into the designer.

Expressions

An expression is a short statement, written in code, which sets the value of a property. An expression can set the value of a property based on just about any data available in the report: parameters, report global values, fields in a dataset, and built-in functions.
SSRS 2005 has made some drastic improvements in how expressions are created. It now supplies an intuitive expression editor. If you scroll through the Properties window, you will notice that most of the properties of controls on the report can be hard-coded or can be set through expressions. (That's the <expression> option you see everywhere.) You will also see buttons labeled fx in the pop-up Properties dialog. These buttons will access the expression editor.


The expression feature makes SSRS 2005 into an incredibly versatile tool, because it allows most aspects of the report, from the data it shows to how it shows it, to behave dynamically. Rather than using a hard-coded value for a particular property, the SSRS resolves the expression to set the value for the property.
Looking at our report, let's say we want it to highlight all the customers from a particular State. We could use the expression:

=iif(Fields!State.Value = "CA", "Bold", "Normal")

If we apply this expression to the detail row in the table and run the report it will bold the text for each row where the value of the State field is California. That's great if the data from California is all that you are interested in. However, it would be ridiculous to have one report for each state, so let's make this expression even more dynamic by adding a report parameter that will determine which State is highlighted when the report is run.
First, let's add the new parameter to the report. Open the FirstReportMan.rdl report and navigate to the Layout tab. From the Report menu select Report Parameters. When the dialog window opens, click the Add button at the bottom of the screen. Call the new parameter 'HighlightState' and set the available values as follows:

CaliforniaCA
FloridaFL
LouisianaLA
IllinoisIL
TexasTX

Now click on OK.
Note:
You'll see that when setting up a list of pre-defined values for a parameter that there is a 'From Query' option. You can use this option by defining a dataset on the data tab of the report designer. For example, if we had a State table in the database we could define a dataset to retrieve the data for the parameter dropdown from that table. Once you choose the 'From Query' option, you select the dataset, the value field (this is the field from the dataset that contains the value passed to the report) and the label field (the field from the dataset that contains the value displayed to the user when they are prompted for parameters).
The next step is to set up the expression. Click on the table control on the report. When the table control is selected, an extra control tab appears at the top and left of the table. Click on the little 'row maker' icon, just to the left of the detail row. This allows you to set properties for the entire row. In the properties window select FontWeight and choose <expression> from the drop-down list to open the expression editor. Typing =iif( should give you Intellisense. You can use the expression builder to create the following line of code:

=iif(Fields!State.Value = Parameters!HighlightState.Value, "Bold", "Normal")

The iif is a flow control statement commonly used in SSRS expressions. Its format is:
iif (boolean statement, true result, false result)
If the boolean statement is true, then the true result is returned, and if not, the false result is returned. In this case, the boolean statement is asking: 'Does the state code equal the state code that was passed to the report? If it does, return the word 'bold'. If it does not, return the word 'normal''. The value returned is then used to set the property for that instance of the row.
Now switch to the Preview tab and select a State to highlight. When the report runs, all the rows with customers from the selected State should be displayed in bold.

Common functions


Let's navigate back to the expression editor. In the bottom half of the screen there are three columns. The first column lists different categories for building expressions. The last option is Common Functions. Expand theCommon Functions node. Click on the Date & Time category. In the next column, double-click on one of the functions. You will see that it is added to the expression box at the top of the dialog box. Next, simply put the cursor in the expression box after the function. If you then type in the opening left bracket you should instantly see Intellisense for the function you selected.


Let's use the Year function in the report to display only the year in which someone was born, instead of their full birth date. Right-click on the field that displays the date of birth and select Properties. On the General tab, find theValue field and click the fx button to bring up the expression editor. Change expression to read.

=Year(Fields!DateOfBirth.Value)

There we have it. It's a good idea to preview the report now.
Also of note here are the aggregate functions. These functions assist you in working with all of the data in a dataset. For example, let's say your report is an order form with a list of items and their prices. You can use theSum function on the Price field to create a total price on the report. In a different example, if you had a report that listed all the purchase dates and the total amount of each purchase, you could use the AVG function to get the average purchase price for that customer.

Global variables


Let's go back again to the expression editor. This time, click on Globals in the first column of the expression editor. In the second column, you will see the list of the global variables that are provided to the report.
In this example, we are going to use the global variables to create a page-numbering scheme for our report. First, add a footer to the FirstReportMan.rdl report. You enable this by going to the Layout tab and selecting the Report Footer option from the Report main menu. Now that you have a footer, drag four text boxes into the footer section. Set their font properties to 8 pt, bold. Set the text for each text box as follows:

Page
=Globals!PageNumber
of
=Globals!TotalPages

Switch to the Preview tab and run the report. You will now have a footer on each page that looks something like 'Page 1 of 5'.
Some other globals worth noting are:
  • ExecutionTime – this tells you how long it took to run the report
  • ReportServerUrl – this allows you to verify that you are getting your report from the correct source
  • UserID - this shows under which User ID the report was run
You can use these global variables to build some basic diagnostics into your reporting. You could also add these variables to the report footer and use a parameter to hide or show them. That way, even in production, your users can see a tidy, clean report, but you can see the same report with all the extra information on it.

Custom functions


There are about 100 common functions in SSRS 2005, and they can handle most of what you will need to do. Occasionally, however, you will still need to set an expression with more control than the common functions can manage. So, to make SSRS even more flexible, you can write custom VB.NET or C# functions and use them in expressions.
Now we are going to add a custom function to the FirstReportMan.rdl report.
Open the report and navigate to the Layout tab. From the Report menu select Report Properties and then jump to the Code tab. We are going to write a custom function that returns a different color, depending on the value that is passed to it. We will then use that function to set the background color for the status field in the report detail table.
Copy the following code into the code window:

Public Function GetColor(ByVal status as String) as String
IF status = "100" Then
Return "White"
End IF
IF status = "101" Then
Return "Yellow"
End IF
IF status = "102" Then
Return "Tomato"
End IF
End Function

Click OK and close the window.
Note:The full list of available colors is found in the Color dropdown list in the properties window.
Now that we have a function that returns color names we need to wire up that function to an expression. Click on the Customer Status cell and open the Properties window. Find the Background Color property and chooseExpression from the dropdown. Add the following line of code to create an expression:

=code.GetColor(Fields!CustomerStatus.Value)

When the report runs and this expression is resolved, SSRS will call your GetColor function and pass the value of the customer status for that instance of the row to the function. The function takes over and decides which color should be returned. SSRS then uses that value as the value for the background property for that cell.


Please note that custom functions must be called using =code.<myfunction>.
Now navigate to the Preview tab and run the report..

Subreports

A subreport is a report that is embedded into another report. Subreports can take parameters and execute their own datasets. A key aspect to note is that a subreport in SSRS is actually just another report (unlike some reporting tools, where a subreport is a special construct). In fact, in SSRS you can execute a subreport on its own.
To add a subreport to a report, you simply drag a subreport control onto the report and tell it which report to display. If the subreport requires parameters, you have to tell the main report which value to pass to the subreport. It's actually very simple.
Let's add a new report to the project and call it MainReport.rdl. Create a new dataset using the shared datasource and the query:
SELECT CustomerID, FirstName, LastName FROM Customer
Switch to the Layout tab. Drag a table on the report detail area. Set up the first column to display the customer's first name (by dragging that column from the Datasets tab into the Detail row) and set up the second column to display the customer's last name. Label the third column 'Address'. Preview the report, just to be sure it works.
Create another report, and call this one MySubReport.rdl. This time, create a dataset that uses the shared data source, and use the following query text:
SELECT Address, City, State, ZipCode
FROM Customer
WHERE (CustomerID = @CustomerID)
In the Layout tab, use text boxes to create the address layout, as shown in figure 5. You can simply drag the text boxes onto the screen by clicking on the field in datasets tab and dragging it onto design surface. You will also note that when you do this, the expression used to set the value property for the textbox uses the First() function. This function will use the value from the first row returned by the dataset. All other rows returned are ignored.

Now preview the report and use '100' for the CustomerID parameter.
Let's jump back to the MainReport.rdl. To embed the subreport, drag a SubReport control into the detail cell for the column you labeled 'Address'. Right-click on the SubReport control and select Properties. In the Properties dialog choose MySubReport from the subreport dropdown.


Next, switch to the Parameters tab. This is where you connect your subreport to the main report. You do this by indicating which value from the main report is to be passed to the subreport to fulfill its parameter requirements.
In the Parameter Name column choose CustomerID and in the Parameter Value column choose=Fields!CustomerID.Value. This will wire up the subreport to whichever customer is being displayed in the row of the table.


Click OK to close the dialog, and then preview the main report.

The Matrix

It's this question that drives us, Neo. What is the Matrix? OK, I'll stop right here. You can insert your own slam to the second two movies. However, there is a really cool control in SSRS called the Matrix control. The Matrix is used to create pivot table style reports. We are going to set up a simple Matrix control to show us which customers, in which State, have which status.
First, start a new report called MatrixReport.rdl. Add our standard dataset where you use the shared data source, and then add the Select * from Customer query.
Navigate to the Layout tab and drag a new Matrix control onto the page. Where it says Rows, drag the State field from the dataset. Where it says Columns, drag the CustomerStatus field from the dataset. Drag first name and last name into the data area on the Matrix control. After a little formatting, it should resemble this:

When the report runs, it looks like this:

Adding drill downs

The drill down functionality in SSRS allows you to have areas of your report that can expand and collapse, much like a tree view.
First, start a new report called AdvancedTable.rdl. Add our standard dataset, where you use the shared data source and the Select * from Customer query.
Navigate to the Layout tab and drag a new table control onto the page. The first thing we need to do is to add a group to the table. Click the table to highlight it, then right-click on the little box with three horizontal lines in it that appear at the left side of the table at the beginning of detail row. Select Insert Group. When the Group Dialog appears use =Fields!State.Value as the expression, so that the report now groups on State. Now drag the State field into the first column on the Group row. Next, drag the First NameLast Name and City fields into the detail row. Add some formatting, and preview the report.


We've now performed a grouping, but we still have to enable the drilldown. Click on the table to highlight it. Right-click on the nub that appears, just to the left of the detail row. Select Properties. When the Properties window opens, expand the visibility section. Set the Hidden property to True and set the ToggleItem property to State. TheHidden property determines the state of the row when the report is first run. If we set it to True then the data is collapsed and hidden. By setting the ToggleItem property to Statee, when the report is run a little + sign appears next to it when the report is run and it works like a tree view.
Switch to the Preview tab and run the report. Now only the States appear, but you can see the customer in each State by using the tree-style +/- controls.


Adding dynamic sorting


It is incredibly easy to add sorting to your table. Let's re-open the FirstReportMan.rdl report. Navigate to the Layouttab of the report designer. Click in the cell labeled First Name in the header of the table. Right-click and selectProperties. Switch to the Interactive Sort tab. Check the checkbox for 'Add an interactive sort action to this textbox'. Next, set the Sort expression to the value that is displayed in the column – in this case=Fields!FirstName.Value. Now repeat this process for the rest of the report.


Preview the report, and you should have interactive sorting on each column.


Beginning SQL Server 2005 Reporting Services Part 1


Building and deploying basic reports

If ever there was job for "real" developers to shuffle to their juniors, it is building reports. It's not real development anyway; it's more like glorified formatting. Besides, the esoteric tools that you use to build reports try to provide an abstraction layer, which often prevents you from having any real control over the report. I've heard all these arguments before. If this sounds like a conversation you've had by the water cooler, then I invite you to take a closer look at SQL Server 2005 Reporting Services (SSRS).
SSRS 2005 is the latest version of SQL Reporting Services, and ships with all versions of SQL Server 2005. SSRS allows you to quickly and easily create reports from multiple database sources. The finished reports can be presented directly from the reporting services website, or they can be displayed in your web- or Windows-based applications. Reports can be exported to multiple formats, including comma delimited text, XML, portable document format (pdf) and Microsoft Excel.
This article is the first of four parts, which will provide in-depth coverage of SQL Server 2005 Reporting Services:
  • Part 1 covers the basics of the SSRS. It demonstrates how to build quick, simple reports and will familiarize you with the basic Report Designer environment
  • Part 2 will cover use of custom functions, aggregate functions, sub-reporting, the matrix control, drill-downs, and sorting.
  • Part 3 will take an in-depth look at the charting control
  • Part 4 digs into the actual Report Definition Language (RDL) and the new Report Builder tool.

Installing and configuring Reporting Services

After much debate, we decided that full installation and configuration details were outside the scope of an article focused on how to build basic reports using SSRS, especially as there are already several online resources that treat this area in detail. See, for example:
and
Well worth reviewing are the details in the latter on the need to install SSL on any machine hosting SSRS.
---Editor's installation notes---In order to test the reports in this article, I went through a single-machine installation on Windows XP (meaning that SQL Server 2005, Reporting Services, and much more, are all installed on my poor laptop). Since I didn't install SSRS when I installed SQL Server 2005 (I didn't have IIS installed at the time), I had to first install IIS 5.1, and then Reporting Services (from the SS2005 disks). I then jumped immediately into Reporting Services Configuration Manager tool (All Programs ¬ SQL Server 2005 ¬ Configuration tools). The left panel acts as a sort of checklist of items to configure:


All went well until the Database Setup. Because I had not installed SSRS at the same time that I installed SQL Server, the ReportServer and ReportServerTempDB were not created by default. These databases hold all the report definitions and reporting server configuration information. Connecting to SQL Server using Service Credentials, the databases appeared to be created, but I received an error suggesting that I didn't have permissions to perform the requested task, and a red cross remained next to the Database Setup icon. This had me stumped for a while – eventually I appeared to solve it by hopping to the Server Status section, stopping the Report Server, opening SSMS and deleting both the ReportServer and ReportServerTempDB databases, and then restarting the Report Server and trying again! Even though I swear this didn't work the first time I tried it, it seemed to do the trick the second time (while I was on the phone moaning to Steve that I couldn't get it to work!). However, I'm still not clear why I had the problem in the first place – or why it suddenly went away.
This wasn't quite the end of my problems. Installing SSRS creates two new virtual directories under the default website on IIS. By default, they are named Reports and ReportServer. The ReportServer site hosts a web service for running and managing reports. The Reports site allows you upload reports from a browser and run reports over the web. When I tried to navigate to http://localhost/ReportServer I received the following error: "Failed to access IIS metabase". Fortunately, the information on the error page is quite useful (for a change) and this, coupled with a quick Google search, led me to grant access to the metabase to the ASPNET user account by executing the following from the directory housing the aspnet_regiis executable (WINDOWS\Microsoft.NET\Framework\v2.0.50727, in my case):

spnet_regiis -ga ASPNET

This did the trick, and I was up and running. I received some raised eyebrows here when I proposed to install SSRS. It made my long-suffering sys admin team particularly nervous. The 2000 version of SSRS seems to have a very bad reputation among the Red Gate team, both as a performance nightmare, and in one case for "completely annihilating" a developer's machine. However, the above slight quirks aside, the SSRS 2005 experience seems pretty smooth and I've had no real performance, or other, issues. So far.
-----End of Editor's note----
Once you've completed the installation and configuration process, the first thing to do is download the code file for this article (see the Code Download link in the speech bubble to the right of the article title). The code file contains a sample Visual Studio project and a SQL Script for creating the ReportDemo database. You will need this database if you want to follow the examples in this series of articles so go ahead and create the database using the ReportingDemoDatabaseScript.sql script or, alternatively, by restoring the provided ReportingDemo.bak file.
If you are using SQL Server Authentication on your SQL Server you will also need to set up a login with permissions to the ReportDemo database (for the examples, I set up a login called DemoUser as a DBO on my ReportDemo database).

Using the Report Wizard

There are two ways to create SSRS Reports. You can build the report manually, or you can use the Report Wizard to give yourself a head start. For this first report, we are going to take advantage of the wizard. Start a new Business Intelligence project in Visual Studio 2005. Then, from the menu, select Project > Add New Item. Select the Report Wizard option and call the file "FirstReportWZ.rdl". Click Add. Click Next on the Welcome screen and this will bring you to the Select the Data Source screen:


Select the New data source radio button and give the data source a name. Select Microsoft SQL Server as the type.
Note:Use of the Shared data source option is actually a better option in most cases but, for the sake of this example, we will just create a new data source. We're going to set up a shared data source later in this article.
Click the Edit button to bring up the Connection Properties dialog:


Enter or select a server name. The default is to log on using Windows Authentication. If you are using SQL Server Authentication, choose that setting, and enter the username and password. Finally, select a database, in this caseReportingDemo. Make sure you test the connection before you click OK.
Next up is the Design the Query screen. You can use the Query Builder by clicking the button at the top left, but in this case simply enter "Select * From Customer" into the Query string text box and click Next. On the Select the Report Type simply select the type you prefer (tabular or matrix) and hit Next.
This brings up the Design the Table screen:


Select State in the Available fields box and click the Group button. This will group the data in the result set by State. Select Next. On the Choose the Table Layout page, select the Stepped option and check the Enable Drilldowncheckbox. On the next screen, choose a style for your report (I chose Ocean) and click Next.
This brings up the final screen, Completing the Wizard:


It shows a summary of your report options, and gives you an opportunity to rename the report and to preview it. Click Finish to end the wizard.
You should be shown the report in the standard Report Designer:


There are three tabs: DataLayout and Preview. You should be on the Layout tab. Click on the Preview tab to view the report. Since this report doesn't take any arguments, it will run as soon as you click on the tab.


Use the +/- symbols next to the State abbreviations to expand and collapse the grouping of the report.

Manual report creation

The previous section, while perhaps overly simplistic, does show you how to get a report up and running with zero code and zero property setting. Obviously, such reports will not meet most development requirements, but do not discount this option as a starting point for more complicated reports. Once you've created a report with the Report Wizard, you are free to make any modifications to it.
In this section, we are going to create a more realistic report from scratch, including how to create and use a shared data source object, stored procedures, and how to format your report, set report properties and use report parameters.

Creating a shared data source

Before we start the report, we are going to build a shared data source i.e. a data source that is common to, and can be used by, all of the reports on a reporting server. While each report can contain its own connection information, it is good practice to use shared data sources, as it will save you a lot time and headaches. This way, you only have to set the connection information once. For example, let's say your company has Development, Test and Production environments. If you put the connection information into each report, you will have to change it each time when you publish to Development, Test and Production. If you use a shared data source, you still have to set up a data source object for each of three environments, but you can simply publish the report to each environment, and they will automatically use the connection information associated with that environment.
From the menu select Project > Add New Item > Select Data Source. On the General tab, call the data source "ReportsDB". Leave the Type as Microsoft SQL Server. Click the Edit button on the right, and enter the connection information for Reporting Demo, as before. Click OK on the Shared Data Source screen and the data source is done.

Add a new report

From the menu select Project > Add New Item. Select Report and name it "FirstReportMan.rdl". A new report will be added to the project, and the Report Designer will open at the Data tab. At this point, let's take a closer look at the Report Designer tool. At the top of the Report Designer window are three tabs: DataLayout and Preview. TheData tab is used to build data sources for your report. The Layout tab is the physical report designer where you set up the header, the footer and the data presentation of the report. The Preview tab allows you to actually run the report from Visual Studio 2005, without having to publish it to a report server first. If your report takes parameters, the Preview tab will ask you to fill them out before it runs the report.
The first thing we need to do is get data into our report. At the top of the Data tab choose <New Dataset…> from the dropdown list:


The Dataset dialog opens:


Name the dataset "ReportData", and select the ReportsDB data source from the dropdown. SelectStoredProcedure as the command type, and enter "spr_CustomerSelectAll" in the query string box. Click OK to close the dialog.
Note:
spr_CustomerSelectAll is a very simple, parameter-less stored procedure that selects all of the columns from the Customer table. The source code is included in the ReportingDemoDatabaseScript.sql script with the code download.
Test the dataset by clicking on the big red exclamation point at the top of the report designer. This executes the query and displays the results. You can repeat these steps if you wish to add multiple datasets to your report.

Setting up the report display

Next, switch to the Layout tab. This is where you actually build the report display. Start by dragging a table from the Toolbox, onto the Body section of the report. By default, the table shows a header row at the top, a detail row in the middle and a footer row at the bottom. You can add additional columns to the table by right-clicking on one of the columns and selecting one of the two Insert Column options.
Click on the Datasets tab under Toolbox on the left-hand side of the Visual Studio environment. You should see theReportData dataset. Expand it, select FirstName and drag it to the first cell of the body row of the table. This will display the First Name field in the first column. Now put the LastName in the second column, and theCustomerStatus in the third:


Note that, when you drag the column FirstName into the body row of the table, SSRS make a guess as to what to call the row. It calls it "First Name". You can click on the Preview tab to view the report.

Adding formatting

OK, so we have a basic, very plain, report. Let's add some formatting to make it look good. Let's add theDateOfBirth column to the table. You can expand and shrink the size of the columns by highlighting and dragging:


If you wish to get rid of the footer row of the table and then click on any field in the table. You will see a grey box surround the table. Right-click on the icon at the beginning of the body row and then click the Table Footer option to deselect it.
The table header is next. To format all the cells in the header in the same way, click and drag over all the cells to select them. Open the Properties window and set background color, font, and so on.


Note, however, that if you wish to change the justification of the text or the size, then you do so using the main menu at the top, not via the properties window. Again, you can click on the Preview tab to view the report.

Add a report header

The table already has a header, but the report can also have a header and footer. Report headers and footers appear on every page of the report. Put the Report Designer in Layout mode and select Report > Page Headerfrom the menu. A new band labeled Page Header appears on the report above the body. Drag a text box onto the header and click directly on it. Type "My First Report", not in the Properties window, but right on the control.


To adjust the text style and size of your heading, highlight the text box and use the option from the top menu.

Formatting

Each field can have formatting. Let's deal with that ugly Date of Birth field. The time information is superfluous, so let's format the date properly. Right-click on the cell that contains the date of birth, and choose Properties. Next, select the Format tab.


Click on the second button (labeled "…") to the right of the Format code field. When the dialog opens, use the standard options. Select Date in the list on the left, then choose the sample date format you want on the right. ClickOK to close the dialog.


Click OK to close the Properties window and then click on the Preview tab to view the report.

Setting report properties

To access the report properties, you need to be on the Layout tab of the Report Designer. When you click on this tab, a new menu item, Report, activates. This menu gives you options for turning on and off the report header and footer sections (as we have seen), adding embedded images, setting report properties, and setting report parameters.
Setting up the report print settings is not intuitive, compared to other products. In the report Layout tab you see your report with a ruler across the top. That ruler is set up in inches. A standard sheet of paper is 8.5 x 11 inches. The default setting in SSRS is to have a 1-inch margin all the way around the content area. So, at 8.5 inches wide with a 1-inch margin on the left and another on the right, you have 6.5 inches for content. Any more, and the content beyond the 6.5 inches will spill over onto a second sheet of paper when printed. It will not automatically shift to Landscape.
To get Landscape reports, you have to make the proper report settings. Navigate to the Layout tab of the Report Designer. From the Report menu select Report Properties. Switch to the Layout tab of the dialog box. To switch to Landscape printing, you need to change Page width to 11in and the Page height to 8.5in.


On the same Layout tab, you can also get up your report to display the data in multiple columns, and you can control the margins. By default, all the margins are set at 1 inch. Remember, if your report width, plus the right and left margins, is greater than the width of the printer, you will get spill-over when you print out your report.

Using parameters

There are two ways to add parameters to your reports. The first is to use parameters in the queries in your data sources. The second is to set up parameters through the Report Parameters dialog box. We will do both.
Query parameters
First, we will set up parameters using a data source query. Navigate to the Data tab, and click the "…" button right next the Dataset dropdown box. The Dataset dialog box opens and allows you to edit the query for the dataset. Change the Query string from "spr_CustomerSelectAll" to "spr_CustomerSelectByState".
Note:spr_CustomerSelectByState accepts a parameter called StateCD that allows us to filter the data from the Customer table by State. Again, the source code is included in the ReportingDemoDatabaseScript.sql script with the code download.
Click OK and then run the query by clicking the red exclamation point (!) on the Data tab toolbar. You will be prompted to enter a parameter value for StateCD (the State code). Enter "CA" and click OK. The query should return all the customers that live in California.
Switch to the Preview tab. Instead of the report just running, there should be a place for you to enter a value for the "StateCD" and run the report. Enter "CA" and click the View Report button. You should see your report filtered by state.
To edit the parameters, or to add new ones, switch to the Layout tab of the Report Designer and open the Report Parameters dialog from the Report menu. First, we are going to make the "State code" prompt a little more friendly. Select StateCD in the Parameters list box then, in the Parameters Properties box, change the prompt to read "State". In the Available values section enter "California" and "CA" on the first line. Enter "Louisiana" and "LA" on the second line.


This will make the prompt for "State value" into a dropdown. You can also build additional datasets into your report, and use the values in those datasets as criteria for dropdowns.
Report parameters
Now let's add a parameter that is not used in a query. Click the Add button in the Report Parameters dialog from the Report menu. Give the new parameter the name "ReportTitle". Its Data type should be String. Set the Prompt to "Report Title". Click OK and close the dialog box.
Drag a new text box onto the report header area. Right-click on it and choose the Expression option. In the Edit Expression dialog select Parameters. Double-click on the ReportTitle parameter. This text box will now display the value you pass to the Report Title parameter.


Switch to the Preview tab and try it out.

Publishing your reports

Up to now, you have been running your reports in the Visual Studio 2005 environment but, to make them useful, you must publish them to a report server. The easiest way to do this is to have Visual Studio publish your reports.
Start by right-clicking on Project in the Project Explorer and choose Properties.


Set TargetServerURL to the URL of your report server. Use the TargetReportFolder property to set up a folder for your reports. If the folder does not exist, the Publisher will create it for you. The other key thing to pay attention to here is the OverwriteDataSources property. When this property is set to "True", it will automatically copy over all your data source objects when you publish. When set to "False", it will copy any new data source objects, but it will not overwrite existing ones. This is important when dealing with development, test and production servers. You can publish a set of data source objects to each server, pointed at the correct database, and never have to worry about what database your reports are hitting in each environment.
From the Build menu select Deploy Solution. This will publish the project to the selected folder on your report server. You can also deploy individual reports by right-clicking on the file in the Solution explorer and selectingDeploy.
Once your report has been published, you can access and run it on your server through the browser athttp://<servername>/<reportservername>. From the Home page, you should be able to find the folder you published to, with the reports in it. Select a report to run. At the top of the page you can enter any values for report parameters, and then run the report. From here, you can also print or export the report.

Ten Common SQL Server Reporting Services Challenges and Solutions


In every business there are several different groups of report users, from chief executives, to business analysts, to operational staff, who all need access to reliable and current data in order to track overall business performance, investigate the effectiveness of individual business functions, or simply for ad-hoc day-to-day reporting.
In most organizations, at least some attempt has been made to meet these reporting needs. Historically, however, the problem has been that the available reports have not always been up-to-date, or even accurate. Furthermore, individual departments have tended to adopt a "silo" approach, using different tools/systems to create reports that are useful within their silo, but not necessarily consistent or compatible with those produced by other departments. In many cases, there doesn't even exist a shared understanding of the business data that underpin these reports.
SQL Server Reporting Services (SSRS), when it arrived, offered a much-needed means to centralize and standardize reporting across the business, and it has largely delivered. Having used SSRS 2005 for the past 4 years, I've found that, with a little effort, it can satisfy most business, ad-hoc, embedded, portal integration, web, and custom reporting needs. However, I've also found that small "gotchas" can halt progress and cause considerable frustration, as it's not always easy to find ways round them in the documentation.
In this article, I round up some of the more interesting challenges that I have encountered in my report development efforts, and the solutions I've found to them. Hopefully, these will be useful to the many (the majority?) people who are still using SSRS 2005 in production. Some of the solutions offered can still be used in SSRS 2008. I conclude the article with a review of some of the issues that SSRS 2008 has fixed, or at least mitigated.

Challenges/Solutions

SSRS offers a range of different reporting techniques and technologies, to cater for the reporting needs of all levels of users, from the chief executives, to business analysts, to operational staff. Their reporting needs range from simple, tabular ad-hoc reports, to parameterized, linked or snapshot reports, to complex drill-down and drill-through multi-level reports.
Following is the list of some of the challenges I have encountered while developing such reports using Reporting Services 2000/2005. In the sections that follow, I will cover each challenge individually, providing insight into what may cause the difficulty, alongside a possible solution.
  1. Horizontal Tables: Calendar Reports
  2. Select "ALL" Query Parameter option
  3. Multiple Sheets in Excel
  4. Excel Merged Cell Issues
  5. Blank Pages
  6. Vertical Text
  7. Report Data in Header/Footer
  8. Are you missing XML/CSV data on your exports?
  9. Template Reports
  10. Using the Reporting Services database

Horizontal Tables: Calendar Reports

The most common need for horizontal display of information, in my experience, is for labeling or for calendar-style reports. There is no native control that allows you to display your data horizontally. There are a few different ways around this, but the easiest way I've found is to use a Matrix control, which allows display of data in a cross-tab or pivot format.
The sample I will be using is of a calendar style report, which will display a report of events which occur in the timeframe displayed. You can build the report from scratch using the steps that I'll outline next, or you can simply import the completed Calendar.rdl file, as part of sample project proved in the code download for this article.
The driving query for this report is shown in Listing 1. The opening lines calculate the required date range for the current month, which may include dates from the prior and forthcoming months, in order to ensure that the results display appropriately on the calendar. The StartDate parameter defines the first Sunday, and the EndDateparameter the last Saturday, to display on the calendar.
The code then creates two Common Table Expressions (CTEs), new to SQL Server 2005 and later. The first,Dates, generates a record for every day in the required date range and the second, Events, simply creates some sample event records for display in the calendar.
Finally, we query these two CTEs, using a ranking function, DENSE_RANK, to assign number to the records based on the date, and various date functions to generate the columns for the matrix control (days of the week), days of the month, event details and so on. The query in Listing 1 is self contained, so all you need to do to test it out is point it to a SQL Server 2005 data source.

DECLARE @StartDate DATETIME, @EndDate DATETIME
--First day of current month
SET @StartDate = DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
--First day to display on calendar
SET @StartDate = DATEADD(DAY,-DATEPART(WEEKDAY,@StartDate)+1,@StartDate)
--Last day of month
SET @EndDate = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
--Last day to display on calendar
SET @EndDate = DATEADD(DAY,6-DATEPART(WEEKDAY,@EndDate),@EndDate)

; WITH Dates([Date]) AS (
   --Select First day in range
   SELECT CONVERT(DATETIME,@StartDate) AS [Date]
   UNION ALL
   --Add a record for every day in the range
   SELECT DATEADD(DAY, 1, [Date]) FROM Dates WHERE Date < CONVERT(DATETIME,@EndDate)
), Events AS (
   --Create some events to place on the calendar
   SELECT EventDate = CONVERT(VARCHAR(2),DATEADD(MONTH, -1,GETDATE()),101) + '/30/2009 02:00:00 PM', Note = 'Event 1'
   UNION SELECT EventDate = CONVERT(VARCHAR(2),GETDATE(),101) + '/23/2009 12:00:00 PM',Note = 'Event 2'
  UNION SELECT EventDate = CONVERT(VARCHAR(2),GETDATE(),101) + '/28/2009 02:00:00 PM',Note = 'Event 3'
   UNION SELECT EventDate = CONVERT(VARCHAR(2),GETDATE(),101) + '/28/2009 06:30:00 PM',Note = 'Event 4'
   UNION SELECT EventDate = CONVERT(VARCHAR(2),GETDATE(),101) + '/30/2009 07:00:00 PM',Note = 'Event 5'
   UNION SELECT EventDate = CONVERT(VARCHAR(2),DATEADD(MONTH, 1,GETDATE()),101) +'/01/2009 01:30:00 PM', Note = 'Event 6'
) SELECT
   -- Number the records based on the date, if multiple records have
   -- the same date then they will be numbered the same. Used in
   -- calculation to determine row record is to display on.
   [Order] = DENSE_RANK() OVER (ORDER BY d.[Date]),
   -- date used in all caluclation for date
   d.[Date],
   --generates matrix columns
   [WeekDay] = DATEPART(WEEKDAY, d.[Date]),
   --used to display day of month on calendar
   [Day] = DATEPART(DAY,d.[Date]),
   --used in some calculations for display
   [Month] = DATEPART(MONTH,d.[Date]),
   -- used to get the time of the event
   e.EventDate,
   --event details to display
   e.Note
--CTEs defined above are used as the queries for the results
FROM Dates d
   LEFT JOIN Events e ON CAST(CONVERT(VARCHAR(10),e.EventDate,101) AS DATETIME) =d.[Date]

--Set the maximum times the Dates cte can recurse
OPTION (MAXRECURSION 100)

Listing 1: The Calendar Report Query

Having defined the query, you can build the report. Start with a blank report and add the query as a dsCalendar data set, as shown in Figure 1.

 
Figure 1: Defining the Calendar report data set

Having created the data set, add a Matrix control to the report, as shown in Figure 2.

Figure 2: Adding the matrix control

Figure 2 displays three watermarked areas of the control:
  • Columns - the matrix column header, which we can use to group the column data.
  • Rows the matrix row grouping for row data, which we can use to group the row data.
  • Data – this cell holds the detail data for the report.
I need to use a table control to group and display our detail data, which is each day in the timeframe from theStartDate to the EndDate, so I dragged a table control from the toolbox into the matrix cell watermarked "Data". For this report, I've have made a few changes to the default setup of the table control. For example, I removed one column and the table footer and I've merged the table header cells, as shown in Figure 3.


Figure 3: Adding a table control to the matrix

The next step is to associate the Matrix control with our dsCalendar data set, as shown in Figure 4.


Figure 4: Associating the matrix control with our data set

Next, I need to establish the row and column grouping for our matrix control. To set the row grouping, switch to theGroups tab on the Matrix properties dialog, select the default row grouping item in the list matrix1_rowGroup1 and click the Edit button.
Set the value of the "Group on" Expression to =Ceiling(Fields!Order.Value / 7), as shown in Figure 5. This Ceiling expression is used to determine when a row should break for the next week, which for the most part will be every 7 records.


Figure 5: Grouping the matrix rows

Click OK, and then select the default column grouping item in the list matrix1_ColumnGroup1 and click the Edit button.  This time, for the "Group on" Expression, simply select =Fields!WeekDay.Value for the drop down list and click OK, as shown in Figure 6.


Figure 6: Grouping the matrix columns

The table inside the "Data" region of the Matrix doesn't require any further work. Based on the established matrix row and column groupings, the matrix data will be organized appropriately.
Now that the control of the data is set up, it's time to define the expressions that will determine what data to display in the matrix and table, when the report is rendered.
First, however, I am going to resize the control. We don't need to display anything in the matrix "rows" region, so we minimize the left column of the matrix control, as shown in Figure 7.


Figure 7: Resizing the matrix columns

The next step is to apply the following Expressions to the various report items for display on the report:
  • Matrix Column Header: =WeekdayName(Fields!WeekDay.Value)
    • Displays the days of the week across the top of the report
  • Table Column Header: =Fields!Day.Value
    • Displays the day for each day in the timeframe
  • Table Detail Column 1: =IIf(Fields!Note.Value = Nothing, "", CDate(Fields!EventDate.Value)
    .ToShortTimeString + ":")
    • Displays the time of the event in the first column of the table
  • Table Detail Column 2: =Fields!Note.Value
    • Displays the event details in the second column of the table

Figure 8 shows the Matrix populated with these expressions.


Figure 8: Matrix expressions

When the report is rendered, it will look similar to that shown in Figure 9.


Figure 9: Rendering the Calendar report

Although the report is now functional, it still looks a little unpolished, so the final step is to tweak the layout and formatting until you are happy with it. Figure 10 shows the finalized report, both in layout mode and rendered.


Figure 10: The finalized Calendar report

Select "ALL" Query Parameter option

When using a query to populate an options list for a parameter, sometimes there is a need to select several options at once, rather than an individual option from the provided list. For example, you may want to run a report for multiple companies, instead of each one individually.
In order to do this, you just need to add a UNION clause to the query that is used to populate a drop down of available options for the company parameter. So, for example, if the original query to populate the parameter list might be of the following form:
SELECT CompanyId, CompanyName FROM Company
When rendered, the parameter dropdown list for the report would look as shown in Figure 11.
Figure 11: Selecting individual parameter values
The updated query, allowing users to select all the available parameter values, might look as follows:

SELECT NULL AS CompanyId, 'ALL' AS CompanyName
UNION
SELECT CompanyIdCompanyName FROM Company


Figure 12: Selecting all parameter values

Next, in the data set that uses the value returned from the query parameter, you will need to update your WHEREclause to work appropriately with the updated parameter. For example, if the original WHERE clause looks as follows:

WHERE CompanyId = @Company
The updated WHERE clause will be:
WHERE (@Company IS NULL OR CompanyId = @Company)

Now, as well as being able to filter the data by an individual company, you can cancel the filter by selecting ALL, which sets the @company parameter to NULL and return results from the query as if there was no company filter.

Multiple Sheets in Excel

Have you had a need to create multiple sheets in Excel? To render a report to Excel on multiple sheets, be sure to use page breaks after the different sections of the report. If a section doesn't specifically allow page breaks, then you'll need to wrap the controls inside a rectangle and set the page break property on the rectangle.
Let's say you have a report with two table regions, as shown in Figure 13.


Figure 13: A report with multiple table regions

When you export the report to Excel, you'll find that both the table regions display on the same worksheet, as shown in Figure 14. This makes it hard to make modifications to the Excel file.

 

Figure 14: Two table regions rendered to the same Excel worksheet
To make the table regions display on different worksheets, you can set the PageBreakAtEnd property to True, as shown in Figure 15.


Figure 15: Setting the PageBreakAtEnd property

When the report is exported to Excel, two worksheets will now be created, as shown in Figure 16.


Figure 16: Two table regions exported to two worksheets

In case you are wondering how to rename the sheets when the report is exported to Excel, there isn't a built-in way. You have the option to design a custom rendering extension, buy 3rd party if one supports this, or to modify the excel file post-export.
A more advanced example of this technique is demonstrated in the Report Index.rdl file, as part of the code download.

Excel Merged Cell Issues

Excel can sometimes seem like the worst rendering extension available in reporting services. If you export a report to Excel, and then try to re-sort the exported data, you get a merged cell error. So, unless you completely reformat the export post-export, you cannot resort your columns.
Reporting Services renders everything top down, and there are several ways in which the merged cell problem can occur when you export the report to Excel:
  • If you have anything (controls, images, etc.) laid out above your table/matrix regions
  • If you merge cells in your table/matrix regions
  • If controls from the top of the report do not lineup with controls from your table
One way to help prevent the merged cell issue is to use the technique discussed in the previous section, "Multiple Sheets in Excel". However, multiple sheets are not always the best resolution for this problem, especially when the problem is your page header.
Figure 17 shows an example of a page header containing an image control and a textbox control, which will cause merged cell issues when exported to Excel. Notice that there are gaps between the controls. Each gap, and each control, that does not span the width of the designer will cause a separate column to be created when you export it to Excel.


Figure 17: A page header that will cause merged cell issues

Figure 18 shows the same page header, formatted in a way that will not cause the problem. Notice how the control spans the width of the designer.


Figure 18: A page header that won't cause merged cell issues

What I've done is remove the image control and set a background image for the textbox control. I also added some padding to the textbox control to change the position in which the text will display, so that the image will display left of the text. This will resolve the merged cell issue, caused by having gaps and multiple controls in the page header.
There is also some Device Information Settings that can be used to alleviate some of these merged cell issues. For instance, on export you can set the setting for SimplePageHeaders to True. More details about this setting can be found here:

Blank Pages

Are blank pages a problem for you, when you export/print your reports? In most cases the extra blank pages result from the fact that the body of your report is too wide.
Let's say you want your report printouts to fit on 8.5in x 11in paper, with 0.5in margins on all sides. This means that the maximum width of your report body in the designer can be 7.5in. If it exceeds that value, then you will get the extra pages printed. Most report developers fall into this trap by having their design surface laid out wider than the allowed width of the body of the report, which would be 7.5in, in this example. As you can see in Figure 19, I ensure that my report body is consistent with a portrait layout of a report. My margins are setup as 0.5in on all sides and the report width is set to 8.5in. So when I layout my report I do not want my designer to exceed 7.5in in width to stay within the report margins and report width.


Figure 19: Report Properties and Layout

Another reason blank pages could be created when you export your report is if you allow your controls to grow. If you do, then they can sometimes grow past the maximum page width for your report. You can prevent your controls from growing by setting the following properties of a control from either the properties dialog or properties panel, as seen in Figure 20. Set the "Textbox height" options in the properties dialog, or set the CanGrow properties in the properties panel of Visual Studio.


Figure 20: CanGrow Properties

Vertical Text

Have you ever needed to display your report information vertically, either top-to-bottom or bottom-to-top, rather than left- to-right? There is some support for this in reporting services. For example, you can set the WritingModeproperty of your textbox to tb-rl, as shown in Figure 21.


Figure 21: Setting the WritingMode property of a text box

As a result, the information in the textbox will display top-to-bottom, as shown in Figure 22.
 

Figure 22: Top-to-bottom vertical text

Displaying your text bottom-to-top is a little trickier; you need to create an image and either set the background image of the control to the generated image, or use an image control. Let's take a look at an example. Again, you can either work through the following steps, or download the completed report, VerticalText.rdl.
What is required is a function, shown in listing 2, that will take the text passed in, measure it, and generate an image of appropriate size with the text displayed bottom-to-top.

Shared Function LoadImage(ByVal text As String) As Byte()
  Dim bmp As New System.Drawing.Bitmap(1, 1)
  Dim graphic As System.Drawing.Graphics =System.Drawing.Graphics.FromImage(bmp)
  Dim font As New System.Drawing.Font("Arial", 10)
  Dim width As Integer = graphic.MeasureString(text, font).Width
  Dim height As Integer = graphic.MeasureString(text, font).Height

  bmp = New System.Drawing.Bitmap(height, width)
  graphic = System.Drawing.Graphics.FromImage(bmp)
  graphic.Clear(System.Drawing.Color.White)
  graphic.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias
  graphic.TranslateTransform(0, width)
  graphic.RotateTransform(270)
  graphic.DrawString(text, font, New System.Drawing.SolidBrush(System.Drawing.Color.Black), 0, 0)
  graphic.Flush()

  Dim ms As New IO.MemoryStream
  bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)

  Return ms.ToArray()
End Function


Listing 2: The LoadImage Function

On the menu bar in Visual Studio, select Report | Report Properties and then paste the above code into the "Code" tab, as shown in Figure 23.


Figure 23: The LoadImage function for displaying vertical text

Next, you will need to add a reference to the System.Drawing namespace, in order to access the basic graphics functionality. Click the "References tab" of the dialog and then the browse ("..") button. Locate the System.Drawingassembly and click "Add". The reference will be added, as shown Figure 24.

 

Figure 24: Adding a reference to Systme.Drawing

Add an image control to the design surface, and then set the MIMEType property to image/jpeg, the Source property to Database, and the Value property to =Code.LoadImage("Hello World"),  as shown in Figure 25. Notice that the value property uses the LoadImage function in our embedded code.


Figure 25: Setting the image control properties

When rendered, the report looks as shown in Figure 26.

 

Figure 26: The rendered report, with top-to-bottom and bottom-to-top vertical text

Natively, SSRS does not allow for text to be displayed at an angle except for in some charts. If you can figure out how to modify the code for the LoadImage function so that it displays the text at an angle and generates an image, you would have a solution for the issue of angled text as well!

Report Data in Header/Footer

Reporting Services does not provide out of-the-box support for use of information from your queries in Page Headers and Footers. There are two ways around this.
The first way is to create controls in the body of your report, holding the values you need to display in the header and/or footer. You can set these controls to "hidden", and place them in some out-of-the-way place, towards the bottom of the report. Then, you can set expressions on controls in your header and footer sections to the value of the control in the body of your report.
In the following example, shown in Figure 27, I placed a textbox control in the body of the report named "textbox1", with a value of "Hello World". In the header section, I placed a textbox with a value of "=ReportItems!textbox1.Value". I then copied the control in the header section and pasted it into the footer section.


Figure 27: Display report data in headers and footers, using a hidden control in the body

If you preview this report, the value of "textbox1" will be displayed in the header and footer, as shown in Figure 28.


Figure 28: Three times Hello World

A slightly cleaner option, in my opinion, is to create a public function that can be called to set the value of a variable, which can then be used in any or all sections of the report body, header, and footer. Figure 29 shows the embedded code that creates this SetReportTitle function, containing the _Title variable.


Figure 29: The SetReportTitle function.

In this example, you can then simply set the value of the hidden textbox in the body of your report to "=Code.SetReportTitle("Report Title")". This calls our function and sets the value of the _Title variable to Report Title.
Now, you can set the value of any control in the header or footer to "=Code._Title". The variable can be used in any or all sections of the report body, header, and footer.

Missing Data in CSV/XML Exports

Is some of your data not getting exported to the data export formats of CSV or XML? Reporting Services, by default, has all data controls set to auto-output on export. This means that the rendering extension whether CSV or XML determines what gets exported. When exporting to the data specific rendering extensions, the extension determines what to export, which in most cases means that tabular data gets exported but not data determined to be informational. There is a way around this feature.
When you click on a control that contains data that you want to export, you should set the propertyDataElementOutput to "Output", as shown in Figure 30.


Figure 30: Setting the DataElementOutput property in preparation for export to CSV or XML.

Alternatively, you can also set this option by right-clicking the control and selecting properties. Once the properties dialog is displayed go to the "Data Output" tab and select the "Yes" option under the "Output" section, as show in Figure 31.


Figure 31: Setting the DataElementOutput property from the Data Output tab
By setting this property to "output", it ensures that your information will get exported. These Data Output options are used only by the CSV and XML rendering extensions. All other built-in formats are exported based on layout and don't use the Data Output settings.

Template Reports

Do you use a predefined layout when you start work on a new report? Do you want to be able to add your report templates to Visual Studio through the "Add New Item" feature? Well, as luck would have it, it's pretty easy to override the built-in template, or add your own templates.
In order to do this, simply navigate to Visual Studio's ReportProject directory, in Windows Explorer:
C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\ProjectItems\ReportProject
Note that this path should be accessible if you are using a default installation of Visual Studio. If not, then you'll need to amend the path as appropriate.
This ReportProject folder is the one in which VS stores the Report.rdl file that is used as the default template when you add a new report to your project, as shown in Figure 32.


Figure 32: The default Report.rdl file is stored in the ReportProject folder.
You can replace this default Report.rdl file with your own template, or simply add your own templates to the same folder. In this example, I've added a landscape and a portrait template to the directory as shown in Figure 33.


Figure 33: Adding custom templates
Now, when I choose to add a new item in Visual Studio, my report "templates" are available to be selected, as shown in Figure 34.


Figure 34: The Portrait and Landscape template are available when creating new reports
Note that the "My Templates" area you see in Figure 34 uses a specialized zip structure with some special code to setup how the template is to be used. My report templates are simply "base layouts" for Portrait and Landscape reports that I use to keep things standard. You can obtain the two example templates, PortraitTemplate.rdl andLandscapeTemplate.rdl, form the code download file.

Using the Reporting Services Database

Some report developers don't realize that there are two databases that you can use to lookup or analyze reporting services information. It's often useful to write your own reports, based on information stored in these databases.
The first database is ReportServer, which is used by the Report Services to store all the information about reports that have been uploaded to the report manager. Information such as the report catalog, settings, and security are all stored within the ReportServer database.  The database ReportServerTempDB stores temporary information such as report snapshots, user sessions, and report execution information.
I have three examples of useful reports created from the ReportServer database. The first report is what I call theReport Index. It provides a list of all the items in the reporting services catalog, with links to render each report in the catalog, as shown in Figure 35. This can prove to be useful as it allows your report users to run just one report and get a list of all reports, without having to navigate through the report manager.


Figure 35: The Report Index report

I provide an example Report Index.rdl report as part of the code download with this article. You'll have to point the report to your ReportServer database.
The second report, Report Usage, is basically a metrics-type report, providing details of reports that are being executed and how many times per month. The ReportServer database contains a table called ExecutionLog that, by default, stores every report execution for 60 days. You can update the setting ExecutionLogDaysKept in tableConfigurationInfo to allow for more than 60 days of execution tracking. Again, you can obtain the Report Usage.rdlfile from the download file, and an example of the report is shown in Figure 36.


Figure 36: The Report Usage report

The third report, Report Users, is similar to the Report Usage report. Report Users report is basically a metrics-type report, providing details of which users are executing the reports.  Again, you can obtain the Report Users.rdlfile from the download file, and an example of the report is shown in Figure 37.


Figure 37: The Report Users report

You will need to point all the report mentioned in this section to your ReportServer database.

What has SSRS 2008 fixed?


The challenges that I've covered in this article are ones for which I've managed to finds workable solutions. While using SSRS 2005, I've encountered other challenges for which I still have not found viable solutions, without investigating 3rd party tools. An example would be Rich Text formatting. In SSRS 2005 if you wanted to use Rich Text you have three options none of which are natively supported. You could design your own custom control, generate an image, or buy 3rd party controls.
With SSRS 2208, Microsoft has itself made some 3rd party acquisitions that have made the report developer's life a little easier. For example, Microsoft acquired Dundas Data Visualization and so new data visualization controls, such as Charts and Gauges, are now built-in to reporting services. Microsoft also acquired the OfficeWriter technology from SoftArtisans, Inc., which added Word export and support for Rich Text.
Within Reporting Services, improvements have been made for report authoring, report processing and rendering, programmability, and architecture. Based on the challenges/solutions discussed in this article, the following issues have been specifically addressed in SSRS 2008:
Merged cell issues – The rich text control alleviates some of the merged cell issues when exporting to Excel. Now, you can have one control with multiple formatting options and expressions.
Report data in Header and Footer – Variables have been introduced into Reporting Services that can be global or scoped to groups. You no longer have to hide controls in the body of your report to get data to display in the header and footer sections of your reports. If you don't want to use variables, you can also now use data directly in the header and footer with certain controls.
Report Pagination and rendering– there have been numerous improvements in this area:
  • New properties have been added to allow greater control over how your report is rendered.
  • Null values are now explicit giving you more control while working with nulls.
  • The Tablix control, basically the Table, Matrix, and List controls rolled into one, has drastically improved report rendering capabilities.
  • Visualization improvements for charts and gauges mean they are far superior to the charting capability available out of the box in SSRS 2005
  • The CSV rendering extension has been revamped to work differently depending on the purpose of the export, whether it's for Excel or for application consumption. Overlapping report items should no longer give warnings but may get adjusted automatically when rendered. This reduces pagination problems.
You can get more information about new features in SSRS 2008 from the Microsoft site:
Finally, it's well worth reviewing the list of breaking changes in SSRS 2008, as they may cause some headache and issues in your environment:
You'll probably uncover most of the issues when deploying and configuring the ReportServer. A lot of the configuration options have been removed and/or consolidated. Most significantly, SSRS 2008 no longer relies on IIS, and instead uses Handlers and Routers to work with HTTP.sys directly.

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More