Binding an Excel table to the results of an MDX query
I like using Excel tables, and one of the things that has mildly annoyed me in the past is that you can’t bind the results of an MDX query to an Excel table in the way you can do with a SQL query. I mean, pivot tables are all very well, but sometimes a plain old table is a better fit – for example, think of the cool stuff the data mining addin works can do with tables. Luckily, with a bit of hacking, you can do it… and here’s how.
The trick is to create a .odc file that contains the MDX query you want. What I did was create an odc file for a SQL query and then edit it in Notepad so the connection string pointed to SSAS and the SQL query was replaced with an MDX query. To do this, open Excel and go to the Data tab, click From Other Data Sources and then choose From Data Connection Wizard. Choose Other/Advanced on the first step, then create a connection to the OLEDB source of your choice so long as it isn’t an SSAS source. The resulting odc file will then be saved to the My Data Sources; go there and edit it in Notepad.
The hacking is fairly easy to do – a quick inspection of the odc file format reveals that there’s a lot of junk and the important stuff is contained in a bit of XML near the beginning. Here’s an example of what that XML needs to be for an MDX query:
1: <xml id=docprops><o:DocumentProperties
2: xmlns:o="urn:schemas-microsoft-com:office:office"
3: xmlns="http://www.w3.org/TR/REC-html40">
4: <o:Name>SSAS Query Test</o:Name>
5: </o:DocumentProperties>
6: </xml><xml id=msodc><odc:OfficeDataConnection
7: xmlns:odc="urn:schemas-microsoft-com:office:odc"
8: xmlns="http://www.w3.org/TR/REC-html40">
9: <odc:Connection odc:Type="OLEDB">
10: <odc:ConnectionString>Provider=MSOLAP.4;Integrated Security=SSPI;
11: Persist Security Info=True;Data Source=localhost;
12: Initial Catalog=Adventure Works DW 2008</odc:ConnectionString>
13: <odc:CommandType>MDX</odc:CommandType>
14: <odc:CommandText>select {[Measures].[Internet Sales Amount],
15: [Measures].[Internet Tax Amount]} on 0,
16: [Date].[Calendar Year].members on 1 from [Adventure Works]
17: </odc:CommandText>
18: </odc:Connection>
19: </odc:OfficeDataConnection>
20: </xml>
Once you’ve done this, you can go back to Excel, go to the Data tab and click Existing Connections to open the file:
Choose to view this data in a table, and you get something that looks like this in your worksheet:
Incidentally, since you can query Analysis Services with a basic dialect of SQL, you can also bind an entire dimension or measure group (which are treated as ‘tables’ in SSAS SQL) or the results of a DMV to a table. Here’s an example of what the xml for the odc file looks like:
1: <xml id=docprops><o:DocumentProperties
2: xmlns:o="urn:schemas-microsoft-com:office:office"
3: xmlns="http://www.w3.org/TR/REC-html40">
4: <o:Name>SSAS Table Test</o:Name>
5: </o:DocumentProperties>
6: </xml><xml id=msodc><odc:OfficeDataConnection
7: xmlns:odc="urn:schemas-microsoft-com:office:odc"
8: xmlns="http://www.w3.org/TR/REC-html40">
9: <odc:Connection odc:Type="OLEDB">
10: <odc:ConnectionString>Provider=MSOLAP.4;Integrated Security=SSPI;
11: Persist Security Info=True;Data Source=localhost;
12: Initial Catalog=Adventure Works DW 2008</odc:ConnectionString>
13: <odc:CommandType>Table</odc:CommandType>
14: <odc:CommandText>Adventure Works.$Source Currency</odc:CommandText>
15: </odc:Connection>
16: </odc:OfficeDataConnection>
17: </xml>
In this example I’m retrieving the entire contents of the Adventure Works Source Currency dimension. The output looks like this:
Since we’re all going to be doing a lot more reporting in Excel in the future, hopefully this tip will turn out useful to someone creating dashboards in Excel using SSAS data.
UPDATE: Greg Galloway just told me about another way of doing this: "If you have an ODC file you build a PivotTable, then if you drillthrough on a cell, it brings up a QueryTable with the drillthrough results. At that point, you can right click on the QueryTable and edit the query. It’s not elegant, but at least you don’t have to create an ODC file per query."

