DOWNLOAD THE CODE:
Download the Code 92723.zip

SQL Server Reporting Services gives you an inexpensive way to deliver Analysis Services data to business users. The powerful features in Reporting Services can let you customize your report delivery to give users drilldown capability and let them flexibly change data views to get the information they need in the format they can use best. Because almost every Reporting Services property can be an expression, you can modify reports in a host of ways, such as changing the displayed names of measures, the format of individual measures in the grid, and so on. These modifications greatly increase the number and types of reports that you can use to bring value to your business.

In “Delivering Analysis Services Data with Reporting Services” (July 2006, InstantDoc ID 50204), we walked through an example that shows how you can use SQL Server 2000 Reporting Services with Analysis Services 2000 to deliver data from a warehouse to an entire organization. You can also apply the examples in that article and in this one to SQL Server 2005 and Reporting Services 2005. The example report in the July article uses an MDX statement that pulls data from Analysis Services, then displays those results in a matrix control in a report. We added interactivity to the report, giving users the ability to expand and collapse regions so that they can drill down to see different levels of data. And we parameterized the reports by using a filter on the matrix control.

In this article, we take the abilities of Reporting Services 2000 a step further by modifying our report so that it displays the measures on rows instead of columns, giving users a way to change their view of the data. This capability can be important when reports need to show lots of measures and use dimensions to act as slicers of the data. For example, a report that shows several measures for a single employee or single product doesn’t need to have the employee or product on either the rows or columns. Therefore, we’ll see how to put the measures on the rows and another dimension, time, on the columns, while slicing by another dimension. We also explore how to parameterize the MDX query and apply formatting to the values.

Another Dimension of Reporting Service
First, let’s review several important aspects of how Reporting Services works with multidimensional data. First, Reporting Services 2000 doesn’t include a graphical query tool for working with Analysis Services data. Therefore, you have to manually code the MDX statement that delivers Analysis Services data to your report. You can preview the results in the grid on the Data tab of a report.

Second, Reporting Services doesn’t deal well with the results of an MDX query, which is a multi-dimensional data object called a cellset. Instead, Reporting Services must flatten the cellset to a two-dimensional recordset, putting all the values on rows and columns. Flattening the recordset causes an interesting side effect: It creates fields for values at all levels higher than the level requested in the query. So if the query calls for individual days, then the month, quarter, and year values are specified as well—providing that’s how the Time dimension hierarchy is structured.

Finally, the MDX statements that Reporting Services uses are different from the MDX used by most other tools. Because the cellset is flattened, the measure data is typically put in whatever dimension and member is specified on the Columns axis of the query. Other dimensions are put into the Rows and Pages axes, as the code in Listing 1 shows. An alternative but equivalent syntax, which Listing 2 shows, uses a Crossjoin function to put the dimensions from the Rows and Pages axes on the Rows axis.

Building a Report with Measures on the Rows
In most Reporting Services reports that use Analysis Services as a data source, the MDX query puts the measures on the Columns axis in the MDX query, and in the Reporting Services matrix control, the Measures field appears in the Data textbox. However, sometimes business requirements call for the measures to be listed on the rows—for example, when a company seeks to measure the results of an individual against a host of performance metrics. How do you make this change to your report? The answer seems simple enough: Change the query so that measures are on the Rows axis. However, you must remember that the value on the report is written in the Columns axis in the MDX expression that will be consumed by Reporting Services. So what do you put into the Columns axis of the query if measures are moved to the Rows axis?

In such a case, you usually put a single value in the Columns axis. This value might be the All level for products, a single category (e.g., Drinks), or a single product (e.g., Beer). Any other dimension, typically Time, can be used on the Pages axis.

For this example, let’s create a new report named Measures on Rows in Visual Studio. To see the finished example’s files, you can download the .zip file. We won’t use the New Report Wizard because of a lack of control in setting up the report. We’ll use the Foodmart 2000 cube as the data source and assume that the business wants to examine the Store Sales and Store Cost measures for the Beer and Wine product category by month. Listing 3 shows the MDX statement that will return the data we need.

When you’re running Listing 3’s MDX statement on the Data tab, you get the correct data, and a report designed with a matrix control will work correctly. Unfortunately, this query isn’t particularly flexible because it’s always based on the category Beer and Wine. When you click the Layout tab and look at the Fields window, you see a field called Product_All_Products_Drink_Alcoholic_Beverages_Beer_and_Wine. In addition to being unwieldy, the field name now contains the product category specified in the query. You can add this field to the Data textbox on a matrix and it will work, but if the report author modifies the query to look at a different category, the field name changes to that of the new category. The report, however, is still looking for the old name. So every time you change the category in the query, you break the report.

Clearly, changing the value in the query and modifying the report in Layout every time you want to look at a different category is cumbersome. Let’s see how to get a field name that doesn’t change, even if the report author wants to change the category or choose a brand, product, or any other level in the Product dimension. We’ll learn how to parameterize this value later in this article.

To establish a fixed name for the field in the report, you need to create an MDX calculated member. In MDX, you create a calculated member by using the WITH MEMBER clause of a query. Listing 4 shows how you’d modify Listing 3’s query to use a calculated member. When you create the calculated member [Product].[Prod], the report will now always see a member with that name regardless of the value typed into the AS clause of the expression. This means that the report author can change the value of the report any time without having to modify the report in the Layout tab. Adding the calculated member also paves the way for adding a parameter to the query, which we’ll demonstrate in a moment.

In addition to dealing with the Product dimension, the query specifies two measures: Store Sales and Store Cost. Any number of measures could be listed, and regardless of how many are added, the Fields list on the layout tab shows only a single value: Measures_MeasuresLevel. Regardless of how many measures are returned, the Fields window shows only this single field, and the matrix will automatically grow to show all the measures that the MDX query returns, displaying one measure per row.

To design this example report, you use a matrix control in Reporting Services, as Figure 1 shows. You put the Time values in the Columns textbox, and you can add multiple levels of time and set the group to let users expand and collapse data. Then, you add Measures_MeasuresLevel field to the Rows textbox. Finally, you add the Product_Prod field to the Data textbox. Note that you need to change the formula in the Data textbox from its default so that instead of starting with the First function, the formula starts with the Sum function. The First function in the Rows text-box is acceptable because it’s simply returning the name of each measure, not its value.

If it seems strange to put the [Product].[Prod] calculated member in the Data textbox, remember that Reporting Services flattens the cellset into a rowset and the numerical values get put into whatever the MDX statement shows is on the Columns axis. Therefore, placing the Product_Prod field in the Data textbox of the matrix reveals the correct numbers, and the names of the measures fill the Rows textbox.

   Prev. page   [1] 2     next page
 
 

ADS BY GOOGLE