What I'll be describing in this article is how you can use OfficeWriter and
Reporting Services to generate Excel workbooks which use these new functions
so that after you've exported your data to Excel you can ensure it stays
synchronised with the data in your cube. I'm going to assume you already
know how OfficeWriter works - if you don't, you may want to take a look
at some of the online documentation available on the SoftArtisans web
site here: http://officewriter.softartisans.com.
First of all, let's take a look at the kind of workbook we want to be
able to generate. Open Excel 2007 and click on the Data tab in the ribbon
bar. To open a connection to an Analysis Services cube go to the 'Get
External Data' group, click on the 'From Other Sources' button and select
'From Analysis Services' in the dropdown menu. Type in the name of your
Analysis Services server, click Next, select the database you want to
connect to and then a cube, click Next again, type in a suitably friendly
name for your connection and click Finish. Once you've done this, an empty
pivot table will appear and you can drag and drop dimensions and measures
to query the cube; after doing so then click on a cell in the pivot table
so that the Option tab appears in the ribbon. Then click on the 'OLAP
Tools' button in the 'Tools' group and select 'Convert to Formulas' in
the dropdown menu. The pivot table will then disappear and in its place
you'll see cells containing the same values that were in the pivot table,
but which instead use the new 'cube' functions to retrieve their data.
Generating this kind of report in Reporting Services will be our goal.
To start, we need a Reporting Services report which uses data from Analysis
Services. If you've got one handy then you can use that - if not, it's
quite easy to use the wizard to generate a report for you. Next, open
up the report and go to the data tab and you'll find the MDX SELECT statement
that's used to query the cube. Our first major problem is going to be
how to translate an MDX query like this into a group of Excel cube functions,
and to do this we're going to need to understand how MDX addresses values
in a cube.
Take the following MDX query that can be run against the AdventureWorks
cube:
SELECT [Measures].[Internet Sales Amount] ON COLUMNS ,
[Date].[Calendar Year].[Calendar Year].MEMBERS ON ROWS
FROM
[Adventure Works]
WHERE([Product].[Category].&[1])
It displays the measure Internet Sales Amount on the columns axis, all
Calendar Years on rows and slices the data by the Product Category Bikes.
The topmost cell in the result set therefore displays the value of Internet
Sales Amount for Calendar Year 2001 for Bikes and this value can be addressed
directly in MDX using a tuple of the form:
([Measures].[Internet Sales Amount], [Date].[Calendar].[Calendar Year].&[2001],
[Product].[Category].&[1])
The Excel function to get a value from the cube is CUBEVALUE(), and you
can use this function to get the same value in an Excel cell as follows:
=CUBEVALUE("MyConnectionName"," ([Measures].[Internet Sales Amount],
[Date].[Calendar].[Calendar Year].&[2001], [Product].[Category].&[1])
")
Getting the tuple that represents the value for each cell in a query
isn't straightforward. You could create an MDX expression which returned
the unique name of the current member on each hierarchy of each dimension,
but if you were using a lot of hierarchies in your query the expression
could become very long and be difficult to maintain. The most elegant
solution is to write an Analysis Services stored procedure and luckily
there's one already available called FindCurrentTuple() which does the
job.
You can find it in the "Analysis Services Stored Procedure Project" which
can be downloaded here:
http://www.codeplex.com/ASStoredProcedures
Please Note: At the time of writing, this function isn't included in
either of the downloads for the last major release, 1.0 Beta, shown on
the Release tab of the project site. In order to use it you need to download
the latest version of the source code, compile it and then register the
resulting ASSP.dll on your Analysis Services server.) You can then use
it with your original query by adding a WITH clause and declaring a calculated
cell in it as follows:
WITH CELL CALCULATION [ShowTuple] FOR '*' AS
'"=CUBEVALUE(""MyConnectionName"",""" + ASSP.FINDCURRENTTUPLE() + """)"'
SELECT [Measures].[Internet Sales Amount] ON COLUMNS ,
[Date].[Calendar Year].[Calendar Year].MEMBERS ON ROWS
FROM
[Adventure Works]
WHERE([Product].[Category].&[1])
The results of this query look like this: |