<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Ramunas Balukonis Blog</title>
	<atom:link href="http://ssas-info.com/RamunasBalukonisBlog/feed" rel="self" type="application/rss+xml" />
	<link>http://ssas-info.com/RamunasBalukonisBlog</link>
	<description>Ramunas Balukonis Blog</description>
	<pubDate>Wed, 21 Nov 2007 10:33:39 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Creating roles from Active Directory grups</title>
		<link>http://ssas-info.com/RamunasBalukonisBlog/32_creating-roles-from-active-directory-grups</link>
		<comments>http://ssas-info.com/RamunasBalukonisBlog/32_creating-roles-from-active-directory-grups#comments</comments>
		<pubDate>Wed, 21 Nov 2007 10:33:39 +0000</pubDate>
		<dc:creator>Ramunas Balukonis</dc:creator>
		
		<category><![CDATA[SSAS]]></category>

		<guid isPermaLink="false">http://ssas-info.com/RamunasBalukonisBlog/?p=32</guid>
		<description><![CDATA[This script could help Analysis Services administrators to load and configure big amount of roles. Supose,  I have to configure  100+ roles for every shop in you enterprise. Every shop have his own group in Active Directory:    active Directory adminsitrator already created AD groups for shops with description &#8220;new&#8221;.   In AS database I [...]]]></description>
			<content:encoded><![CDATA[<p>This script could help Analysis Services administrators to load and configure big amount of roles. Supose,  I have to configure  100+ roles for every shop in you enterprise. Every shop have his own group in Active Directory:    active Directory adminsitrator already created AD groups for shops with description &#8220;new&#8221;.   In AS database I have store dimension and &#8220;stor bkey&#8221; attribute for each shop.<br />
My task is loop via Active directory groups, look for group description &#8220;new&#8221;, then create role in Analysis Services, add  AD group  as role member, grant read permission on cube, define allowed set to his own shop, default member and Visual Totals. After I need to delete description &#8220;new&#8221;.<br />
1&#8217;st part of script  looping via AD groups in container and look for description &#8220;new&#8221; and then call procedure CreateRole.   </p>
<blockquote><p><font size="2"><font size="2" color="#0000ff">Public</font><font size="2"> </font><font size="2" color="#0000ff">Sub</font><font size="2"> Main()<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> ADContainer </font><font size="2" color="#0000ff">As</font><font size="2"> System.DirectoryServices.DirectoryEntry = _<br />
</font><font size="2" color="#0000ff">New</font><font size="2"> System.DirectoryServices.DirectoryEntry(</font><font size="2" color="#a31515"><a href="ldap://OU=MyGruops3,OU=MyGruops2,OU=MyGruops1,DC=MyEnterprise,DC=int/">LDAP://OU=MyGruops3,OU=MyGruops2,OU=MyGruops1,DC=MyEnterprise,DC=int</a></font><font size="2">)<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> ADGroup </font><font size="2" color="#0000ff">As</font><font size="2"> System.DirectoryServices.DirectoryEntry<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> sGroupName </font><font size="2" color="#0000ff">As</font><font size="2"> </font><font size="2" color="#0000ff">String</font></font><font size="2"><font size="2" color="#0000ff">For</font><font size="2"> </font><font size="2" color="#0000ff">Each</font><font size="2"> ADGroup </font><font size="2" color="#0000ff">In</font><font size="2"> ADContainer.Children<br />
</font><font size="2" color="#0000ff">If</font><font size="2"> ADGroup.Properties(</font><font size="2" color="#a31515">&#8220;Description&#8221;</font><font size="2">).Value = </font><font size="2" color="#a31515">&#8220;new&#8221;</font><font size="2"> </font><font size="2" color="#0000ff">Then<br />
</font><font size="2">sGroupName = ADGroup.Properties(</font><font size="2" color="#a31515">&#8220;cn&#8221;</font><font size="2">).Value<br />
CreateRole(sGroupName)<br />
ADGroup.Properties(</font><font size="2" color="#a31515">&#8220;Description&#8221;</font><font size="2">).RemoveAt(0)<br />
ADGroup.CommitChanges()<br />
</font><font size="2" color="#0000ff">End</font><font size="2"> </font><font size="2" color="#0000ff">If<br />
</font><font size="2" color="#0000ff">Next<br />
</font><font size="2">Dts.TaskResult = Dts.Results.Success<br />
</font><font size="2" color="#0000ff">End</font><font size="2"> </font><font size="2" color="#0000ff">Sub</font></font></p></blockquote>
<p>Rest of script - configuring role:</p>
<blockquote><p><font size="2"><font size="2" color="#0000ff">Private</font><font size="2"> </font><font size="2" color="#0000ff">Sub</font><font size="2"> CreateRole(</font><font size="2" color="#0000ff">ByVal</font><font size="2"> sGroupName </font><font size="2" color="#0000ff">As</font><font size="2"> </font><font size="2" color="#0000ff">String</font><font size="2">)<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> RoleMember </font><font size="2" color="#0000ff">As</font><font size="2"> </font><font size="2" color="#0000ff">String</font><font size="2"> = </font><font size="2" color="#a31515">&#8220;MyEnterprise\&#8221; </font><font size="2">  &amp; sGroupName<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AllowedMember = </font><font size="2" color="#a31515">&#8220;[store].[stor bkey].&amp;["</font><font size="2"> &amp; sGroupName &amp; </font><font size="2" color="#a31515">"]&#8221;<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMOServer </font><font size="2" color="#0000ff">As</font><font size="2"> Microsoft.AnalysisServices.Server = </font><font size="2" color="#0000ff">New</font><font size="2"> Microsoft.AnalysisServices.Server<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMODatabase </font><font size="2" color="#0000ff">As</font><font size="2"> Microsoft.AnalysisServices.Database = </font><font size="2" color="#0000ff">New</font><font size="2"> Microsoft.AnalysisServices.Database<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMOCube </font><font size="2" color="#0000ff">As</font><font size="2"> Microsoft.AnalysisServices.Cube<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMORole </font><font size="2" color="#0000ff">As</font><font size="2"> Microsoft.AnalysisServices.Role<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMODatabasePermission </font><font size="2" color="#0000ff">As</font><font size="2"> Microsoft.AnalysisServices.DatabasePermission<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMOCubePermission </font><font size="2" color="#0000ff">As</font><font size="2"> Microsoft.AnalysisServices.CubePermission<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMODimension </font><font size="2" color="#0000ff">As</font><font size="2"> Microsoft.AnalysisServices.Dimension<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMODimensionAttribute </font><font size="2" color="#0000ff">As</font><font size="2"> Microsoft.AnalysisServices.DimensionAttribute<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMOCubeDimensionPermission </font><font size="2" color="#0000ff">As</font><font size="2"> CubeDimensionPermission<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMOAttributePermission </font><font size="2" color="#0000ff">As</font><font size="2"> AttributePermission<br />
</font><font size="2" color="#0000ff">Dim</font><font size="2"> AMODimensionPermission </font><font size="2" color="#0000ff">As</font><font size="2"> DimensionPermission<br />
AMOServer.Connect(MyServer</font><font size="2">)<br />
AMODatabase = AMOServer.Databases(MyDatabase</font><font size="2">)<br />
AMOCube = AMODatabase.Cubes.GetByName(MyCube</font><font size="2">)<br />
AMORole = AMODatabase.Roles.FindByName(sGroupName)<br />
</font><font size="2" color="#0000ff">If</font><font size="2"> </font><font size="2" color="#0000ff">Not</font><font size="2"> AMORole </font><font size="2" color="#0000ff">Is</font><font size="2"> </font><font size="2" color="#0000ff">Nothing</font><font size="2"> </font><font size="2" color="#0000ff">Then<br />
</font><font size="2">AMODatabase.Roles.Remove(AMODatabase.Roles.GetByName(sGroupName).ID)<br />
</font><font size="2" color="#0000ff">End</font><font size="2"> </font><font size="2" color="#0000ff">If<br />
</font><font size="2">AMORole = AMODatabase.Roles.Add(sGroupName)<br />
AMORole.Members.Add(</font><font size="2" color="#0000ff">New</font><font size="2"> RoleMember(RoleMember))<br />
AMORole.Update()<br />
AMODatabasePermission = AMODatabase.DatabasePermissions.Add(AMORole.ID)<br />
AMODatabasePermission.Read = ReadAccess.Allowed<br />
AMODatabasePermission.Update()<br />
AMOCubePermission = AMOCube.CubePermissions.Add(AMORole.ID)<br />
AMOCubePermission.Read = ReadAccess.Allowed<br />
AMODimension = AMODatabase.Dimensions.GetByName(</font><font size="2" color="#a31515">&#8220;store&#8221;</font><font size="2">)<br />
AMODimensionAttribute = AMODimension.Attributes.GetByName(</font><font size="2" color="#a31515">&#8220;stor bkey&#8221;</font><font size="2">)<br />
AMOCubePermission.Update()<br />
AMODimensionPermission = AMODimension.DimensionPermissions.Add(AMORole.ID)<br />
AMOAttributePermission = AMODimensionPermission.AttributePermissions.Add(AMODimensionAttribute.ID)<br />
AMOAttributePermission.AllowedSet = </font><font size="2" color="#a31515">&#8220;{&#8221;</font><font size="2"> &amp; AllowedMember &amp; </font><font size="2" color="#a31515">&#8220;}&#8221;<br />
</font><font size="2">AMOAttributePermission.DefaultMember = AllowedMember<br />
AMOAttributePermission.VisualTotals = 1<br />
AMODimensionPermission.Update()<br />
</font><font size="2" color="#0000ff">End</font><font size="2"> </font><font size="2" color="#0000ff">Sub</font></font></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://ssas-info.com/RamunasBalukonisBlog/32_creating-roles-from-active-directory-grups/feed</wfw:commentRss>
		</item>
		<item>
		<title>Filtering Pivot Table by list of values (Excel 2007)</title>
		<link>http://ssas-info.com/RamunasBalukonisBlog/25_filtering-pivot-table-by-list-of-values-excel-2007</link>
		<comments>http://ssas-info.com/RamunasBalukonisBlog/25_filtering-pivot-table-by-list-of-values-excel-2007#comments</comments>
		<pubDate>Wed, 11 Jul 2007 11:37:50 +0000</pubDate>
		<dc:creator>Ramunas Balukonis</dc:creator>
		
		<category><![CDATA[SSAS]]></category>

		<guid isPermaLink="false">http://ssas-info.com/RamunasBalukonisBlog/?p=25</guid>
		<description><![CDATA[One of the missing features in SSAS we found is filtering by list of values. In most of clients (Excel, Panorama) you are able to set a filter for one or several items.  But filter cube by 300 items could be tricky task.   Let say we have a bussines task like: filter a Adventure Works cube by 300 different products. These 300 products spread in [...]]]></description>
			<content:encoded><![CDATA[<p>One of the missing features in SSAS we found is filtering by list of values. In most of clients (Excel, Panorama) you are able to set a filter for one or several items.  But filter cube by 300 items could be tricky task.   Let say we have a bussines task like: filter a Adventure Works cube by 300 different products. These 300 products spread in all Products categories hierarchy and depend to different product categories. To select 300 products you have to open Product hierarchy and check each item. To check 300 different items could be a tricky tasks, isn&#8217;t it? The solution - to find a way  programically select items.<br />
Using Excel 2007 you can filter Pivot Table items using &#8220;VisibleItemsList&#8221; property. Look for VBA code below.</p>
<blockquote><p>     Dim iTmp As Integer<br />
    Dim ProductKey As String<br />
    Dim ProductKeyArray() As String<br />
    iTmp = 2<br />
   <br />
    ProductKey = Excel.Worksheets(&#8221;Filter&#8221;).Cells(iTmp, 1).Value<br />
    While ProductKey &lt;&gt; Empty<br />
        ReDim Preserve ProductKeyArray(iTmp - 2)<br />
        ProductKeyArray(iTmp - 2) = &#8220;[Product].[Product Key].&amp;[" &amp; ProductKey &amp; "]&#8221;<br />
        iTmp = iTmp + 1<br />
        ProductKey = Excel.Worksheets(&#8221;Filter&#8221;).Cells(iTmp, 1).Value<br />
    Wend<br />
   <br />
    On Error Resume Next<br />
    Excel.Worksheets(&#8221;Data&#8221;).PivotTables(Excel.Worksheets(&#8221;Data&#8221;).PivotTables.Count).PivotFields( _<br />
        &#8220;[Product].[Product Key].[Product Key]&#8220;).VisibleItemsList = _<br />
        ProductKeyArray()</p></blockquote>
<p> To look how this works, download file  <a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/filterptsamplexlsm.zip" title="FilterPTSample.xlsm">FilterPTSample.xlsm</a> (rename zip to FilterPTSample.xlsm). Enable macros and data connection, change data connection to Adventure Works, put product keys on sheet &#8220;Filter&#8221;, down from &#8220;A2&#8243; and then press &#8220;Filter by product key&#8221;.  After filter was applied, in 1&#8217;st sheet (&#8221;Data&#8221;) , attribute Product Key and hierarchy &#8220;Product Categories&#8221; you have to see only products from sheet &#8220;Filter&#8221;. To clear filter, choose &#8220;Clear&#8221; from Data\Sort &amp; Filter box.</p>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/pt_before_filter.bmp" title="PTBeforeFilter"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/pt_before_filter.bmp" alt="PTBeforeFilter" /></a></p>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/productkeys.bmp" title="ProductKeys"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/productkeys.bmp" alt="ProductKeys" /></a></p>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/pt_after_filter.bmp" title="PTAfterFilter"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/pt_after_filter.bmp" alt="PTAfterFilter" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://ssas-info.com/RamunasBalukonisBlog/25_filtering-pivot-table-by-list-of-values-excel-2007/feed</wfw:commentRss>
		</item>
		<item>
		<title>Avoid setting IsAggregatable = False to dimension attributes</title>
		<link>http://ssas-info.com/RamunasBalukonisBlog/19_Avoid setting IsAggregatable = False to dimension attributes</link>
		<comments>http://ssas-info.com/RamunasBalukonisBlog/19_Avoid setting IsAggregatable = False to dimension attributes#comments</comments>
		<pubDate>Mon, 14 May 2007 12:16:49 +0000</pubDate>
		<dc:creator>Ramunas Balukonis</dc:creator>
		
		<category><![CDATA[SSAS]]></category>

		<guid isPermaLink="false">http://ssas-info.com/RamunasBalukonisBlog/?p=19</guid>
		<description><![CDATA[In my last article I described the situation when Analysis Services reproduces incorrect results with Default Member defined on dimension attributes. Very similar problems occurs when IsAggragatable =False to dimension attributes.
The IsAggregatable property controls show or hide the topmost (aggregatable) level of hierarchy. Let say, you do not want to show the (All) level for [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/bikes.jpg" title="Bikes"></a>In my last article I described the situation when Analysis Services reproduces incorrect results with Default Member defined on dimension attributes. Very similar problems occurs when IsAggragatable =False to dimension attributes.<br />
The IsAggregatable property controls show or hide the topmost (aggregatable) level of hierarchy. Let say, you do not want to show the (All) level for some of you hierarchies. As example, IsAggragatable =False for scenario attribute , scenario dimension  In Adventure Works database. Therefore this attribute does not have (All) level. But be careful setting IsAggragatable =False, there may be incorrect results in some circumstances using Excel 2007. Follow the steps to reproduce behaviour and get wrong results.</p>
<p>Set IsAggregatable = False to [Product]/[Product categories] attribute. Connect to cube and drag [Product categories] hierarchy on filter area, Gross Profit on values. You have to see the 1&#8217;st member from [Product categories] hierarchy: Accessories. Try changing filter values from Accessories to Bikes and then to both (Accessories and Bikes). When you select both, Bikes gross profit is not taked into account! Look below for screenchots and MDX generated by Excel 2007.</p>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/accessories.jpg" title="Accessories"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/accessories.jpg" alt="Accessories" /></a></p>
<blockquote><p>SELECT  FROM [Adventure Works] WHERE ([Product].[Product Categories].[Category].&amp;[4],[Measures].[Gross Profit])</p></blockquote>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/bikes.jpg" title="Bikes"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/bikes.jpg" alt="Bikes" /></a></p>
<blockquote><p>SELECT  FROM [Adventure Works] WHERE ([Product].[Product Categories].[Category].&amp;[1],[Measures].[Gross Profit])</p></blockquote>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/both.jpg" title="Both with multiselect"></a><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/both_isaggregatable.jpg" title="Both with multiselect"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/both_isaggregatable.jpg" alt="Both with multiselect" /></a></p>
<blockquote><p>SELECT  FROM (SELECT ({[Product].[Product Categories].[Category].&amp;[4],[Product].[Product Categories].[Category].&amp;[1]}) ON COLUMNS  FROM [Adventure Works]) WHERE ([Measures].[Gross Profit])</p></blockquote>
<p>I created BUG incident in Microsoft feedback, so please everyone that is interesting in IsAggregatable, vote for this case. <a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=277058">https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=277058</a> . Hope Microsoft will then pay more attention.</p>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/both.jpg" title="Both (Accessories and Bikes) with multiselect"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://ssas-info.com/RamunasBalukonisBlog/19_Avoid setting IsAggregatable = False to dimension attributes/feed</wfw:commentRss>
		</item>
		<item>
		<title>Avoid defining Default Member</title>
		<link>http://ssas-info.com/RamunasBalukonisBlog/14_avoid-defining-default-member</link>
		<comments>http://ssas-info.com/RamunasBalukonisBlog/14_avoid-defining-default-member#comments</comments>
		<pubDate>Wed, 09 May 2007 12:26:42 +0000</pubDate>
		<dc:creator>Ramunas Balukonis</dc:creator>
		
		<category><![CDATA[SSAS]]></category>

		<guid isPermaLink="false">http://ssas-info.com/RamunasBalukonisBlog/?p=14</guid>
		<description><![CDATA[Default Members are good thing in BI environment. You can define Default member as &#8220;Last month&#8221; in Date dimension, &#8220;Active&#8221; in status dimension and so on.
But be careful defining default members: Analysis Services returns incorrect results with default member in some circumstances. To reproduce buggy behaviour, open Adveture Works, define default member as [Road Bikes] subcategory in [...]]]></description>
			<content:encoded><![CDATA[<p>Default Members are good thing in BI environment. You can define Default member as &#8220;Last month&#8221; in Date dimension, &#8220;Active&#8221; in status dimension and so on.<br />
But be careful defining default members: Analysis Services returns incorrect results with default member in some circumstances. To reproduce buggy behaviour, open Adveture Works, define default member as [Road Bikes] subcategory in [Product].[Product Categories] hierarchy. First, set Category attribute default member to &#8220;[Product].[Category].&amp;[1]&#8221; or [Product].[Category].[Bikes], and then set &#8220;subcategory&#8221; default member to &#8220;[Product].[Subcategory].[Subcategory].&amp;[2]&#8221; or [Product].[Subcategory].[Subcategory].[Road Bikes].</p>
<p>From Excel 2007, connect to Adventure Works cube and put [Product].[Product Categories] in Filter area, Gross profit on data area. Try select [Road Bikes], [Mountain Bikes] or both ([Road Bikes], [Mountain Bikes]) in [Product].[Product Categories]. For multi-select Excel 2007 shows incorrect results, only default member is taked into account! See below screenshots and generated MDX.</p>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/roadbikes.jpg" title="Road Bikes"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/roadbikes.jpg" alt="Road Bikes" /></a></p>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/both.jpg" title="Both - multiselect"></a></p>
<blockquote><p>SELECT  FROM [Adventure Works] WHERE ([Product].[Product Categories].[Subcategory].&amp;[1],[Measures].[Gross Profit]) CELL PROPERTIES VALUE, FORMAT_STRING, LANGUAGE, BACK_COLOR, FORE_COLOR, FONT_FLAGS</p></blockquote>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/mountainbikes.jpg" title="Mountain Bikes"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/mountainbikes.jpg" alt="Mountain Bikes" /></a></p>
<blockquote><p>SELECT  FROM [Adventure Works] WHERE ([Product].[Product Categories].[Subcategory].&amp;[2],[Measures].[Gross Profit]) CELL PROPERTIES VALUE, FORMAT_STRING, LANGUAGE, BACK_COLOR, FORE_COLOR, FONT_FLAGS</p></blockquote>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/both.jpg" title="Both - multiselect"></a></p>
<blockquote><p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/05/both.jpg" title="Both - multiselect"></a><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/both_mountainbikes_roadbikes.jpg" title="Both MountainBikes and RoadBikes"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/07/both_mountainbikes_roadbikes.jpg" alt="Both MountainBikes and RoadBikes" /></a> </p>
<p>SELECT  FROM (SELECT ({[Product].[Product Categories].[Subcategory].&amp;[1],[Product].[Product Categories].[Subcategory].&amp;[2]}) ON COLUMNS  FROM [Adventure Works]) WHERE ([Measures].[Gross Profit]) CELL PROPERTIES VALUE, FORMAT_STRING, LANGUAGE, BACK_COLOR, FORE_COLOR, FONT_FLAGS</p></blockquote>
<p>I created BUG incident in Microsoft feedback database and everyone could vote for it, hope Microsoft will recognize this error and pay attention on this case:<br />
<a href="http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=275207">http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=275207</a> .</p>
]]></content:encoded>
			<wfw:commentRss>http://ssas-info.com/RamunasBalukonisBlog/14_avoid-defining-default-member/feed</wfw:commentRss>
		</item>
		<item>
		<title>Describing the cube</title>
		<link>http://ssas-info.com/RamunasBalukonisBlog/13_describing-the-cube</link>
		<comments>http://ssas-info.com/RamunasBalukonisBlog/13_describing-the-cube#comments</comments>
		<pubDate>Fri, 04 May 2007 11:53:02 +0000</pubDate>
		<dc:creator>Ramunas Balukonis</dc:creator>
		
		<category><![CDATA[SSAS]]></category>

		<guid isPermaLink="false">http://ssas-info.com/RamunasBalukonisBlog/?p=13</guid>
		<description><![CDATA[One of the features I missed in OLAP clients are objects descriptions (measures, calculated member, dimensions and so on). Only SSAS administrator could see objects descriptions. But description information for end users are also needed, even critical. I would like to see description information on OLAP objects tooltip, as example.
In our BI enviroment, we use abbraviations for some fileds. As example we have calculated member &#8220;gross margin [...]]]></description>
			<content:encoded><![CDATA[<p>One of the features I missed in OLAP clients are objects descriptions (measures, calculated member, dimensions and so on). Only SSAS administrator could see objects descriptions. But description information for end users are also needed, even critical. I would like to see description information on OLAP objects tooltip, as example.</p>
<p>In our BI enviroment, we use abbraviations for some fileds. As example we have calculated member &#8220;gross margin return on investment&#8221;, but more conveniant to name this field as &#8220;GMROI&#8221; and give him description &#8220;gross margin return on investment&#8221;.   But how to set descriptions and how to show descriptions in OLAP clients? it could be a tricky task.<br />
In Visual Studio, there is easy way to set description for a specific object. Right click on object you want to set a description and click properties. Among all other properties you&#8217;ll find &#8220;Description&#8221;.  But there is no properties for calculated members, so therefore unable to set it in Visual Mode. To workaround, open cube code (In Visual Studio, right click on cube and choose &#8220;View Code&#8221;). Locate calculated member you want to describe under &lt;CalculationProperties&gt; section and add additional tag &lt;Description&gt;. If needed, add description field for Translation as well:</p>
<blockquote><p>        &lt;CalculationProperty dwd:design-time-name=&#8221;96f39d00-3468-4509-9018-9bce0452ecf2&#8243;&gt;<br />
          &lt;CalculationReference&gt;[MEASURES].[GMROI]&lt;/CalculationReference&gt;<br />
          &lt;CalculationType&gt;Member&lt;/CalculationType&gt;<br />
          &lt;Description&gt;Gross Margin Return On Investment&lt;/Description&gt;<br />
          &lt;Translations&gt;<br />
            &lt;Translation dwd:design-time-name=&#8221;c81e34a5-77f7-4443-85a7-c33044d88c7d&#8221;&gt;<br />
              &lt;Language&gt;1063&lt;/Language&gt;<br />
              &lt;Caption&gt;GMROI&lt;/Caption&gt;<br />
              &lt;Description&gt;Investavimo grÄ…Å¾a.&lt;/Description&gt;<br />
            &lt;/Translation&gt;<br />
          &lt;/Translations&gt;<br />
        &lt;/CalculationProperty&gt;</p></blockquote>
<p>Deploy the cube. Now, description for field GMROI is ready.<br />
Another way to add a description on calculated member is to use third party add ins, like BIDS helper: <a href="http://www.codeplex.com/bidshelper">http://www.codeplex.com/bidshelper</a> .<br />
But how to show the actual field name and description in front end? As I said, I do not known any clients that shows OLAP objects descriptions. So, the alternative is to write your own application. Below I pasted the sample code how to connect to analysis services, loop through cubes, then loop through every measure and calculated member in cube, write object name and they descriptions. </p>
<blockquote><p>    Public Sub RunAmo(ByVal DatabaseName As String)</p>
<p>        Dim AmoServer As New Microsoft.AnalysisServices.Server<br />
        Dim AmoDatabase As New Microsoft.AnalysisServices.Database<br />
        Dim AmoCube As New Microsoft.AnalysisServices.Cube<br />
        Dim AmoDimension As New Microsoft.AnalysisServices.Dimension<br />
        Dim AmoDimensionAttribute As New Microsoft.AnalysisServices.DimensionAttribute<br />
        Dim AmoDimensionHierarchy As New Microsoft.AnalysisServices.Hierarchy<br />
        Dim AmoMeasureGroup As New Microsoft.AnalysisServices.MeasureGroup<br />
        Dim AmoMeasure As New Microsoft.AnalysisServices.Measure<br />
        Dim AMOCalculationProperty As Microsoft.AnalysisServices.CalculationProperty<br />
        Dim AttributesHierarchiesList(1) As String<br />
        Dim DimensionsList(1) As String<br />
        Dim CubesList(1) As String<br />
        Dim MeasuresCalulationsList(1) As String &#8216; Put measures and calculated members in the same array, because later this array is sorted.</p>
<p>        Dim iTmp As Integer = 0<br />
        Dim jTmp As Integer = 0<br />
        Dim kTmp As Integer = 0<br />
        Dim count As Integer<br />
        Dim tString As String<br />
        Dim tStringID As String<br />
        Dim tStringName As String<br />
        Dim tStringDescription As String<br />
        Dim DescriptionOK As Boolean</p>
<p>        AmoServer.Connect(&#8221;server_name&#8221;)</p>
<p>        &#8216;through cubes<br />
        iTmp = 0<br />
        For Each AmoCube In AmoServer.Databases(DatabaseName).Cubes<br />
            count = iTmp + 1<br />
            ReDim Preserve CubesList(count - 1)<br />
            CubesList(iTmp) = AmoCube.Name.ToString &amp; &#8220;|&#8221; &amp; AmoCube.ID &amp; &#8220;|&#8221;</p>
<p>            For kTmp = 0 To AmoCube.Translations.Count - 1<br />
                If AmoCube.Translations(kTmp).Language = 1063 And Not AmoCube.Translations(kTmp).Description Is Nothing Then<br />
                    If Not AmoCube.Translations(kTmp).Description Is Nothing Then<br />
                        CubesList(iTmp) = CubesList(iTmp) &amp; AmoCube.Translations(kTmp).Description<br />
                    End If<br />
                End If<br />
            Next<br />
            iTmp = count<br />
        Next</p>
<p>        SortArray(CubesList)<br />
        Response.Write(&#8221;&lt;h3&gt;Cubes and fields:&lt;/h3&gt;&#8221;)<br />
        Response.Write(&#8221;&lt;table&gt;&#8221;)</p>
<p>        For iTmp = 0 To UBound(CubesList)<br />
            tString = CubesList(iTmp).ToString<br />
            tStringName = Left(tString, InStr(tString, &#8220;|&#8221;, CompareMethod.Text) - 1)<br />
            tStringID = Mid(tString, InStr(tString, &#8220;|&#8221;, CompareMethod.Text) + 1, InStr(InStr(tString, &#8220;|&#8221;, CompareMethod.Text) + 1, tString, &#8220;|&#8221;) - InStr(tString, &#8220;|&#8221;, CompareMethod.Text) - 1)<br />
            tStringDescription = Mid(tString, InStr(InStr(tString, &#8220;|&#8221;, CompareMethod.Text) + 1, tString, &#8220;|&#8221;) + 1)</p>
<p>            Response.Write(&#8221;&lt;tr&gt;&lt;tdclsCubeHeader&#8221;"&gt;Fields for cube &lt;spanclsCubeName&#8221;"&gt;&#8221; &amp; tStringName &amp; &#8220;&lt;/span&gt;&lt;/td&gt;&lt;tdclsCubeHeader&#8221;"&gt;&#8221; &amp; tStringDescription &amp; &#8220;&lt;/td&gt;&lt;/tr&gt;&#8221;)<br />
            AmoCube = AmoServer.Databases(DatabaseName).Cubes(tStringID)</p>
<p>            jTmp = 0<br />
            For Each AmoMeasureGroup In AmoCube.MeasureGroups<br />
                For Each AmoMeasure In AmoMeasureGroup.Measures<br />
                    If AmoMeasure.Visible = True Then<br />
                        count = jTmp + 1<br />
                        ReDim Preserve MeasuresCalulationsList(count - 1)</p>
<p>                        For kTmp = 0 To AmoMeasure.Translations.Count - 1<br />
                            If AmoMeasure.Translations(kTmp).Language = 1063 Then<br />
                                If Not AmoMeasure.Translations(kTmp).Caption Is Nothing Then<br />
                                    MeasuresCalulationsList(jTmp) = AmoMeasure.Translations(kTmp).Caption.ToString &amp; &#8220;|&#8221;<br />
                                Else<br />
                                    MeasuresCalulationsList(jTmp) = AmoMeasure.Name &amp; &#8220;|&#8221;<br />
                                End If<br />
                                Exit For<br />
                            End If<br />
                        Next<br />
                        DescriptionOK = False<br />
                        For kTmp = 0 To AmoMeasure.Translations.Count - 1<br />
                            If AmoMeasure.Translations(kTmp).Language = 1063 Then<br />
                                If Not AmoMeasure.Translations(kTmp).Description Is Nothing Then<br />
                                    MeasuresCalulationsList(jTmp) = MeasuresCalulationsList(jTmp) &amp; AmoMeasure.Translations(kTmp).Description.ToString &amp; &#8220;&lt;br&gt;&#8221;<br />
                                    DescriptionOK = True<br />
                                End If<br />
                                Exit For<br />
                            End If<br />
                        Next<br />
                        If Not AmoMeasure.Description Is Nothing And DescriptionOK = False Then<br />
                            MeasuresCalulationsList(jTmp) = MeasuresCalulationsList(jTmp) &amp; AmoMeasure.Description.ToString &amp; &#8220;&lt;br&gt;&#8221;<br />
                        End If</p>
<p>                        jTmp = count<br />
                    End If<br />
                Next    &#8216;AmoMeasure In AmoMeasureGroup.Measures<br />
            Next    &#8216;AmoMeasureGroup In AmoCube.MeasureGroups<br />
            If AmoCube.MdxScripts.Count &gt; 0 Then<br />
                For Each AMOCalculationProperty In AmoCube.MdxScripts(0).CalculationProperties<br />
                    &#8216;If AMOCalculationProperty.Visible = True Then<br />
                    count = jTmp + 1<br />
                    ReDim Preserve MeasuresCalulationsList(count - 1)</p>
<p>                    If AMOCalculationProperty.Translations.Count &lt;&gt; 0 Then<br />
                        MeasuresCalulationsList(jTmp) = AMOCalculationProperty.Translations(0).Caption.ToString &amp; &#8220;|&#8221;<br />
                    Else<br />
                        MeasuresCalulationsList(jTmp) = AMOCalculationProperty.Description.ToString &amp; &#8220;|&#8221;<br />
                    End If</p>
<p>                    DescriptionOK = False<br />
                    If AmoMeasure.Translations.Count &lt;&gt; 0 Then<br />
                        If Not AMOCalculationProperty.Translations(0).Description Is Nothing Then<br />
                            MeasuresCalulationsList(jTmp) = MeasuresCalulationsList(jTmp) &amp; AMOCalculationProperty.Translations(0).Description.ToString &amp; &#8220;&lt;br&gt;&#8221;<br />
                            DescriptionOK = True<br />
                        End If<br />
                    End If<br />
                    If Not AMOCalculationProperty.Description Is Nothing And DescriptionOK = False Then<br />
                        MeasuresCalulationsList(jTmp) = MeasuresCalulationsList(jTmp) &amp; AMOCalculationProperty.Description.ToString &amp; &#8220;&lt;br&gt;&#8221;<br />
                    End If</p>
<p>                    jTmp = count</p>
<p>                Next    &#8216;AMOCalculationProperty In AmoCube.MdxScripts(0).CalculationProperties<br />
            End If</p>
<p>            SortArray(MeasuresCalulationsList) &#8216;Call external function to sort MeasuresCalulationsList<br />
            For jTmp = 0 To UBound(MeasuresCalulationsList)<br />
                tString = MeasuresCalulationsList(jTmp).ToString<br />
                tStringName = Left(tString, InStr(tString, &#8220;|&#8221;, CompareMethod.Text) - 1)<br />
                tStringDescription = Mid(tString, InStr(tString, &#8220;|&#8221;, CompareMethod.Text) + 1)</p>
<p>                Response.Write(&#8221;&lt;tr&gt;&lt;tdclsMeasures&#8221;"&gt;&#8221;)<br />
                Response.Write(tStringName)<br />
                Response.Write(&#8221;&lt;/td&gt;&lt;td clsMeasuresDescription&#8221;"&gt;&#8221;)<br />
                Response.Write(tStringDescription)<br />
                Response.Write(&#8221;&lt;tr&gt;&lt;td&gt;&#8221;)</p>
<p>            Next<br />
        Next<br />
        Response.Write(&#8221;&lt;/table&#8221;)</p>
<p>    End Sub</p></blockquote>
<p>This is only way to describe you cube.</p>
]]></content:encoded>
			<wfw:commentRss>http://ssas-info.com/RamunasBalukonisBlog/13_describing-the-cube/feed</wfw:commentRss>
		</item>
		<item>
		<title>Choosing client for SSAS 2005: Excel 2003 or Excel 2007</title>
		<link>http://ssas-info.com/RamunasBalukonisBlog/3_choosing-client-for-ssas-2005-excel-2003-or-excel-2007</link>
		<comments>http://ssas-info.com/RamunasBalukonisBlog/3_choosing-client-for-ssas-2005-excel-2003-or-excel-2007#comments</comments>
		<pubDate>Wed, 02 May 2007 19:54:18 +0000</pubDate>
		<dc:creator>Ramunas Balukonis</dc:creator>
		
		<category><![CDATA[SSAS]]></category>

		<guid isPermaLink="false">http://ssas-info.com/RamunasBalukonisBlog/?p=3</guid>
		<description><![CDATA[After we migrated Analysis Services from 2000 to 2005 we discovered that the same (or analogous) queries against SSAS 2005 runs even slower than AS 2000. Our users used MS Excel 2003 as front end on AS 2005. After some time I installed MS Excel 2007. Then I tried to do the same Pivot Table actions on both Excel [...]]]></description>
			<content:encoded><![CDATA[<p>After we migrated Analysis Services from 2000 to 2005 we discovered that the same (or analogous) queries against SSAS 2005 runs even slower than AS 2000. Our users used MS Excel 2003 as front end on AS 2005. After some time I installed MS Excel 2007. Then I tried to do the same Pivot Table actions on both Excel versions (2003 and 2007): make Pivot Table from Advenure Works database placing days of [Date].[Calendar] [July 2003] and [August 2003] on rows, [Mountain-200 Silver, 38] and [Mountain-200 Silver, 42] from product [Product].[categories] on columns and [Sales Amount] as facts<u><font color="#810081"><br />
</font></u><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/04/excel2003_mdx.txt" title="Excel2003 MDX"></a> </p>
<p>Excel 2003 genetares cumbersome MDX wits lots of except:</p>
<blockquote><p>SELECT NON EMPTY HIERARCHIZE(Except({AddCalculatedMembers(Except({AddCalculatedMembers(Except({AddCalculatedMembers(DrillDownMember({Except({AddCalculatedMembers(DrillDownMember({DrillDownLevel({[Product].[Prod<br />
uct Categories].[All Products]})}, {[Product].[Product Categories].[Category].&amp;[1]}))}, {[Product].[Product Categories].[Category].&amp;[2], [Product].[Product Categories].[Category].&amp;[3], [Product].[Product<br />
Categories].[Category].&amp;[4]})}, {[Product].[Product Categories].[Subcategory].&amp;[1]}))}, {[Product].[Product Categories].[Subcategory].&amp;[2], [Product].[Product Categories].[Subcategory].&amp;[3]}))},<br />
{[Product].[Product Categories].[Product].&amp;[600], [Product].[Product Categories].[Product].&amp;[599], [Product].[Product Categories].[Product].&amp;[598], [Product].[Product Categories].[Product].&amp;[597],<br />
 [Product].[Product<br />
Categories].[Product].&amp;[596], [Product].[Product Categories].[Product].&amp;[595], [Product].[Product Categories].[Product].&amp;[594], [Product].[Product Categories].[Product].&amp;[593], [Product].[Product<br />
Categories].[Product].&amp;[592], [Product].[Product Categories].[Product].&amp;[591], [Product].[Product Categories].[Product].&amp;[590], [Product].[Product Categories].[Product].&amp;[589], [Product].[Product<br />
Categories].[Product].&amp;[588], [Product].[Product Categories].[Product].&amp;[587], [Product].[Product Categories].[Product].&amp;[367], [Product].[Product Categories].[Product].&amp;[366], [Product].[Product<br />
Categories].[Product].&amp;[365], [Product].[Product Categories].[Product].&amp;[364], [Product].[Product Categories].[Product].&amp;[363], [Product].[Product Categories].[Product].&amp;[362], [Product].[Product<br />
Categories].[Product].&amp;[361], [Product].[Product Categories].[Product].&amp;[360], [Product].[Product Categories].[Product].&amp;[359], [Product].[Product Categories].[Product].&amp;[358], [Product].[Product<br />
Categories].[Product].&amp;[357], [Product].[Product Categories].[Product].&amp;[356], [Product].[Product Categories].[Product].&amp;[352], [Product].[Product Categories].[Product].&amp;[351], [Product].[Product<br />
Categories].[Product].&amp;[350], [Product].[Product Categories].[Product].&amp;[349], [Product].[Product Categories].[Product].&amp;[348], [Product].[Product Categories].[Product].&amp;[347], [Product].[Product<br />
Categories].[Product].&amp;[346], [Product].[Product Categories].[Product].&amp;[345], [Product].[Product Categories].[Product].&amp;[344], [Product].[Product Categories].[Product].&amp;[311], [Product].[Product<br />
Categories].[Product].&amp;[310], [Product].[Product Categories].[Product].&amp;[606], [Product].[Product Categories].[Product].&amp;[605], [Product].[Product Categories].[Product].&amp;[604], [Product].[Product<br />
Categories].[Product].&amp;[584], [Product].[Product Categories].[Product].&amp;[583], [Product].[Product Categories].[Product].&amp;[582], [Product].[Product Categories].[Product].&amp;[581], [Product].[Product<br />
Categories].[Product].&amp;[580], [Product].[Product Categories].[Product].&amp;[390], [Product].[Product Categories].[Product].&amp;[389], [Product].[Product Categories].[Product].&amp;[388], [Product].[Product<br />
Categories].[Product].&amp;[387], [Product].[Product Categories].[Product].&amp;[386], [Product].[Product Categories].[Product].&amp;[385], [Product].[Product Categories].[Product].&amp;[384], [Product].[Product<br />
Categories].[Product].&amp;[383], [Product].[Product Categories].[Product].&amp;[382], [Product].[Product Categories].[Product].&amp;[381], [Product].[Product Categories].[Product].&amp;[380], [Product].[Product<br />
Categories].[Product].&amp;[379], [Product].[Product Categories].[Product].&amp;[378], [Product].[Product Categories].[Product].&amp;[377], [Product].[Product Categories].[Product].&amp;[376], [Product].[Product<br />
Categories].[Product].&amp;[375], [Product].[Product Categories].[Product].&amp;[374], [Product].[Product Categories].[Product].&amp;[373], [Product].[Product Categories].[Product].&amp;[372], [Product].[Product<br />
Categories].[Product].&amp;[371], [Product].[Product Categories].[Product].&amp;[370], [Product].[Product Categories].[Product].&amp;[369], [Product].[Product Categories].[Product].&amp;[368], [Product].[Product<br />
Categories].[Product].&amp;[343], [Product].[Product Categories].[Product].&amp;[342], [Product].[Product Categories].[Product].&amp;[341], [Product].[Product Categories].[Product].&amp;[340], [Product].[Product<br />
Categories].[Product].&amp;[339], [Product].[Product Categories].[Product].&amp;[338], [Product].[Product Categories].[Product].&amp;[337], [Product].[Product Categories].[Product].&amp;[336], [Product].[Product<br />
Categories].[Product].&amp;[335], [Product].[Product Categories].[Product].&amp;[334], [Product].[Product Categories].[Product].&amp;[333], [Product].[Product Categories].[Product].&amp;[332], [Product].[Product<br />
Categories].[Product].&amp;[331], [Product].[Product Categories].[Product].&amp;[330], [Product].[Product Categories].[Product].&amp;[329], [Product].[Product Categories].[Product].&amp;[328], [Product].[Product<br />
Categories].[Product].&amp;[327], [Product].[Product Categories].[Product].&amp;[326], [Product].[Product Categories].[Product].&amp;[325], [Product].[Product Categories].[Product].&amp;[324], [Product].[Product<br />
Categories].[Product].&amp;[323], [Product].[Product Categories].[Product].&amp;[322], [Product].[Product Categories].[Product].&amp;[321], [Product].[Product Categories].[Product].&amp;[320], [Product].[Product<br />
Categories].[Product].&amp;[319], [Product].[Product Categories].[Product].&amp;[318], [Product].[Product Categories].[Product].&amp;[317]}))}, {[Product].[Product Categories].[Category].&amp;[2], [Product].[Product<br />
Categories].[Category].&amp;[3], [Product].[Product Categories].[Category].&amp;[4], [Product].[Product Categories].[Subcategory].&amp;[2], [Product].[Product Categories].[Subcategory].&amp;[3], [Product].[Product<br />
Categories].[Product].&amp;[600], [Product].[Product Categories].[Product].&amp;[599], [Product].[Product Categories].[Product].&amp;[598], [Product].[Product Categories].[Product].&amp;[597], [Product].[Product<br />
Categories].[Product].&amp;[596], [Product].[Product Categories].[Product].&amp;[595], [Product].[Product Categories].[Product].&amp;[594], [Product].[Product Categories].[Product].&amp;[593], [Product].[Product<br />
Categories].[Product].&amp;[592], [Product].[Product Categories].[Product].&amp;[591], [Product].[Product Categories].[Product].&amp;[590], [Product].[Product Categories].[Product].&amp;[589], [Product].[Product<br />
Categories].[Product].&amp;[588], [Product].[Product Categories].[Product].&amp;[587], [Product].[Product Categories].[Product].&amp;[367], [Product].[Product Categories].[Product].&amp;[366], [Product].[Product<br />
Categories].[Product].&amp;[365], [Product].[Product Categories].[Product].&amp;[364], [Product].[Product Categories].[Product].&amp;[363], [Product].[Product Categories].[Product].&amp;[362], [Product].[Product<br />
Categories].[Product].&amp;[361], [Product].[Product Categories].[Product].&amp;[360], [Product].[Product Categories].[Product].&amp;[359], [Product].[Product Categories].[Product].&amp;[358], [Product].[Product<br />
Categories].[Product].&amp;[357], [Product].[Product Categories].[Product].&amp;[356], [Product].[Product Categories].[Product].&amp;[352], [Product].[Product Categories].[Product].&amp;[351], [Product].[Product<br />
Categories].[Product].&amp;[350], [Product].[Product Categories].[Product].&amp;[349], [Product].[Product Categories].[Product].&amp;[348], [Product].[Product Categories].[Product].&amp;[347], [Product].[Product<br />
Categories].[Product].&amp;[346], [Product].[Product Categories].[Product].&amp;[345], [Product].[Product Categories].[Product].&amp;[344], [Product].[Product Categories].[Product].&amp;[311], [Product].[Product<br />
Categories].[Product].&amp;[310], [Product].[Product Categories].[Product].&amp;[606], [Product].[Product Categories].[Product].&amp;[605], [Product].[Product Categories].[Product].&amp;[604], [Product].[Product<br />
Categories].[Product].&amp;[584], [Product].[Product Categories].[Product].&amp;[583], [Product].[Product Categories].[Product].&amp;[582], [Product].[Product Categories].[Product].&amp;[581], [Product].[Product<br />
Categories].[Product].&amp;[580], [Product].[Product Categories].[Product].&amp;[390], [Product].[Product Categories].[Product].&amp;[389], [Product].[Product Categories].[Product].&amp;[388], [Product].[Product<br />
Categories].[Product].&amp;[387], [Product].[Product Categories].[Product].&amp;[386], [Product].[Product Categories].[Product].&amp;[385], [Product].[Product Categories].[Product].&amp;[384], [Product].[Product<br />
Categories].[Product].&amp;[383], [Product].[Product Categories].[Product].&amp;[382], [Product].[Product Categories].[Product].&amp;[381], [Product].[Product Categories].[Product].&amp;[380], [Product].[Product<br />
Categories].[Product].&amp;[379], [Product].[Product Categories].[Product].&amp;[378], [Product].[Product Categories].[Product].&amp;[377], [Product].[Product Categories].[Product].&amp;[376], [Product].[Product<br />
Categories].[Product].&amp;[375], [Product].[Product Categories].[Product].&amp;[374], [Product].[Product Categories].[Product].&amp;[373], [Product].[Product Categories].[Product].&amp;[372], [Product].[Product<br />
Categories].[Product].&amp;[371], [Product].[Product Categories].[Product].&amp;[370], [Product].[Product Categories].[Product].&amp;[369], [Product].[Product Categories].[Product].&amp;[368], [Product].[Product<br />
Categories].[Product].&amp;[343], [Product].[Product Categories].[Product].&amp;[342], [Product].[Product Categories].[Product].&amp;[341], [Product].[Product Categories].[Product].&amp;[340], [Product].[Product<br />
Categories].[Product].&amp;[339], [Product].[Product Categories].[Product].&amp;[338], [Product].[Product Categories].[Product].&amp;[337], [Product].[Product Categories].[Product].&amp;[336], [Product].[Product<br />
Categories].[Product].&amp;[335], [Product].[Product Categories].[Product].&amp;[334], [Product].[Product Categories].[Product].&amp;[333], [Product].[Product Categories].[Product].&amp;[332], [Product].[Product<br />
Categories].[Product].&amp;[331], [Product].[Product Categories].[Product].&amp;[330], [Product].[Product Categories].[Product].&amp;[329], [Product].[Product Categories].[Product].&amp;[328], [Product].[Product<br />
Categories].[Product].&amp;[327], [Product].[Product Categories].[Product].&amp;[326], [Product].[Product Categories].[Product].&amp;[325], [Product].[Product Categories].[Product].&amp;[324], [Product].[Product<br />
Categories].[Product].&amp;[323], [Product].[Product Categories].[Product].&amp;[322], [Product].[Product Categories].[Product].&amp;[321], [Product].[Product Categories].[Product].&amp;[320], [Product].[Product<br />
Categories].[Product].&amp;[319], [Product].[Product Categories].[Product].&amp;[318], [Product].[Product Categories].[Product].&amp;[317]})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS , NON EMPTY<br />
HIERARCHIZE(Except({AddCalculatedMembers(Except({AddCalculatedMembers(DrillDownMember({Except({AddCalculatedMembers(DrillDownMember({Except({AddCalculatedMembers(DrillDownMember({Except({Add<br />
CalculatedMembers(DrillDownMember({DrillDownLevel({[Date].[Calendar].[All Periods]})}, {[Date].[Calendar].[Calendar Year].&amp;[2003]}))}, {[Date].[Calendar].[Calendar Year].&amp;[2004], [Date].[Calendar].[Calendar<br />
Year].&amp;[2002], [Date].[Calendar].[Calendar Year].&amp;[2001]})}, {[Date].[Calendar].[Calendar Semester].&amp;[2003]&amp;[2]}))}, {[Date].[Calendar].[Calendar Semester].&amp;[2003]&amp;[1]})}, {[Date].[Calendar].[Calendar<br />
Quarter].&amp;[2003]&amp;[3]}))}, {[Date].[Calendar].[Calendar Quarter].&amp;[2003]&amp;[4]})}, {[Date].[Calendar].[Month].&amp;[2003]&amp;[7], [Date].[Calendar].[Month].&amp;[2003]&amp;[8]}))}, {[Date].[Calendar].[Month].&amp;[2003]&amp;[9]}))},<br />
{[Date].[Calendar].[Calendar Year].&amp;[2004], [Date].[Calendar].[Calendar Year].&amp;[2002], [Date].[Calendar].[Calendar Year].&amp;[2001], [Date].[Calendar].[Calendar Semester].&amp;[2003]&amp;[1], [Date].[Calendar].[Calendar<br />
Quarter].&amp;[2003]&amp;[4], [Date].[Calendar].[Month].&amp;[2003]&amp;[9]})) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON ROWS FROM [Adventure Works] WHERE ([Measures].[Sales Amount])</p></blockquote>
<p>Excel 2007 generates elegant MDX:</p>
<blockquote><p>SELECT NON EMPTY Hierarchize({DrilldownLevel({[Product].[Product Categories].[All Products]})}) DIMENSION PROPERTIES PARENT_UNIQUE_NAME ON COLUMNS , NON EMPTY<br />
Hierarchize(DrilldownMember({{DrilldownMember({{DrilldownMember({{DrilldownMember({{DrilldownLevel({[Date].[Calendar].[All Periods]})}}, {[Date].[Calendar].[Calendar Year].&amp;[2003]})}},<br />
{[Date].[Calendar].[Calendar Semester].&amp;[2003]&amp;[2]})}}, {[Date].[Calendar].[Calendar Quarter].&amp;[2003]&amp;[3]})}}, {[Date].[Calendar].[Month].&amp;[2003]&amp;[7],[Date].[Calendar].[Month].&amp;[2003]&amp;[8]})) DIMENSION<br />
PROPERTIES PARENT_UNIQUE_NAME,[Date].[Calendar].[Calendar Semester].[Calendar Year],[Date].[Calendar].[Calendar Quarter].[Calendar Quarter of Year],[Date].[Calendar].[Calendar Quarter].[Calendar<br />
Semester],[Date].[Calendar].[Calendar Quarter].[Calendar Semester of Year],[Date].[Calendar].[Calendar Quarter].[Fiscal Quarter],[Date].[Calendar].[Month].[Calendar Quarter],[Date].[Calendar].[Month].[Month of<br />
Year],[Date].[Calendar].[Date].[Day Name],[Date].[Calendar].[Date].[Day of Year],[Date].[Calendar].[Date].[Day of Month],[Date].[Calendar].[Date].[Day of Week],[Date].[Calendar].[Date].[Month<br />
Name],[Date].[Calendar].[Date].[Week of Year] ON ROWS  FROM (SELECT ({[Product].[Product Categories].[Product].&amp;[352], [Product].[Product Categories].[Product].&amp;[353], [Product].[Product<br />
Categories].[Product].&amp;[354], [Product].[Product Categories].[Product].&amp;[355]}) ON COLUMNS , ({[Date].[Calendar].[Month].&amp;[2003]&amp;[8], [Date].[Calendar].[Month].&amp;[2003]&amp;[7]}) ON ROWS  FROM [Adventure Works])<br />
WHERE ([Measures].[Sales Amount]) CELL PROPERTIES VALUE, FORMAT_STRING, LANGUAGE, BACK_COLOR, FORE_COLOR, FONT_FLAGS</p></blockquote>
<p>The 1&#8217;st query from Excel 2003 runs 5 times longer! Profiler shows lots of &#8220;Started/finised reading data from the &#8230; partitions</p>
<p> <a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/04/excel_2003_profiler.jpg" title="Excel_2003_profiler"></a><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/04/excel_2003_profiler.jpg" title="excel_2003_profiler.jpg"><img src="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/04/excel_2003_profiler.jpg" alt="excel_2003_profiler.jpg" /></a></p>
<p><a href="http://ssas-info.com/RamunasBalukonisBlog/wp-content/uploads/2007/04/excel_2003_profiler.jpg" title="excel_2003_profiler.jpg"></a>So, we started to move client to new Excel 2007 version. After some time I gathered statistics from profiler and querylog. The results are as follows: </p>
<p>Avg MDX text length (Excel 2003): 2403<br />
Avg MDX text length (Excel 2007): 1567<br />
Avg query duration (Excel 2003): 507 ms<br />
Avg query duration (Excel 2007): 96 ms</p>
<p>From my expirience, almost impossible to work with SSAS 2005 with Excel 2003. Avoid using this as a client and move to new Excel 2007. </p>
<p>Excel 2007 also has backward compatibility mode. It means Excel 2007  generates queries for AS 2000, as example with lots of except. To take advantages working with Excel 2007 ensure you have converted Excel 2007 from &#8220;compatibility mode&#8221; and recreated pivot tables. Among all other Excel 2007 features you&#8217;ll get the best performance.</p>
]]></content:encoded>
			<wfw:commentRss>http://ssas-info.com/RamunasBalukonisBlog/3_choosing-client-for-ssas-2005-excel-2003-or-excel-2007/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
