<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Paul te Braak</title>
	<atom:link href="http://paultebraak.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://paultebraak.wordpress.com</link>
	<description>Business Intelligence Blog</description>
	<lastBuildDate>Fri, 17 May 2013 15:54:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='paultebraak.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/caff8b5f9412f72337a81f05500c42a3?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Paul te Braak</title>
		<link>http://paultebraak.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://paultebraak.wordpress.com/osd.xml" title="Paul te Braak" />
	<atom:link rel='hub' href='http://paultebraak.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Extending Data Sets in SSRS with VB Functions</title>
		<link>http://paultebraak.wordpress.com/2013/03/21/extending-data-sets-in-ssrs-with-vb-functions/</link>
		<comments>http://paultebraak.wordpress.com/2013/03/21/extending-data-sets-in-ssrs-with-vb-functions/#comments</comments>
		<pubDate>Thu, 21 Mar 2013 03:08:24 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[MDX]]></category>
		<category><![CDATA[SSRS]]></category>
		<category><![CDATA[VB]]></category>
		<category><![CDATA[Functions]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=614</guid>
		<description><![CDATA[A common event that occurs rather often is when a report has to be altered to include some set of data that does not exist in the &#8216;corporate&#8217; data warehouse. This type of situation is easy to imagine in sales environments where a campaign exists (one which was not planned at budget time) and someone* [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=614&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A common event that occurs rather often is when a report has to be altered to include some set of data that does not exist in the &#8216;corporate&#8217; data warehouse. This type of situation is easy to imagine in sales environments where a campaign exists (one which was not planned at budget time) and <strong>someone*</strong> would like to see this data reported against actual sales (and possibly even a comparative to budget). <em>I agree that it would be ideal to have this data &#8216;corporatized&#8217;; however, there are often competing forces and changes in priorities, which means that this data never makes it in.</em> This post looks at how this data can be included into reports.</p>
<p>Consider the situation where and how someone has gone through and created a new budget for adventure works data (as below) and we want to include this in our report.</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda1.png?w=595" /></p>
<p>In order to include this will create a function which specifies what the new value should be given the inputs of year in category. Naturally, in a production environment, these combinations increase but the principle applied is exactly the same. You can read a little bit more about functions <a href="http://msdn.microsoft.com/en-us/library/ms156028(v=SQL.105).aspx">here</a> but essentially what we&#8217;re trying to do is return some value given inputs. We can then append that to our data set as an additional field (i.e. another measure) and then use that field in the report.<span style="text-decoration:underline;"><br />
</span></p>
<p><span style="text-decoration:underline;"><strong>Base Data<br />
</strong></span></p>
<p>The base query for [reseller sales amount] by using categories would be;</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:319px;" />
<col style="width:319px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #bfbfbf .5pt;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select</span><br />
</span><span style="font-family:Consolas;font-size:9pt;">[Measures].[Reseller Sales Amount] <span style="color:blue;">on</span> 0,<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Date].[Calendar].[Calendar Year]<br />
</span><span style="font-family:Consolas;font-size:9pt;">* [Product].[Category].[Category]<br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">on</span> 1<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from</span> [Channel Sales]<br />
</span></td>
<td style="padding-left:7px;padding-right:7px;border-top:solid #bfbfbf .5pt;border-left:none;border-bottom:solid #bfbfbf .5pt;border-right:solid #bfbfbf .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda2.png?w=595" /></td>
</tr>
</tbody>
</table>
</div>
<p><span style="text-decoration:underline;"><strong>Creating the Function 20 oh<br />
</strong></span></p>
<p>Having the data in the tabular format is makes it really easy to manipulate in Excel, in fact, we could add another column with a formula to specify what the return value should be given the year and category. In my workbook, the formula would be;</p>
<p><span style="font-family:Courier New;">=&#8221;if (year_name=&#8221;"&#8221;&amp;A2&amp;&#8221;"&#8221; and category_name =&#8221;"&#8221;&amp;B2&amp;&#8221;"&#8221;) then return &#8221; &amp;D2<br />
</span></p>
<p>And it is apply to every row that we have data for (as in the screenshot below).</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda3.png?w=595" /></p>
<p>Now that we have these formulas, we can embed them in a property construct and add them to the report code. In order to do this you define the property name, the return value type, the input parameters (and their type).</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">Public </span><span style="color:blue;">Function</span> UserValue(year_name <span style="color:blue;">As </span><span style="color:blue;">String</span>, category_name <span style="color:blue;">As </span><span style="color:blue;">String</span>) <span style="color:blue;">As </span><span style="color:blue;">Double</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><br />
<span style="color:green;">&#8216;use if statements here<br />
</span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">End </span><span style="color:blue;">Function</span></span></td>
</tr>
</tbody>
</table>
</div>
<p>Note that we are defining a read-only property (UserValue) and specifying a &#8216;Get&#8217; modifier for the property. All this means is that a function will be created (called UserValue) and require the input variables of year_name and category_name. The function will return a double type. A cut of the complete function looks like this;</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">Public </span><span style="color:blue;">Function</span> UserValue(year_name <span style="color:blue;">As </span><span style="color:blue;">String</span>, category_name <span style="color:blue;">As </span><span style="color:blue;">String</span>) <span style="color:blue;">As </span><span style="color:blue;">Double<br />
</span></span><span style="color:blue;font-family:Consolas;font-size:9pt;">  if (year_name=&#8221;CY 2005&#8243; and category_name =&#8221;Accessories&#8221;) then return 20000<br />
</span><span style="color:blue;font-family:Consolas;font-size:9pt;">  if (year_name=&#8221;CY 2005&#8243; and category_name =&#8221;Bikes&#8221;) then return 7340000<br />
</span><span style="color:blue;font-family:Consolas;font-size:9pt;">  if (year_name=&#8221;CY 2005&#8243; and category_name =&#8221;Clothing&#8221;) then return 34000<br />
</span><span style="color:blue;font-family:Consolas;font-size:9pt;">  &#8230;..</span></p>
<p><span style="color:blue;font-family:Consolas;font-size:9pt;">  if (year_name=&#8221;CY 2005&#8243; and category_name =&#8221;Components&#8221;) then return 615000<br />
</span><span style="color:blue;font-family:Consolas;font-size:9pt;">  if (year_name=&#8221;CY 2006&#8243; and category_name =&#8221;Accessories&#8221;) then return 92000<br />
</span><span style="color:blue;font-family:Consolas;font-size:9pt;">  if (year_name=&#8221;CY 2006&#8243; and category_name =&#8221;Bikes&#8221;) then return 19000000<br />
</span><span style="color:blue;font-family:Consolas;font-size:9pt;">End Function<br />
</span></td>
</tr>
</tbody>
</table>
</div>
<p><em>As a tip, it may be easier to create this in a text editor before adding it to report code.</em></p>
<p><span style="text-decoration:underline;"><strong>Adding the Function to Report Code<br />
</strong></span></p>
<p>There are a few ways to add code to a report, perhaps the easiest is to right click (outside the canvas) and select the report properties from the pop-up menu and then navigate to the code. You could then paste the code directly into the custom code box.</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:246px;" />
<col style="width:392px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda4.png?w=595" /></td>
<td style="padding-left:7px;padding-right:7px;border-top:solid #d9d9d9 .5pt;border-left:none;border-bottom:solid #d9d9d9 .5pt;border-right:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda5.png?w=595" /></td>
</tr>
</tbody>
</table>
</div>
<p><span style="text-decoration:underline;"><strong>Calling the Function<br />
</strong></span></p>
<p>Functions can be called by editing the expression (that we are interested in). Since we want to append to our original dataset, we edit the dataset and adding new column. Right click on the dataset and select edit. We then add a new calculated field (as below);</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda6.png?w=595" /></p>
<p>The field can be given a name (New_Value) and entered by clicking the expressions button. <em><strong>Note that I can use values from the current dataset as inputs from a function. </strong>Just as any other expression editor I simply need to double click on the items that I want to add.<strong><br />
</strong></em></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda7.png?w=595" /></p>
<p>My report now has a new measure (New_Value) which can be added to the report, just as any other measure.</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda8.png?w=595" /></p>
<p><span style="text-decoration:underline;"><strong>Other Titbit&#8217;s and Gotchas<br />
</strong></span></p>
<p>Although this function was added to the dataset, it could also be used as a cell in a matrix or table. The benefit of adding an additional column to the dataset is that the value can be aggregated in your report and used in totals. This would not occur if was added to the control directly.</p>
<p>Also note that the default MDX generated by the query designer in SSRS excludes non-empty data and this may lead to misleading results where no &#8216;sales&#8217; have occurred, but there is a New_Value amount to be shown. In this situation it is advisable to remove the nonempty criteria query so that you can to guarantee that data will be shown (regardless of the results returned through the underlying dataset).</p>
<p>A side benefit of using this technique is that the data then become (somewhat) available to other users.  Once the report is published, it can be consumed as an atom feed.</p>
<p><span style="font-size:10pt;"><em>* The use of the word <strong>someone</strong> here is intentional because the person making the request for the change to a report does not often have control over the data that is entered into the data warehouse. While there is a business imperative to include this data, it is not seen as an IT imperative. There is simply not enough time to go through the appropriate channels.</em></span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/614/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/614/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=614&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/03/21/extending-data-sets-in-ssrs-with-vb-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda1.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda2.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda3.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda4.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda5.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda6.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda7.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/032113_0308_extendingda8.png" medium="image" />
	</item>
		<item>
		<title>Designing Good Dimensions in SSAS</title>
		<link>http://paultebraak.wordpress.com/2013/03/15/designing-good-dimensions-in-ssas/</link>
		<comments>http://paultebraak.wordpress.com/2013/03/15/designing-good-dimensions-in-ssas/#comments</comments>
		<pubDate>Fri, 15 Mar 2013 01:09:16 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[MDX]]></category>
		<category><![CDATA[Other Tools]]></category>
		<category><![CDATA[SSAS]]></category>
		<category><![CDATA[Attribute Keys]]></category>
		<category><![CDATA[Attributes]]></category>
		<category><![CDATA[Dimension Design]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=601</guid>
		<description><![CDATA[Designing good dimensions is a balancing act between at least two factors. Our dimension design must offer the user good (and intuitive) way to navigate data and it must also perform well in queries. This post looks at achieving that balance and the dangers that assumptions can produce for dimension design and result output. While [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=601&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Designing good dimensions is a balancing act between at least two factors. Our dimension design must offer the user good (and intuitive) way to navigate data and it must also perform well in queries<em>.</em> This post looks at achieving that balance and the dangers that assumptions can produce for dimension design and result output.<em><br />
</em></p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;">
<p style="text-align:center;"><strong><em>While we can consider other factors (for example processing speed and property/attribute visibility) as important in our design, I considered these factors the most important because the dimension must be used in an intuitive way by users in order to be successful and, the user experience is driven by quick results (especially in an addhoc analytical environment).</em></strong></p>
</td>
</tr>
</tbody>
</table>
</div>
<p><span style="text-decoration:underline;"><strong>Scenario<br />
</strong></span></p>
<p>If we examine the adventure works database and the [Direct Sales] perspective, we note that the customer dimension has a [Post Code] attribute hierarchy (single level hierarchy) and a [Customer Geography] hierarchy which also shows a level [Postal Code]. This can be seen in the diagram below;</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:255px;" />
<col style="width:384px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo1.png?w=595" /></td>
<td style="padding-left:7px;padding-right:7px;border-top:solid #d9d9d9 .5pt;border-left:none;border-bottom:solid #d9d9d9 .5pt;border-right:solid #d9d9d9 .5pt;">Now consider that someone wishes to know what sales were derived in a postcode. We assume that they could use either of these hierarchies to interrogate sales.</p>
<p><em>Although this is a trivial example, I have seen this type of question present itself in production environments that have &#8220;<strong>reported</strong>&#8221; incorrect data the years. Consider a product hierarchy (which includes colour at a lower level) and an attribute hierarchy [colour] (that just shows colours).<br />
</em></p>
<p><em>I&#8217;ll also point out that I highlighted reported above because the business expectation of the results different from the technical. In this instance, the client thought that they were viewing all &#8220;yellow&#8221; products when in fact they were viewing only a subset of the yellow products.</em></td>
</tr>
</tbody>
</table>
</div>
<p>The dangers of this issue can also be magnified by method that client tool is used to query cube.</p>
<p><span style="text-decoration:underline;"><strong>So What&#8217;s the Issue?<br />
</strong></span></p>
<p>If we consider the postcode example, we ask ourselves the question what are the sales will postcode &#8220;V9&#8243;. If this were the case, one might expect to use the [Postal Code] attribute hierarchy and just show &#8220;V9&#8243;. If created pivot in Excel and filter on V9, I get the following results.</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:292px;" />
<col style="width:346px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #f2f2f2 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo2.png?w=595" /></td>
<td style="padding-left:7px;padding-right:7px;border-top:solid #f2f2f2 .5pt;border-left:none;border-bottom:solid #f2f2f2 .5pt;border-right:solid #f2f2f2 .5pt;"><strong>This output is not useful</strong>, why? Because I expect to see a single value for V9 ($252K).</p>
<p>I could use the [Postal code] level of the [Customer Geography] dimension by creating a set but this is not that intuitive (and doesn&#8217;t change results) and is not the kind of interaction we want to give our users.</td>
</tr>
</tbody>
</table>
</div>
<p>From the above results we know that there are two occurrences of the postcode (that is two different areas with the same postcode) which have a value &#8216;V9&#8242;. However, what I want is the total for V9!</p>
<p>This distinction becomes obvious when we look at the members in MDX and the [Postal Code] key definition (as below). Note that the key is a composite key (State, City, Postcode) which is also shown when we look at the MDX member key (by dragging members to the query grid in SSMS).</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo3.png?w=595" /></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo4.png?w=595" /></p>
<p>This type of design is perfectly acceptable when the attribute is used within a dimension hierarchy (as is the case in adventure works). I suggest that the [Postal Code] attribute should be hidden since it is available in hierarchy. Furthermore, the creation of a hierarchy (with relationships between the levels) is a SSAS design best practice. Note that the relationships are defined between these attributes.</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo5.png?w=595" /></p>
<p><strong>The problem is that we have not been able to answer a question about the sales for [Postal Code] V9! What we really need is another attribute that only shows distinct postcode values!<br />
</strong></p>
<p><span style="text-decoration:underline;"><strong>Dangerous Clients<br />
</strong></span></p>
<p>Exposing the attribute hierarchy in this way can be a very dangerous situation, especially when the client uses a <strong>name</strong> in the generation of MDX. For example consider the first query which shows all members that have a postcode of V9. Both members are shown as we would expect;</p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select</span> [Measures].[Internet Sales Amount] <span style="color:blue;">on</span> 0,<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">filter</span>(<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Customer].[Postal Code].<span style="color:blue;">members</span><br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">, [Customer].[Postal Code].<span style="color:maroon;">currentmember</span>.<span style="color:blue;">member_caption</span> = <span style="color:#a31515;">&#8216;V9&#8242;</span><br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">)<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">on</span> 1<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from</span> [Direct Sales]<br />
</span></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo6.png?w=595" /></p>
<p>We could aggregate these results to show the combined result (which is the answer we want);</p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">with</span><br />
<span style="color:blue;">member</span><br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Customer].[Postal Code].[MyAgg] <span style="color:blue;">as</span><br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:maroon;">aggregate</span>(<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">            <span style="color:blue;">filter</span>([Customer].[Postal Code].<span style="color:blue;">members</span><br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">                    , [Customer].[Postal Code].<span style="color:maroon;">currentmember</span>.<span style="color:blue;">member_caption</span> = <span style="color:#a31515;">&#8216;V9&#8242;</span><br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">                    )<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">        )<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select</span>     [Measures].[Internet Sales Amount] <span style="color:blue;">on</span> 0,<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Customer].[Postal Code].[MyAgg] <span style="color:blue;">on</span> 1<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from</span> [Direct Sales]<br />
</span></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo7.png?w=595" /></p>
<p><strong>Now consider the situation where the client simply references the member name [V9] in MDX.</strong> This is shown below. Note that only the first member is returned which we would naïvely assumed to be the sales for the postcode.</p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select</span> [Measures].[Internet Sales Amount] <span style="color:blue;">on</span> 0,<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Customer].[Postal Code].[V9] <span style="color:blue;">on</span> 1<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from</span> [Direct Sales]<br />
</span></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo8.png?w=595" /></p>
<p><span style="text-decoration:underline;"><strong>Conclusion<br />
</strong></span></p>
<p>It is easy to see how useability is an important consideration for attributes. What often surprises most though, are the dangers of clients which purport to show a member value (say V9) and only return 1 member.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/601/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=601&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/03/15/designing-good-dimensions-in-ssas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo1.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo2.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo3.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo4.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo5.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo6.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo7.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031513_0108_designinggo8.png" medium="image" />
	</item>
		<item>
		<title>SSIS 2012 Execution Reporting</title>
		<link>http://paultebraak.wordpress.com/2013/03/14/ssis-2012-execution-reporting/</link>
		<comments>http://paultebraak.wordpress.com/2013/03/14/ssis-2012-execution-reporting/#comments</comments>
		<pubDate>Thu, 14 Mar 2013 00:18:23 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[Other Tools]]></category>
		<category><![CDATA[SSIS]]></category>
		<category><![CDATA[Package Execution]]></category>
		<category><![CDATA[Reporting]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=586</guid>
		<description><![CDATA[SSIS 2012 has (arguably) two main improvements over prior versions. The first is a project deployment model where an entire project can be deployed and managed with a common structure. The second is a more favourable logging mechanism. This post looks at the latter and examines reporting on package and job execution in SSIS 2012. [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=586&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>SSIS 2012 has (arguably) two main improvements over prior versions. The first is a project deployment model where an entire project can be deployed and managed with a common structure. The second is a more favourable logging mechanism. This post looks at the latter and examines reporting on package and job execution in SSIS 2012.</p>
<p>There are standard inbuilt reports that show the execution of the project (and individual packages within the project). These can be seen in SQL Server Management Studio (SSMS) by right clicking on the SSIS catalogue (or node) and selecting the &#8220;All Executions&#8221; report from the reports menu (as below). Note that although you can get to the report through the path Reports &gt; All Executions or Reports &gt; Standard Reports &gt; All Executions, the reports are the same (and shown below).</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><strong>Accessing the Execution Reports through SSMS</strong></td>
</tr>
<tr>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:solid #d9d9d9 .5pt;border-bottom:solid #d9d9d9 .5pt;border-right:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe1.png?w=595" /></td>
</tr>
</tbody>
</table>
</div>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><strong>Sample Report Output</strong></td>
</tr>
<tr>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:solid #d9d9d9 .5pt;border-bottom:solid #d9d9d9 .5pt;border-right:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe2.png?w=595" /></td>
</tr>
</tbody>
</table>
</div>
<p>One of the really great features of this report is that you can click on the Overview hyperlink and see what packages have executed as part of the (node) execution. So, for example, the packages that have executed under my &#8216;Catalog Testing&#8217; (project) execution are listed since this is the node I selected (when I selected overview from the &#8216;All Executions&#8217; report above. An example of this output is seen below. You may note that the overview includes the tasks that have executed within the package.</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><strong>Overview Report </strong>(accessed by the Overview link in the &#8216;All Executions&#8217; report)</td>
</tr>
<tr>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:solid #d9d9d9 .5pt;border-bottom:solid #d9d9d9 .5pt;border-right:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe3.png?w=595" /></td>
</tr>
</tbody>
</table>
</div>
<p><span style="text-decoration:underline;"><strong>But Wait – There&#8217;s More!<br />
</strong></span></p>
<p>While these reports are good, they require SSMS to view the reports, so you might want to interrogate the SSIS database directly. Using this you can create some custom reports and expose these as normal SSRS reports.</p>
<p>Two views that are invaluable for examining package executions (and task executions) are <a href="http://msdn.microsoft.com/en-us/library/ff878089.aspx"><span style="font-family:Consolas;font-size:9pt;">catalog.executions</span></a><span style="font-family:Consolas;font-size:9pt;"><br />
</span>and <a href="http://msdn.microsoft.com/en-us/library/hh479592.aspx"><span style="font-family:Consolas;font-size:9pt;">catalog.executable_statistics</span></a><span style="color:blue;font-family:Consolas;font-size:9pt;">. </span>From MSDN the executions view shows &#8220;instances package execution in the Integration Services Catalogue&#8221;, therefore, we can use this to show (and identify the execution_id) of packages when execute. Consider the &#8220;All Executions&#8221; report above which shows the execution_id of 10275. This can be easily identified in the executions view with the query;</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select </span> <span style="color:gray;">*</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from </span><span style="color:blue;">catalog<span style="color:gray;">.<span style="color:teal;">executions</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">where </span><span style="color:teal;">execution_id </span><span style="color:gray;">=</span> 10275</span></td>
</tr>
<tr>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:solid #d9d9d9 .5pt;border-bottom:solid #d9d9d9 .5pt;border-right:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe4.png?w=595" /></td>
</tr>
</tbody>
</table>
</div>
<p>More importantly we can easily identify executions of packages (or groups of packages) by referring to the package_name field in this table.</p>
<p>Once we have the execution_id, we can then use this in the statistics view to see the detailed execution of the package. This is the same data that is shown in the &#8216;Overview&#8217; report above.</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select </span> <span style="color:gray;">*</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from </span><span style="color:blue;">catalog<span style="color:gray;">.<span style="color:teal;">executable_statistics</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">where </span><span style="color:teal;">execution_id </span><span style="color:gray;">=</span> 10275</span></td>
</tr>
<tr>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:solid #d9d9d9 .5pt;border-bottom:solid #d9d9d9 .5pt;border-right:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe5.png?w=595" /></td>
</tr>
</tbody>
</table>
</div>
<p>Most of my projects utilise a parent/child architecture, so when I consider the natural drill path for package executions as the master_package <span style="font-family:Wingdings;">à</span> child_package <span style="font-family:Wingdings;">à</span> tasks. If I want to only show the packages that have executed as part of the Master package (note Master_1.dtsx package name in the executions above) I can simply use the following query;</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select </span></span><span style="color:teal;font-family:Consolas;font-size:9pt;">e<span style="color:gray;">.*</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span><span style="color:fuchsia;">CONVERT<span style="color:blue;"><span style="color:gray;">(<span style="color:blue;">datetime<span style="color:gray;">, </span><span style="color:teal;">es<span style="color:gray;">.<span style="color:teal;">start_time<span style="color:gray;">) </span><span style="color:blue;">AS</span> start_time</span><br />
</span></span></span></span></span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span><span style="color:fuchsia;">CONVERT<span style="color:blue;"><span style="color:gray;">(<span style="color:blue;">datetime<span style="color:gray;">, </span><span style="color:teal;">es<span style="color:gray;">.<span style="color:teal;">end_time<span style="color:gray;">) </span><span style="color:blue;">AS</span> end_time</span><br />
</span></span></span></span></span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span><span style="color:teal;">es<span style="color:gray;">.<span style="color:teal;">execution_duration </span></span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span><span style="color:teal;">es<span style="color:gray;">.<span style="color:teal;">statistics_id</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span><span style="color:teal;">es<span style="color:gray;">.<span style="color:teal;">execution_result</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span><span style="color:blue;">case </span><span style="color:teal;">es<span style="color:gray;">.<span style="color:teal;">execution_result</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">when</span> 0 <span style="color:blue;">then </span><span style="color:red;">&#8216;Success&#8217;</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">when</span> 1 <span style="color:blue;">then </span><span style="color:red;">&#8216;Failure&#8217;</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;"><span style="color:#000000;">     </span>when</span> 2 <span style="color:blue;">then </span><span style="color:red;">&#8216;Completion&#8217;</span><br />
</span><span style="font-family:Consolas;font-size:9pt;">    <span style="color:blue;">when</span> 3 <span style="color:blue;">then </span><span style="color:red;">&#8216;Cancelled&#8217;</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;"><span style="color:#000000;">  </span>end </span> <span style="color:blue;">as </span><span style="color:teal;">execution_result_description</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from </span><span style="color:blue;">catalog<span style="color:gray;">.<span style="color:teal;">executables </span><span style="color:teal;">e</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">join </span><span style="color:blue;">catalog<span style="color:gray;">.<span style="color:teal;">executable_statistics </span><span style="color:teal;">es</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">on </span> <span style="color:teal;">e<span style="color:gray;">.<span style="color:teal;">executable_id</span> =</span> es<span style="color:gray;">.<span style="color:teal;">executable_id</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;"> and </span><span style="color:teal;">e<span style="color:gray;">.<span style="color:teal;">execution_id</span> =</span> es<span style="color:gray;">.<span style="color:teal;">execution_id</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">where </span><span style="color:teal;">package_path </span> <span style="color:gray;">= </span> <span style="color:red;">&#8216;\Package&#8217;</span><br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">and </span> <span style="color:teal;">e<span style="color:gray;">.<span style="color:teal;">execution_id</span> =</span> 10275</span></span></td>
</tr>
<tr>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:solid #d9d9d9 .5pt;border-bottom:solid #d9d9d9 .5pt;border-right:solid #d9d9d9 .5pt;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe6.png?w=595" /></td>
</tr>
</tbody>
</table>
</div>
<p><span style="text-decoration:underline;"><strong>A Word of Caution<br />
</strong></span></p>
<p>while they SSISDB database can be used to provide some nice reporting, the executions view contain some inbuilt security which implements row security. If we examine the definition of the view we can see that the where clause includes the following conditions.</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #d9d9d9 .5pt;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">WHERE </span> <span style="color:teal;">opers<span style="color:gray;">.<span style="color:teal;">[operation_id]</span> in <span style="color:blue;"> <span style="color:gray;">(<span style="color:blue;">SELECT </span><span style="color:teal;">id </span> <span style="color:blue;">FROM </span> <span style="color:teal;">[internal]<span style="color:gray;">.<span style="color:teal;">current_user_readable_operations]<span style="color:gray;">)</span></span></span></span></span></span></span></span></span><span style="font-family:Consolas;font-size:9pt;"><br />
<span style="color:gray;">OR <span style="color:blue;"> <span style="color:gray;">(<span style="color:fuchsia;">IS_MEMBER<span style="color:gray;">(<span style="color:red;">&#8216;ssis_admin&#8217;<span style="color:gray;">) </span> <span style="color:gray;">=</span> 1<span style="color:gray;">)</span><br />
</span></span></span></span></span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">OR <span style="color:blue;"> <span style="color:gray;">(<span style="color:fuchsia;">IS_SRVROLEMEMBER<span style="color:gray;">(<span style="color:red;">&#8216;sysadmin&#8217;<span style="color:gray;">) </span><span style="color:gray;">=</span> 1<span style="color:gray;">)</span></span></span></span></span></span></span></span></td>
</tr>
</tbody>
</table>
</div>
<p>The credential for accessing the database should be a member of ssis_amdin or sysadmin role. If not, no rows are returned.</p>
<p><em>I will leave it to your own devices to come up with alternate methods for bypassing this requirement.<br />
</em></p>
<p><em><br />
</em></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/586/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=586&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/03/14/ssis-2012-execution-reporting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe1.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe2.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe3.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe4.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe5.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/031413_0018_ssis2012exe6.png" medium="image" />
	</item>
		<item>
		<title>Creating Custom Calculations in Excel with Pivot Table Extensions</title>
		<link>http://paultebraak.wordpress.com/2013/03/05/creating-custom-calculations-in-excel-with-pivot-table-extensions/</link>
		<comments>http://paultebraak.wordpress.com/2013/03/05/creating-custom-calculations-in-excel-with-pivot-table-extensions/#comments</comments>
		<pubDate>Tue, 05 Mar 2013 10:29:03 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[MDX]]></category>
		<category><![CDATA[Calculations]]></category>
		<category><![CDATA[PivotTables]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=575</guid>
		<description><![CDATA[One of the biggest hurdles that users are faced with when using Pivot Tables is that all measures and dimensions must be defined within the cube. Having the defined data available is really convenient for drag and drop analysis however in most situations, the users requirements can quickly outgrow the bounds of the definition of [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=575&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>One of the biggest hurdles that users are faced with when using Pivot Tables is that all measures and dimensions must be defined within the cube. Having the <strong>defined</strong> data available is really convenient for drag and drop analysis however in most situations, the users requirements can quickly outgrow the bounds of the definition of the cube. <em>I want to see such and such in my data </em>is the usual type of requirement. Sure, developers and report writers can create calculations but what about users – the people that need to use the data? This post looks at <a href="https://olappivottableextend.codeplex.com/">OLAP PivotTable Extensions</a>, a tool which increases the usability of pivot tables for end users.</p>
<p>Traditional PivotTables just don&#8217;t give the user enough flexibility. Sure Excel 2013 has some nice features for creating calculations in Pivots but I haven&#8217;t worked with any corporate client that is seriously considering using 2013 just yet. There is just too much corporate tape to cut through. So let me just say<strong>, if your users aren&#8217;t using this tool, they should be</strong>. You may argue that users could use Power Pivot but, that really defeats the purpose of having a cube doesn&#8217;t it? Besides, why should the users have to handle data just to do some simple analysis? Besides that, the addin is free, <em>talk about a lower barrier to entry for self-service BI</em>!</p>
<p>This post looks at creating calculations using the OLAP pivot table extensions addin.</p>
<p><span style="text-decoration:underline;"><strong>A Quick Overview<br />
</strong></span></p>
<p>Once the <a href="https://olappivottableextend.codeplex.com/">add-in</a> has been installed it can be accessed from a pivot table by simply right clicking on that pivot table. For example, consider the pivot table below which shows the [sales amount] and [sales quota] by year in adventure works. To add a custom calculation to this pivot, all I need to do is right click and select &#8220;OLAP Pivot Table Extnesions …&#8221;</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus1.png?w=595" /></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus2.png?w=595" /></p>
<p>This opens the following window (note that the calculations tab is selected);</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus3.png?w=595" /></p>
<p><span style="text-decoration:underline;"><strong>Calculations On Measures<br />
</strong></span></p>
<p>The first example that we can use for creating a calculation involves creating a new measure that is based on other measures. For example based on the [Sales Amount] and [Sales Amount Quota], we might like to see what the variance is. We can express this as [Sales Amount] &#8211; [Sales Amount Quota] but we should remember two things;</p>
<p>Firstly, there are spaces in in the names so we need to surround the name with square bracket (ie [, ]).</p>
<p>Secondly, the pivot is based on MDX. This is a decorative language and has its own rules. While these rules can sometimes be bypassed (as we will see below), it&#8217;s probably the better idea to use the fully qualified name for items that are referring to.</p>
<p>If we consider the requirement for sales variance (lets call it [sales variance]) we could simply create the measure using the following formula [Sales Amount] &#8211; [Sales Amount Quota]. This is shown below as;</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus4.png?w=595" /></p>
<p>Once the measure has been defined I can added to the pivot table by clicking the &#8216;Add to Pivot Table&#8217; button.</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus5.png?w=595" /></p>
<p><span style="text-decoration:underline;"><strong>Fully Qualified Names<br />
</strong></span></p>
<p>I stated above that MDX has requirements for how we refer to items in the language, and it is a good idea to use the fully qualified name. An exception to this is the requirement to use the fully qualified names for measures. For example if we are in cell C8 and we create a formula that references C5, we can see that Excel adds its own calculation (one that users the formula GETPIVOTDATA).</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus6.png?w=595" /></p>
<p>By examining this formula, we can see that the fully qualified name for the [Sales Amount] measure is [Meaures].[Sales Amount]. <em>Also note that the fully qualified name for [CY 2008] is [Date].[Calendar Year].&amp;[2008].</em></p>
<p>The use of the GETPIVOTDATA function is a very useful trick that you can use to determine fully qualified name for pivot cells.</p>
<p><span style="text-decoration:underline;"><strong>Using Static References<br />
</strong></span></p>
<p>One of the restrictions of pivot tables is that it&#8217;s very hard to reference individual cells in the pivot. For example, if we wished to show the sales amount for 2005 in the pivot we would generally filter columns or rows to 2005 and add the [sales amount] measure. We can use the pivot table extensions with a static reference to include the 2005 sales amount value as a column in the pivot. All we have to do is to create a new measure for the cell coordinates that we are interested in.</p>
<p>Consider the GETPIVOTDATA formula for the sales amount in 2005, that is;</p>
<p><span style="font-family:Courier New;font-size:10pt;">=GETPIVOTDATA(&#8220;[Measures].[Sales Amount]&#8220;,$A$1,&#8221;[Date].[Calendar Year]&#8220;,&#8221;[Date].[Calendar Year].&amp;[2005]&#8220;)<br />
</span></p>
<p><span style="font-size:10pt;">We can simply create a measure that references this coordinate. This is ( [Sales Amount] , [Date].[Calendar Year].&amp;[2005] )<br />
</span></p>
<p><span style="font-size:10pt;"><strong><em>Note that coordinates should be enclosed in parenthesis and separated by commas.<br />
</em></strong></span></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus7.png?w=595" /><span style="font-size:10pt;"><strong><br />
</strong></span></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus8.png?w=595" /><span style="font-size:10pt;"><strong><br />
</strong></span></p>
<p><span style="font-size:10pt;">A really cool thing about creating this new measure is that we can use it by other measures. So we could show the variance compared to 2005 (Sales Amount Measure) by creating a measure that refers to the [Sales Amount 2005] measure. This measure would be;<br />
</span><span style="font-family:Courier New;font-size:10pt;">[Sales Amount] &#8211; [Sales Amount 2005]<br />
</span></p>
<p><span style="font-size:10pt;">Note, that we did not have to keep &#8216;referenced&#8217; measures in the pivot table to use their outcome. For example we can remove the measure [Sales Amount 2005] from the pivot table and see the measure [Sales Variance 2005] in the pivot. Measures are removed just as any pivot measure, by dragging them from the &#8216;Values&#8217; box in the field selection list.<br />
</span></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus9.png?w=595" /><span style="font-size:10pt;"><br />
</span></p>
<p><span style="font-size:10pt;">The use of the word<strong> static</strong> to this section implies that we will only reference data from 2005 in our calculated measure. <strong>More often than not we want to refer to a coordinate in the context of another. This is usually the &#8216;next year&#8217; or the &#8216;prior year&#8217;.</strong> For example we might like to see the [Sales Amount] variance compared to last year. In order to achieve this we will create a measure [Sales Amount LY] and [Sales Variance LY].<br />
</span></p>
<p><span style="font-size:10pt;text-decoration:underline;"><strong>Calculations using Relative References<br />
</strong></span></p>
<p><span style="font-size:10pt;">If we recall the GETPIVOTDATA formula for the sales amount in 2005, we can also discover that the &#8217;2005&#8242; amount relates to a specific dimension, and the hierarchy within that dimension. We can see this in the highlighted sections below;<br />
</span></p>
<p><span style="font-size:10pt;"><span style="font-family:Courier New;">=GETPIVOTDATA(&#8220;[Measures].[Sales Amount]&#8220;,$A$1<span style="background-color:yellow;">,&#8221;[Date].[Calendar Year]</span>&#8220;,&#8221;<span style="background-color:yellow;">[Date].[Calendar Year]</span>.&amp;[2005]&#8220;)</span><span style="text-decoration:underline;"><strong><br />
</strong></span></span></p>
<p><span style="font-size:10pt;">These both give us the same information, specifically that the hierarchy <span style="font-family:Courier New;">[Date].[Calendar Year] </span>is being used. Additionally, we should know that each row actually refers to a specific member (for example 2005). If we want to create a measure that uses a relative reference we have two to use the hierarchy name and the relative function.<br />
</span></p>
<p><span style="font-size:10pt;"><strong>Arguably the .prevmember function is one of the most useful relative functions available.</strong> This function takes the current coordinate (item) and substitutes the prior one for it. Therefore, if we are on the 2006 row, the .prevmember would give us the 2005 coordinate. Also note that because we are using a relative function, the &#8216;exact&#8217; coordinate is not referred to, rather the hierarchy is used in formulas.<br />
</span></p>
<p><span style="font-size:10pt;">Therefore, we can get the prior year of a row using the following coordinate <span style="font-family:Courier New;">[Date].[Calendar Year].prevmember<br />
</span></span></p>
<p><span style="font-size:10pt;">This may seem a little bit complicated at first, and it may help to think that the rows shown are from the <span style="font-family:Courier New;">[Date].[Calendar Year] </span>hierarchy, rather than specific values. For example <span style="font-family:Courier New;">[Date].[Calendar Year].&amp;[2005].<br />
</span></span></p>
<p><span style="font-size:10pt;">If we wish to create a calculated measure to show what sells amount was last year we simply need to use the formula<br />
</span></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus10.png?w=595" /><span style="font-size:10pt;"><br />
</span></p>
<p><span style="font-size:10pt;">The measure [Sales Var LY] is simply <span style="font-family:Courier New;">[Sales Amount] &#8211; [Sales Amount LY].<br />
</span></span></p>
<p><span style="font-size:10pt;">The results of these calculations are shown on screen shot below;<br />
</span></p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus11.png?w=595" /><span style="font-size:10pt;"><br />
</span></p>
<p><span style="font-size:10pt;text-decoration:underline;"><strong>Conclusion<br />
</strong></span><span style="font-size:10pt;">The use of the OLAP PivotTable Extensions offers a huge improvement to the usability of pivot tables. This post is looked at the ability to create custom calculations within the pivot so that the user can create their own analysis.<br />
</span></p>
<p><span style="font-size:10pt;text-decoration:underline;"><strong>References<br />
</strong></span><span style="font-size:10pt;">Download the addin <a href="https://olappivottableextend.codeplex.com/">here</a><br />
</span><span style="font-size:10pt;">Prevmember function reference on <a href="http://msdn.microsoft.com/en-us/library/ms144719.aspx">MSDN</a><br />
</span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/575/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/575/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=575&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/03/05/creating-custom-calculations-in-excel-with-pivot-table-extensions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus1.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus2.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus3.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus4.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus5.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus6.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus7.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus8.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus9.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus10.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/03/030513_1027_creatingcus11.png" medium="image" />
	</item>
		<item>
		<title>Rank Partitioning in ETL using SSIS</title>
		<link>http://paultebraak.wordpress.com/2013/02/25/rank-partitioning-in-etl-using-ssis/</link>
		<comments>http://paultebraak.wordpress.com/2013/02/25/rank-partitioning-in-etl-using-ssis/#comments</comments>
		<pubDate>Mon, 25 Feb 2013 08:52:44 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[SSIS]]></category>
		<category><![CDATA[SSIS;Partition;Script Component]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=561</guid>
		<description><![CDATA[A common use of partitioning functions within an SQL query is to rank data with in subsets of results. For example, using Adventure Works we may want to ask &#8220;what&#8217;s the sales rank of each product within each subcategory?&#8221; or, &#8220;what&#8217;s the best selling product with in each subcategory&#8221; ? Partitioning functions in SQL server [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=561&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A common use of partitioning functions within an SQL query is to rank data with in subsets of results. For example, using Adventure Works we may want to ask &#8220;what&#8217;s the sales rank of each product within each subcategory?&#8221; or, &#8220;what&#8217;s the best selling product with in each subcategory&#8221; ? Partitioning functions in SQL server allow us to answer this type of question easily. There are also many uses for partitioning in an ETL process when a query cannot be executed against prepared data within SQL Server. Consider the requirement to determine the likely value of codes based on ordered logic. In this situation, we have to determine what descriptions are given to codes where there are many code, name combinations.</p>
<p>This post looks at how to include partitioning with a SSIS Data Flow.</p>
<p><span style="text-decoration:underline;"><strong>Why use SSIS?</strong></span></p>
<p>With the availability of partitioning within SQL Server, you may question why would this be required within SSIS? The main reason for doing so is simply because the required data may not be available from a single SQL Server or we wish to combine multiple data sources. Without an integrated data, an SQL query is simply not a viable option partitioning.</p>
<p>One way to create an integrated data set would be to create a &#8216;temporary table&#8217; in SQL Server and then query it, however, this is a cumbersome process because it requires multiple staging and extract layers. A more succinct approach is to simply EXTRACT, TRANSFORM and LOAD data in one step without touching the relational engine multiple times. Besides that, performance is better since there are no duplicate loads!</p>
<p><span style="text-decoration:underline;"><strong>The SQL Function<br />
</strong></span></p>
<p>In this example we are trying to mimic the SQL row_number() function (output as below). That is, we are seeking to ranks the products based on order_quantity within each sub-category.</p>
<div style="text-align:center;">
<table style="border-collapse:collapse;" border="0">
<col style="width:638px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:none;">
<p style="text-align:left;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select</span><br />
</span><span style="font-family:Consolas;font-size:9pt;">    <span style="color:teal;">psc<span style="color:gray;">.<span style="color:teal;">EnglishProductSubcategoryName </span><span style="color:blue;">as </span><span style="color:teal;">sub_category</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">  , </span> <span style="color:teal;">p<span style="color:gray;">.<span style="color:teal;">ProductAlternateKey </span> <span style="color:blue;">as </span><span style="color:teal;">product_id</span><br />
,  </span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:fuchsia;">sum<span style="color:gray;">(<span style="color:teal;">fis<span style="color:gray;">.<span style="color:teal;">OrderQuantity<span style="color:gray;">) </span><span style="color:blue;">as</span> order_quantity</span><br />
</span></span></span></span></span><span style="font-family:Consolas;font-size:9pt;"> <span style="color:gray;">,  </span><span style="color:fuchsia;">ROW_NUMBER<span style="color:gray;">() </span><span style="color:blue;">over <span style="color:gray;">(</span>    partition </span> <span style="color:blue;">by </span> <span style="color:teal;">psc<span style="color:gray;">.<span style="color:teal;">EnglishProductSubcategoryName</span><br />
</span></span></span></span><span style="font-family:Consolas;font-size:9pt;">                            <span style="color:blue;">order </span><span style="color:blue;">by </span><span style="color:fuchsia;">sum<span style="color:gray;">(<span style="color:teal;">fis<span style="color:gray;">.<span style="color:teal;">OrderQuantity<span style="color:gray;">) </span><span style="color:blue;">desc</span><br />
</span></span></span></span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">                       ) </span><span style="color:blue;">as </span><span style="color:teal;">row_rank</span><br />
</span></p>
<p style="text-align:left;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from </span> <span style="color:teal;">dbo<span style="color:gray;">.<span style="color:teal;">DimProduct </span> <span style="color:teal;">p</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">join </span> <span style="color:teal;">dbo<span style="color:gray;">.<span style="color:teal;">FactInternetSales </span> <span style="color:teal;">fis</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;">    <span style="color:blue;">on </span> <span style="color:teal;">p<span style="color:gray;">.<span style="color:teal;">ProductKey</span> =</span> fis<span style="color:gray;">.<span style="color:teal;">ProductKey</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">join </span> <span style="color:teal;">dbo<span style="color:gray;">.<span style="color:teal;">DimProductSubcategory </span> <span style="color:teal;">psc</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;">    <span style="color:blue;">on </span> <span style="color:teal;">p<span style="color:gray;">.<span style="color:teal;">ProductSubcategoryKey</span> =</span> psc<span style="color:gray;">.<span style="color:teal;">ProductSubcategoryKey</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">group </span> <span style="color:blue;">by</span><br />
<span style="color:teal;">psc<span style="color:gray;">.<span style="color:teal;">EnglishProductSubcategoryName<span style="color:gray;">,</span> p<span style="color:gray;">.<span style="color:teal;">ProductAlternateKey</span><br />
</span></span></span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">order </span> <span style="color:blue;">by</span><br />
<span style="color:teal;">sub_category<span style="color:gray;">,</span> row_rank</span><br />
</span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p style="text-align:center;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti1.png?w=595" /></p>
<p><span style="text-decoration:underline;"><strong>Implementing a Data Flow Approach<br />
</strong></span></p>
<p>When implementing this solution within a data flow task we note that the data is ranked by sub-category and order quantity (in at order). Then, the rank simply follows the following criteria;</p>
<ol>
<li>Use a number counter to determine the row_order. This increments by one with each new row within the same sub_category.</li>
<li>When a new sub-category is found, the row_order defaults to 1 (since this must be the first new product within a new sub_category group).</li>
</ol>
<p>This can be seen by looking at the subcategories below. Note that the data is ordered by sub_category and order_quantity (descending). Each time we change sub_category, we simply reset a counter to 1.</p>
<p style="text-align:center;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti2.png?w=595" /><span style="text-decoration:underline;"><strong><br />
</strong></span></p>
<p>The dataflow looks very simple. Note that I have included the order_quantity in the products_src datasource. Practically (to satisfy the non-sql criteria) this would be included by reference to a lookup task.</p>
<div style="text-align:center;">
<table style="border-collapse:collapse;" border="0">
<col style="width:236px;" />
<col style="width:403px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:none;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti3.png?w=595" /></td>
<td style="padding-left:7px;padding-right:7px;border:none;">
<p style="text-align:left;"><span style="color:blue;font-family:Consolas;font-size:9pt;">// Data source query<br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select</span><br />
</span><span style="color:teal;font-family:Consolas;font-size:9pt;">ps<span style="color:gray;">.<span style="color:teal;">EnglishProductSubcategoryName </span><span style="color:blue;">as </span> <span style="color:teal;">sub_category</span><br />
</span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span><span style="color:teal;">p<span style="color:gray;">.<span style="color:teal;">ProductAlternateKey </span> <span style="color:blue;">as </span> <span style="color:teal;">product_id</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span><span style="color:fuchsia;">sum<span style="color:gray;">(<span style="color:teal;">fis<span style="color:gray;">.<span style="color:teal;">OrderQuantity<span style="color:gray;">) </span><span style="color:blue;">as</span> order_quantity</span><br />
</span></span></span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from </span> <span style="color:teal;">dbo<span style="color:gray;">.<span style="color:teal;">FactInternetSales </span><span style="color:teal;">fis</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">join </span> <span style="color:teal;">dbo<span style="color:gray;">.<span style="color:teal;">DimProduct </span> <span style="color:teal;">p</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;">    <span style="color:blue;">on </span> <span style="color:teal;">fis<span style="color:gray;">.<span style="color:teal;">ProductKey</span> =</span> p<span style="color:gray;">.<span style="color:teal;">ProductKey</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">join </span> <span style="color:teal;">dbo<span style="color:gray;">.<span style="color:teal;">DimProductSubcategory </span> <span style="color:teal;">ps</span><br />
</span></span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">on </span> <span style="color:teal;">p<span style="color:gray;">.<span style="color:teal;">ProductSubcategoryKey</span> =</span> ps<span style="color:gray;">.<span style="color:teal;">ProductSubcategoryKey</span><br />
</span></span></span></p>
<p style="text-align:left;"><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">group </span><span style="color:blue;">by </span></span><span style="color:teal;font-family:Consolas;font-size:9pt;">ps<span style="color:gray;">.<span style="color:teal;">EnglishProductSubcategoryName</span><br />
</span></span><span style="font-family:Consolas;font-size:9pt;"><span style="color:gray;">, </span> <span style="color:teal;">p<span style="color:gray;">.<span style="color:teal;">ProductAlternateKey</span><br />
</span></span></span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>Secondly, the input data is sorted by the required partitioning scheme. This includes the sorting field for the rank qualifier. As below, this is defined as the order_quantity within sub_category.</p>
<p style="text-align:center;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti4.png?w=595" /></p>
<p><span style="text-decoration:underline;"><strong>Adding the Script Task<br />
</strong></span></p>
<p>When the scripting task is added to the dataflow, specify the transform option and add an additional column for the row_rank (see below). We also need to access the sub_cateogory field within the transform so this must be specified as an input (below).</p>
<p style="text-align:center;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti5.png?w=595" /></p>
<p style="text-align:center;"><span style="color:#4f81bd;font-size:9pt;"><strong>Image 1 &#8211; Add a Colum to the output<br />
</strong></span></p>
<p style="text-align:center;"><img alt="" src="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti6.png?w=595" /><span style="text-decoration:underline;"><strong><br />
</strong></span></p>
<p><span style="text-decoration:underline;"><strong>Scripting Code<br />
</strong></span></p>
<p>By default, the script task as has three methods (PreExecute, PostExecute &amp; ProcessRow). As the name implies these are processed before, after and during the consumption of the buffer. Additionally, we can utilise a global variable within class. The use of class variables allows us to keep track of the &#8216;current&#8217; sub_category and row_rank (that is, the &#8216;current&#8217; sub_category and row_number). If the row sub_category is not the same as the global sub_category, we know we have a new sub_category.</p>
<p>The code for this is shown below.</p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">public</span><br />
<span style="color:blue;">class</span><br />
<span style="color:#2b91af;">ScriptMain</span> : <span style="color:#2b91af;">UserComponent</span><br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">{<br />
</span><span style="font-family:Consolas;font-size:9pt;"> <span style="color:blue;">string</span> _sub_category = <span style="color:#a31515;">&#8220;&#8221;</span>;<br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">int</span> _row_rank = 1;<br />
</span><span style="font-family:Consolas;font-size:9pt;"><br />
<span style="color:blue;">public </span> <span style="color:blue;">override </span> <span style="color:blue;">void</span> Input0_ProcessInputRow(<span style="color:#2b91af;">Input0Buffer</span> Row)<br />
</span><span style="font-family:Consolas;font-size:9pt;">{<br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">if</span> (Row.subcategory != _sub_category)<br />
</span><span style="font-family:Consolas;font-size:9pt;">{<br />
</span><span style="font-family:Consolas;font-size:9pt;">_row_rank = 1;<br />
</span><span style="font-family:Consolas;font-size:9pt;">Row.rowrank = _row_rank;<br />
</span><span style="font-family:Consolas;font-size:9pt;">}<br />
</span><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">else</span><br />
</span><span style="font-family:Consolas;font-size:9pt;">{<br />
</span><span style="font-family:Consolas;font-size:9pt;">_row_rank++;<br />
</span><span style="font-family:Consolas;font-size:9pt;">Row.rowrank = _row_rank;<br />
</span><span style="font-family:Consolas;font-size:9pt;">}<br />
</span><span style="font-family:Consolas;font-size:9pt;">}<br />
</span><span style="font-family:Consolas;font-size:9pt;">}<br />
</span></p>
<p>The Output of the buffer can be seen below;</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti7.png?w=595" /><span style="text-decoration:underline;"><strong><br />
</strong></span></p>
<p><span style="text-decoration:underline;"><strong><br />
</strong></span></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/561/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/561/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=561&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/02/25/rank-partitioning-in-etl-using-ssis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>

		<media:content url="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti1.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti2.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti3.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti4.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti5.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti6.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/02/022513_0852_rankpartiti7.png" medium="image" />
	</item>
		<item>
		<title>Pivot Filtering with Cell Selection and VBA</title>
		<link>http://paultebraak.wordpress.com/2013/01/25/pivot-filtering-with-cell-selection-and-vba/</link>
		<comments>http://paultebraak.wordpress.com/2013/01/25/pivot-filtering-with-cell-selection-and-vba/#comments</comments>
		<pubDate>Fri, 25 Jan 2013 03:30:28 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[MDX]]></category>
		<category><![CDATA[SSAS]]></category>
		<category><![CDATA[Reports]]></category>
		<category><![CDATA[Slicer]]></category>
		<category><![CDATA[VBA]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=545</guid>
		<description><![CDATA[This post looks at applying data filters in Excel workbooks with sheet &#8216;click&#8217; functionality for filtering. The purpose of this is to provide a rich user experience for reporting within Excel. With these types of reports, you present some data in a pivot which is used to as a source filter for other parts of [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=545&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This post looks at applying data filters in Excel workbooks with sheet &#8216;click&#8217; functionality for filtering. The purpose of this is to provide a rich user experience for reporting within Excel. With these types of reports, you present some data in a pivot which is used to as a source filter for other parts of your report (or worksheet). Consider the situation below; when you click on one of the country names in the pivot, the chart is automatically updated to filter for that country. Clicking on any other area of the pivot removes any chart filter.</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/01/012513_0330_pivotfilter1.png?w=595" /></p>
<p><em>Why would you do this?</em></p>
<p><em>Monthly reporting workbooks are often treated as report packs and designed in lieu of an enterprise reporting system. Even where such an enterprise reporting system are in-place, the reporting environments are usually not flexible enough to provide the business what they need for monthly reporting and so the workbooks are bundled together in Excel. These workbooks can be extended to have highly interactive functionality that mimics high-end reporting tools.<br />
</em></p>
<p><em>While you could achieve these results with a slicer, the automation of the action may provide a nicer experience for the user because it removes the slicer clutter from the page and allows a direct association with the data being investigated.<br />
</em></p>
<p><span style="text-decoration:underline;"><strong>How to Do IT<br />
</strong></span></p>
<p>Achieving this functionality is conceptually pretty simple (and soon programmatically simple too <span style="font-family:Wingdings;">J</span>), all we need to do is;</p>
<ol>
<li>Listen for changes in the cell position on a worksheet.</li>
<li>When a change is detected, we check that the change was to our source pivot</li>
<li>Determine the filter value (ie what value was clicked in the pivot) … and</li>
<li>Apply that value to the slicer for the chart.</li>
</ol>
<p>These items are now discussed individually.</p>
<p><span style="text-decoration:underline;"><strong>Work Book Setup<br />
</strong></span></p>
<p>In this example, I am using an Adventure Works connection with a pivot table and pivot chart. The pivot table (the one you click a cell on) is called &#8216;country_sales&#8217;. This uses the customer.country hierarchy from adventure works. The pivot chart has a slicer linked to it (and the name of the slicer is &#8216;Slicer_Counrty&#8217;). Note that the same hierarchy must be used for both the slicer and pivot table.</p>
<p><span style="text-decoration:underline;"><strong>Listening for changes in the worksheet<br />
</strong></span></p>
<p>Each worksheet has its own code module with defined events. An event is a subroutine that is &#8216;inbuilt&#8217; into Excel and fired when something happens in Excel (for example, when the user changes the active cell). You can see the worksheets module by double clicking the sheet in the project explorer or with a right-click and &#8216;View Code&#8217; and see the events by selecting them from the dropdown (as shown below).</p>
<p><img alt="" src="http://paultebraak.files.wordpress.com/2013/01/012513_0330_pivotfilter2.png?w=595" /></p>
<p>When you do this (and choose the event SelectionChange), you&#8217;ll see the following subroutine added to your module</p>
<p><span style="color:#4f81bd;font-family:Courier New;"><strong>Private Sub Worksheet_SelectionChange(ByVal Target As Range)<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;"><strong>End Sub<br />
</strong></span></p>
<p>Now, that this has been added, this procedure will fire every time you change selection cells on Sheet1. It also may be worthwhile to note that the Target parameter refers to the range of cells that&#8217;s selected (as part of the selection). Because you can select more than 1 cell, we want to check for single cell selection so we simply exit the sub if there is more than on cell in the range.</p>
<p><span style="color:#4f81bd;font-family:Courier New;"><strong>If (Target.Cells.Count &lt;&gt; 1) Then Exit Sub<br />
</strong></span></p>
<p><span style="text-decoration:underline;"><strong>Detecting the Source Pivot and the Active Cell Value<br />
</strong></span></p>
<p>There are some pretty handy functions to determine if the active cell relates to a pivot table, and if it does, that the member name is and what its value is. These relate to the <strong>activecell </strong>and are the properties<strong><br />
</strong></p>
<p style="margin-left:36pt;"><span style="font-family:Courier New;"><strong>.PivotTable</strong></span></p>
<p style="margin-left:36pt;"><span style="font-family:Courier New;"><strong>.PivotItem </strong></span></p>
<p style="margin-left:36pt;"><span style="font-family:Courier New;"><strong>.PivotField<br />
</strong></span></p>
<p>Thus, in order to determine what the name of a pivot table for the active cell we would simply write;</p>
<p><span style="color:#4f81bd;font-family:Courier New;"><strong>Dim source_pivot_name As String<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;"><strong>source_pivot_name = ActiveCell.PivotTable.Name<br />
</strong></span></p>
<p>The name (MDX value) of a column could be determined by<span style="color:#4f81bd;font-family:Courier New;"><strong> ActiveCell.PivotItem.Name<br />
</strong></span></p>
<p>and the (MDX) name of the attribute<span style="font-family:Courier New;"><strong><br />
<span style="color:#4f81bd;">(Dimension.Hierarchy.Level) </span></strong></span>determined by <span style="font-family:Courier New;"><strong> <span style="color:#4f81bd;">ActiveCell.PivotField.Name<br />
</span></strong></span></p>
<p>For example, if I click on the France &#8216;country columns&#8217; in my pivot table, I would get the following values.</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:319px;" />
<col style="width:319px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;border:solid #bfbfbf .5pt;"><span style="color:#4f81bd;font-family:Courier New;">ActiveCell.PivotTable.Name</span></td>
<td style="padding-left:7px;padding-right:7px;border-top:solid #bfbfbf .5pt;border-left:none;border-bottom:solid #bfbfbf .5pt;border-right:solid #bfbfbf .5pt;"><span style="color:#4f81bd;font-family:Courier New;">&#8220;country_sales&#8221;</span></td>
</tr>
<tr>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:solid #bfbfbf .5pt;border-bottom:solid #bfbfbf .5pt;border-right:solid #bfbfbf .5pt;"><span style="color:#4f81bd;font-family:Courier New;">ActiveCell.PivotField.Name</span></td>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:none;border-bottom:solid #bfbfbf .5pt;border-right:solid #bfbfbf .5pt;"><span style="color:#4f81bd;font-family:Courier New;">&#8220;[Customer].[Country].[Country]&#8220;</span></td>
</tr>
<tr>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:solid #bfbfbf .5pt;border-bottom:solid #bfbfbf .5pt;border-right:solid #bfbfbf .5pt;"><span style="color:#4f81bd;font-family:Courier New;">ActiveCell.PivotItem.Name</span></td>
<td style="padding-left:7px;padding-right:7px;border-top:none;border-left:none;border-bottom:solid #bfbfbf .5pt;border-right:solid #bfbfbf .5pt;"><span style="color:#4f81bd;font-family:Courier New;">&#8220;[Customer].[Country].&amp;[France]&#8220;</span></td>
</tr>
</tbody>
</table>
</div>
<p>Note that the pivot values references are to the object model (ie the Pivot object). If the cell your referring to (the activecell) is not part of a pivot table, you&#8217;ll get an error. This is pretty easy to catch with some error trapping (see final code).</p>
<p>Assuming that the user clicked on a cell in the pivot (I will leave the checks for the final code) we have all the values that we need and can then set the slicer.</p>
<p><span style="text-decoration:underline;"><strong>Applying the filter to the Slicer<br />
</strong></span></p>
<p>I have discussed applying how to apply slicer value in VBA in this <a href="http://paultebraak.wordpress.com/2012/02/24/accessing-the-slicer-through-vba/">post</a>. For brevity, I&#8217;ll just include the essential items. We simply make a reference to the slicer (SlicerCache) and set its value.</p>
<p><span style="color:#4f81bd;font-family:Courier New;"><strong>Dim sC As SlicerCache<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;"><strong>Set sC = ActiveWorkbook.SlicerCaches(&#8220;Slicer_Country&#8221;)<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;"><strong>sC.VisibleSlicerItemsList = Array(ActiveCell.PivotItem.Name)<br />
</strong></span></p>
<p>If I want to remove the slicers current filter (when no &#8216;country is needed), I can do that with this code;</p>
<p><span style="color:#4f81bd;font-family:Courier New;"><strong>sC.ClearManualFilter<br />
</strong></span></p>
<p><span style="text-decoration:underline;"><strong>Complete Code<br />
</strong></span></p>
<p>The following code demonstrates the complete solution. I have included updating the &#8216;title&#8217; of the chart and error traps to determine if a &#8216;non country&#8217; part of the pivot was chosen.</p>
<p><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>Private Sub Worksheet_SelectionChange(ByVal Target As Range)<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  If (Target.Cells.Count &lt;&gt; 1) Then Exit Sub<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  Dim source_pivot_name As String<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  source_pivot_name = &#8220;&#8221;<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  Dim source_field As String<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  source_field = &#8220;&#8221;<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  Dim source_attribute As String<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  source_attribute = &#8220;&#8221;<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  Dim sC As SlicerCache<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  Set sC = ActiveWorkbook.SlicerCaches(&#8220;Slicer_Country&#8221;)<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>  On Error GoTo continue<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong><span style="color:#9bbb59;">  &#8216;try and get the active cells pivot table name<br />
</span></strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>source_pivot_name = ActiveCell.PivotTable.Name<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>continue:<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong><span style="color:#9bbb59;">&#8216;we can only apply a filter if we are on our &#8216;selection pivot&#8217;<span style="color:#4f81bd;"><br />
</span></span></strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>If source_pivot_name = &#8220;country_sales&#8221; Then<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong><span style="color:#9bbb59;"><span style="color:#4f81bd;">  </span>&#8216;note the name must go first so we can check for a &#8216;Row Labels&#8217; Position<span style="color:#4f81bd;"><br />
</span></span></strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>On Error GoTo continue2<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>source_attribute = ActiveCell.PivotField.Name<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>On Error GoTo continue3<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>source_field = ActiveCell.PivotItem.Name<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>continue2:<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>continue3:<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong><span style="color:#9bbb59;">&#8216;check we have the correct source<span style="color:#4f81bd;"><br />
</span></span></strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>If (Len(source_attribute) &gt; 10 And Left(source_attribute, 10) = &#8220;[Measures]&#8220;) Or _<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>(source_field = &#8220;&#8221; And source_attribute = &#8220;[Customer].[Country].[Country]&#8220;) Then<br />
</strong></span><span style="color:#9bbb59;font-family:Courier New;font-size:8pt;"><strong>&#8216;set to all<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>sC.ClearManualFilter<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>Sheet1.Cells(11, 4) = &#8220;Category Sales for All Areas&#8221;<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>Else<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>sC.VisibleSlicerItemsList = Array(source_field)<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>Sheet1.Cells(11, 4) = &#8220;Category Sales for &#8221; &amp; ActiveCell.Value<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>End If<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong> End If<br />
</strong></span><span style="color:#4f81bd;font-family:Courier New;font-size:8pt;"><strong>End Sub<br />
</strong></span></p>
<p><span style="text-decoration:underline;"><strong>Conclusion<br />
</strong></span></p>
<p>Adding some interactive functionality to a pivot is a pretty simple exercise which relates to the identification of a cell value and, in turn setting a slicer. This improves the end user experience for excel reporting books.</p>
<p>Viva Excel and black IT <span style="font-family:Wingdings;">J</span>. A little cheeky!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/545/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/545/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=545&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/01/25/pivot-filtering-with-cell-selection-and-vba/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/012513_0330_pivotfilter1.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/012513_0330_pivotfilter2.png" medium="image" />
	</item>
		<item>
		<title>A Different Approach to Self-Service?</title>
		<link>http://paultebraak.wordpress.com/2013/01/18/a-different-approach-to-self-service/</link>
		<comments>http://paultebraak.wordpress.com/2013/01/18/a-different-approach-to-self-service/#comments</comments>
		<pubDate>Fri, 18 Jan 2013 01:27:39 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[Other Tools]]></category>
		<category><![CDATA[Jaspersoft]]></category>
		<category><![CDATA[Self-Service]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=541</guid>
		<description><![CDATA[Most of the business intelligence tools today focusing on self service delivery assume that the user or more appropriately report consumer is interested playing with data. They assume that the end user wants to conduct their own analysis and understand data, derive relationships and determine &#8217;cause and effect&#8217; patterns. I do not agree with this [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=541&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Most of the business intelligence tools today focusing on self service delivery assume that the user <em>or more appropriately report consumer</em> is interested playing with data.  They assume that the end user wants to conduct their own analysis and understand data, derive relationships and determine &#8217;cause and effect&#8217; patterns.  I do not agree with this assertion and am inclined to suggest that most users just simply want enough functionality to do their job with minimal effort.  The requirement for data manipulation and construction is a pretty easy side-bar for a developer like me to fall into because we tend to assume that everyone likes playing with data just as we do.
</p>
<p>At a recent <a href="http://www.boulderbibraintrust.org/index.php">BBBT</a> meeting on 11-Jan-2013, Jaspersoft showcased some of their new product and they have a very interesting approach to delivering Self-Service to consumers.  While they do use the words Self-Service (this is my interpretation), the offering meets the Self-Service definition because it places a large amount of power in the hands of the end user without requiring them to have technical skills.  After all, this is the nature of Self-Service.
</p>
<p>I have known of Jaspersoft by name for more than a few years now.  I&#8217;d be the first to admit, I had a very limited understanding of the product and it never really struck me as a stand out tool.  In-fact, I saw their offering as similar to most row set reporting tools providing row groupings, aggregation functions (auto subtotal, total line items) with specific formats at these levels, parameters, charting and other expected reporting functions.  Nothing really much new there &#8211; just another report writer and server.  This understanding may not be too much better now but some parts of their offering are novel and noteworthy.
</p>
<p>Jaspersoft&#8217;s approach seems different because their reports focus on giving the user the ability to manipulate the components that already exist in the report.  This is a nice feature to deliver for those who simply wish to use and manipulate existing reports (and the datasets in them).  Examples of this type of functionality include the ability to change chart types, apply filtering to datasets, sorting, conditional formatting and altering table layouts (by including, removing and rearranging columns).  All formatting objects of the report can change at the users will.
</p>
<p>This meets a rather large hole in the ability to deliver Self-Service to users.  Again, the target audience are people that do not want to write reports, or have reports that merely allow them to change parameters in an otherwise fixed report.  They just want to cherry pick components of reports that they&#8217;ve seen.  Of course, this is delivered via the browser.
</p>
<p>This is a much more powerful delivery of Self-Service and targets a much larger audience than tools that demand the user manage data as part of their daily process.
</p>
<p>
 </p>
<p>
 </p>
<p>
 </p>
<p>
 </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/541/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/541/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=541&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/01/18/a-different-approach-to-self-service/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>
	</item>
		<item>
		<title>Managing Connections In Power Pivot</title>
		<link>http://paultebraak.wordpress.com/2013/01/15/managing-connections-in-power-pivot/</link>
		<comments>http://paultebraak.wordpress.com/2013/01/15/managing-connections-in-power-pivot/#comments</comments>
		<pubDate>Tue, 15 Jan 2013 04:13:38 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[BISM]]></category>
		<category><![CDATA[DAX]]></category>
		<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[Connection]]></category>
		<category><![CDATA[Power Pivot]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=539</guid>
		<description><![CDATA[Demonstrations that show importing data into Power Pivot do this from database icon in the home window (as identified below). However, once data is in your model and you wish to add new tables it is wiser to reuse the existing connection rather than create a new connection for each import. Each time that table(s) [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=539&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Demonstrations that show importing data into Power Pivot do this from database icon in the home window (as identified below).  However, once data is in your model and you wish to add new tables it is wiser to reuse the existing connection rather than create a new connection for each import.  Each time that table(s) are added by this dialogue, a new connection is created within the model with multiple connections possible referring to the same source.  For model simplicity, it is better to have a single connection referring to a single data source.
</p>
<p><strong>Standards for Import<br />
</strong></p>
<p>The standard method importing data into Power Pivot is to use the import from database icon as shown in the diagram below (when a database is being used).  This utility has features that allow you to detect relationships between tables and may suffice from two models.  That is, when there are no existing tables and the model.
</p>
<p><img src="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon1.png?w=595" alt="" />
	</p>
<p>What this utility does is create a new connection to the data source each time the Wizard is invoked.  Consider for example, an existing model that has the product table from Adventure Works imported.  The initial import did not include the ProductCategory and ProductSubCateogory table.  Naturally, we would want to include this in the model.
</p>
<p>If we use this Wizard to reimport the tables, a new connection is set up.  This connection is associated with the two new tables.  We can see this by selecting the &#8220;Existing Connections&#8221; icon in the design.
</p>
<p><img src="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon2.png?w=595" alt="" />
	</p>
<p>Note that there are two connections in the model (as below) which was caused by the &#8220;re-import&#8221;of data once the initial population of the model had occurred.
</p>
<p><img src="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon3.png?w=595" alt="" />
	</p>
<p><strong>Altering an Existing Connection<br />
</strong></p>
<p>We can add data to the existing model and reuse an existing connection at the same time.  If we wish to do this you simply reopen the existing connections properties and append tables (or add a query).  Click the &#8216;Open&#8217; button from the dialogue and select either the &#8216;Select from a list of tables…&#8217; or &#8216;Write a query that will….&#8217;.
</p>
<div>
<table style="border-collapse:collapse;" border="0">
<col style="width:321px;" />
<col style="width:317px;" />
<tbody valign="top">
<tr>
<td style="padding-left:7px;padding-right:7px;">
<p><img src="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon4.png?w=595" alt="" /></p>
</td>
<td vAlign="middle" style="padding-left:7px;padding-right:7px;">
<p><img src="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon5.png?w=595" alt="" /></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>
 </p>
<p>This will append any new tables to the model utilising existing connection.
</p>
<p>Perhaps the main reason for reusing the connection is that it keeps the model succinct and manageable.  Once a table has been imported through a connection the connection properties for that table cannot be changed without first deleting all the tables using the connection.  Naturally this would increase the amount of rework required to the model should consolidation of connections be required at a later stage.
</p>
<p>Finally, the connections are retained within the model even after all the tables using connection have been deleted.  The connection must manually be deleted from the &#8216;Existing Connections&#8217; dialogue.
</p>
<p>
 </p>
<p>
 </p>
<p>
 </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/539/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=539&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/01/15/managing-connections-in-power-pivot/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon1.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon2.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon3.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon4.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/011513_0413_managingcon5.png" medium="image" />
	</item>
		<item>
		<title>SQL SAT Brisbane 2013</title>
		<link>http://paultebraak.wordpress.com/2013/01/10/sql-sat-brisbane-2013/</link>
		<comments>http://paultebraak.wordpress.com/2013/01/10/sql-sat-brisbane-2013/#comments</comments>
		<pubDate>Thu, 10 Jan 2013 05:32:09 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[PASS]]></category>
		<category><![CDATA[SQL Saturday]]></category>
		<category><![CDATA[Training]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=526</guid>
		<description><![CDATA[Just a short note to advise that SQL Saturday will be held in Brisbane on 27th April 2013 at the Microsoft offices in George St.  For those that don’t know, these are free community training days and are hugely successful (yes that’s free to attend and you even get lunch, prize draws etc).  The last [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=526&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Just a short note to advise that SQL Saturday will be held in Brisbane on 27<sup>th</sup> April 2013 at the Microsoft offices in George St.</p>
<p> For those that don’t know, these are free community training days and are hugely successful (yes that’s free to attend and you even get lunch, prize draws etc).  The last one we had in April 2012 was a huge success.</p>
<p> The space at Microsoft is limited so in order to avoid disappointment, register your attendance as soon as possible.</p>
<p> Checkout the site at <a href="http://www.sqlsaturday.com/210/eventhome.aspx">http://www.sqlsaturday.com/210/eventhome.aspx</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/526/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/526/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=526&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/01/10/sql-sat-brisbane-2013/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>
	</item>
		<item>
		<title>OLAP Rigidity wins against Tabular?</title>
		<link>http://paultebraak.wordpress.com/2013/01/07/olap-rigidity-wins-against-tabular/</link>
		<comments>http://paultebraak.wordpress.com/2013/01/07/olap-rigidity-wins-against-tabular/#comments</comments>
		<pubDate>Mon, 07 Jan 2013 06:40:26 +0000</pubDate>
		<dc:creator>Paul te Braak</dc:creator>
				<category><![CDATA[BISM]]></category>
		<category><![CDATA[DAX]]></category>
		<category><![CDATA[MDX]]></category>
		<category><![CDATA[PowerPivot]]></category>
		<category><![CDATA[SSAS]]></category>
		<category><![CDATA[Engine Choice; SSAS]]></category>
		<category><![CDATA[Tabular]]></category>

		<guid isPermaLink="false">http://paultebraak.wordpress.com/?p=519</guid>
		<description><![CDATA[There are many reasons why you might choose a Tabular Model over Multidimensional one. Marco Russo discusses some of the pros of tabular in his blog here which general relate to the flexibility that the tabular model gives you. However, one reason surprising reason for choosing multidimensional may be its rigid dimensional structure and the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=519&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There are many reasons why you might choose a Tabular Model over Multidimensional one.  Marco Russo discusses some of the pros of tabular in his blog <a href="http://sqlblog.com/blogs/marco_russo/archive/2012/03/01/why-to-use-tabular-in-analysis-services-2012-ssas.aspx">here</a> which general relate to the flexibility that the tabular model gives you.  However, one reason surprising reason for choosing multidimensional may be its rigid dimensional structure and the certainty that this structure gives in changing data environments.
</p>
<p>A Multidimensional dimension provides many ways to record information against an attribute.  Most importantly these are the attributes KEY, NAME and VALUE which are set under the dimension source properties.  For example we can see the [State-Province] attribute from the Geography dimension in Adventure Works as below.  The Key is the only property that must be set for an attribute so if no name is specified, the key will automatically be applied as the name.
</p>
<p><img src="http://paultebraak.files.wordpress.com/2013/01/010713_0640_olaprigidit1.png?w=595" alt="" />
	</p>
<p>Note that in the tabular engine, there is no concept of the KEY or Name.  These are not specified as native DAX refers to column value(s).
</p>
<p><span style="text-decoration:underline;"><strong>Referring to Attribute Members<br />
</strong></span></p>
<p>When an MDX query refers to members of the attribute it can do so by using the member name or the members unique name.  Thus, the two MDX statements are equivalent;
</p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:green;">&#8211; query using members unique name</span><br />
		</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select</span><br />
		</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Measures].[Internet Sales Amount] <span style="color:blue;">on</span> 0,<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Product].[Product Categories].[Category].&amp;[4] <span style="color:blue;">on</span> 1<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from</span> [Direct Sales]<br />
</span></p>
<p>
 </p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:green;">&#8211; query using members name</span><br />
		</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">select</span><br />
		</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Measures].[Internet Sales Amount] <span style="color:blue;">on</span> 0,<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;">[Product].[Product Categories].[Category].[Accessories] <span style="color:blue;">on</span> 1<br />
</span></p>
<p><span style="font-family:Consolas;font-size:9pt;"><span style="color:blue;">from</span> [Direct Sales]<br />
</span></p>
<p>
 </p>
<p>There are many reasons why you would choose the first query over the second, namely, the second can give unexpected values when there is more than one member with the name being sought.  That is, if there were two product categories (with different keys) <em>and </em>the same name (as Accessories), then the query would return only the first member.  <strong><em>One might expect that the query would aggregate the results but this does not occur.<br />
</em></strong></p>
<p>Once the query has been written, the members unique name is confusing and many people complain that it lacks reference to the underlying data (after all its impossible to know what does .&amp;[4] means anyway).  However, it is still the best way to refer to a member and this is the way most client tools generate MDX (using the unique_member_name).
</p>
<p>Note that since the tabular engine has no concept of a key for an attribute (you don&#8217;t uniquely specify the key or name for an attribute) the MDX equivalent passed to the tabular engine uses what we would otherwise consider the name as the key.   Thus, as in the example above, the tabular equivalent for this member is <span style="font-family:Consolas;font-size:9pt;">[Product].[Category].[Category].&amp;[Accessories].  </span>To an OLAP (multidimensional) developer, this type of key (ie the name as the key) is generally considered a real NO NO and contravenes best practice.
</p>
<p>
 </p>
<p><span style="text-decoration:underline;"><strong>Client Queries </strong></span>and the interesting stuff.<span style="text-decoration:underline;"><strong><br />
			</strong></span></p>
<p>For tabular models, the unique name for a member is generated by the name.  Furthermore, most client tools refer to the key in their script.  <em>I have even seen some tools hard code the published member for parameters.  </em>So, what happens when the underlying attribute name changes?  The change could break your report.
</p>
<p>We can easily demonstrate how this error would occur using Excel as a client.  Suppose I have a pivot based on a multidimensional cube and I convert the simple pivot to formulas (as below).  The Accessories member in Cell A2 is hardcoded (the formula is in D2 and uses the key [4] <em>as above</em>).  If the name of this member changes, the spread sheet still works fine, and the new name is displayed.
</p>
<p><img src="http://paultebraak.files.wordpress.com/2013/01/010713_0640_olaprigidit2.png?w=595" alt="" />
	</p>
<p>However, for the tabular example (as below), when the hardcoded name is changed, the MDX returns a #N/A error for the CUBEMEMBER function.
</p>
<p>In the second picture, the name of the member has changed to [Accessories &amp; Other] however the &#8216;report&#8217; still relies on the hard coded value .&amp;[Accessories] and the error occurs.
</p>
<p><img src="http://paultebraak.files.wordpress.com/2013/01/010713_0640_olaprigidit3.png?w=595" alt="" />
	</p>
<p><img src="http://paultebraak.files.wordpress.com/2013/01/010713_0640_olaprigidit4.png?w=595" alt="" />
	</p>
<p><span style="text-decoration:underline;"><strong>Conclusion</strong></span>
	</p>
<p>The use of a &#8216;key&#8217; for each member would offer a way to solve the problem as addressed above and this is only available in multidimensional dimensions.  To be fair though, the problem is as much a function of design as it is of structure.  A multidimensional dimension would still raise the issue if the attributes name had been used as a key (but no-one does that do they?).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/paultebraak.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/paultebraak.wordpress.com/519/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=paultebraak.wordpress.com&#038;blog=21358579&#038;post=519&#038;subd=paultebraak&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://paultebraak.wordpress.com/2013/01/07/olap-rigidity-wins-against-tabular/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/3315127f61225b3ff0ec28cb45b825d6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paultebraak</media:title>
		</media:content>

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/010713_0640_olaprigidit1.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/010713_0640_olaprigidit2.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/010713_0640_olaprigidit3.png" medium="image" />

		<media:content url="http://paultebraak.files.wordpress.com/2013/01/010713_0640_olaprigidit4.png" medium="image" />
	</item>
	</channel>
</rss>