[...] Binding an Excel table to the results of an MDX query « Chris Webb's BI Blog http://cwebbbi.wordpress.com/2009/12/18/binding-an-excel-table-to-the-results-of-an-mdx-query/ [...]
SmartPivot - Little Excel Add-On for Olap Pivot Tables, Easily create Excel dashboards from olap cubes - Rui Quintino BI -
December 5, 2010 at 10:58 pm
[...] Binding an Excel table to the results of an MDX query « Chris Webb’s BI Blog http://cwebbbi.wordpress.com/2009/12/18/binding-an-excel-table-to-the-results-of-an-mdx-query/ [...]
SmartPivot – Little Excel Add-On for Olap Pivot Tables, Easily create Excel dashboards from olap cubes « Rui Quintino Blog
December 18, 2010 at 9:40 pm
Thanks for the solution, but it is not correctly working. to get it working i also needed to change the connection string from Provider=MSOLAP.4;Integrated Security=SSPI;Persist Security Info=True;Data Source=server_name;Initial Catalog=catalog_name
to Provider=MSOLAP.4;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=catalog_name;Data Source=server_name;Safety Options=2;Locale Identifier=1031
AN_AS2008
January 12, 2011 at 3:26 pm
[...] Binding an Excel table to the results of an MDX query « Chris Webb’s BI Blog http://cwebbbi.wordpress.com/2009/12/18/binding-an-excel-table-to-the-results-of-an-mdx-query/ [...]
SmartPivot – Little Excel Add-On for Olap Pivot Tables, Easily create Excel dashboards from olap cubes,Auto Synchronize Excel Pivot Tables filters « Rui Quintino Blog
January 12, 2011 at 4:23 pm
[...] a comment » One of the more popular posts on my blog is one I wrote just over a year ago on binding the results of an MDX query to a table inside Excel. I was thinking about it again recently when I was looking at the list of DMVs (=Dynamic Management [...]
Querying PowerPivot DMVs from Excel « Chris Webb's BI Blog
February 23, 2011 at 5:00 pm
An alternative Example using direct vba automation to accomplish the MDX Query to ListObject/QueryTable
Option Explicit
Sub Create_Report_Based_On_ListObject_QueryTable()
‘The connection string.
Const stCon As String = “OLEDB;Provider=MSOLAP.4;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=CUBENAME;Data Source=SERVERNAME;MDX Compatibility=1;Safety Options=2;MDX Missing Member Mode=Error”
‘The MDX Expression Can be any MDX Expression but here is an example.
Const stMDX As String = “SELECT NON EMPTY ({({[Date].[Calendar Quarter Name].[All].children})}) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS FROM [Breathout Test] WHERE ([Region].[Parent RegionKey].&[10],[DataRow].[Parent DataRowKey].&[99],[Measures].[Sales Amount Quarterly Hidden]) CELL PROPERTIES VALUE, FORMAT_STRING, LANGUAGE, BACK_COLOR, FORE_COLOR, FONT_FLAGS”
‘Excel variables.
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Dim rnStart As Range
Dim qtTable As QueryTable
Set wbBook = ActiveWorkbook
Set wsSheet = ActiveSheet
Set rnStart = wsSheet.Range(“A1″)
‘The creation of the ListObject and the associated QueryTable.
Set qtTable = wsSheet.ListObjects.Add( _
SourceType:=xlSrcQuery, _
Source:=stCon, _
Destination:=rnStart).QueryTable
‘qtTable.ListObject.ShowHeaders = False
‘Populate some major properties of the QueryTable.
With qtTable
.CommandText = stMDX
.CommandType = xlCmdDefault
‘In order to see the output for the first time
‘we need to use the Refresh command.
.Refresh
.RefreshOnFileOpen = True
End With
End Sub
Scott Gall
August 17, 2011 at 8:20 pm
Thanks!
Chris Webb
August 18, 2011 at 8:28 pm
Hi Scott,
I have copied your code and substituted the Cube Name, the Data Source and the MDX expression with my own ‘values’ however I am getting the following error:
“Run TIme error ’1004′
Application-defined or object-defined error”
when the code reaches:
.refresh
Any ideas on what may be causing the error?
Any help would be greatly appreciated.
Thanks
Carl
Carl Thompson
August 8, 2012 at 2:19 pm
Hi again,
Never mind.
As per AN_AS2008′s post of Jan 2011 I needed to include the following:
;Locale Identifier=1031
Thanks
Carl Thompson
August 8, 2012 at 2:24 pm
[...] tricks discussed here can be used to create an Excel table bound to a DAX query; in particular it’s very easy to use [...]
Detail level reporting with DAX « Chris Webb's BI Blog
September 6, 2011 at 12:11 pm
[...] Webb wrote this post: Binding an Excel table to the results of an MDX query. In a comment at the bottom, Scott Gall suggested using VBA. I want to take this one step [...]
Binding an Excel table to the results of an MDX query « Christian Wade's Blog
May 19, 2012 at 2:09 am
[...] When binding the results of an MDX query to a table in Excel, as described here [...]
Introduction to MDX for PowerPivot Users, Part 1 « Chris Webb's BI Blog
October 7, 2012 at 11:47 pm
[...] PivotTables (either with or without named sets) or Excel cube functions. Having said that, the post I wrote a few years ago about binding a table in Excel to an MDX query has been one of the most [...]
Introduction to MDX for PowerPivot Users, Part 5: MDX Queries « Chris Webb's BI Blog
December 18, 2012 at 3:41 pm