<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DkQGQXc5fip7ImA9WxBbEE4.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472</id><updated>2010-03-08T18:45:20.926+11:00</updated><title>Boyan Penev on Microsoft BI</title><subtitle type="html">A practical blog about Microsoft BI tools, techniques and practices written by a developer for other fellow developers.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.bp-msbi.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>47</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/bp-msbi" /><feedburner:info uri="bp-msbi" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by/2.5/" /><entry gd:etag="W/&quot;C0cFRng9fSp7ImA9WxBUEEU.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-3520176685791656719</id><published>2010-02-24T13:20:00.001+11:00</published><updated>2010-02-25T17:56:57.665+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-25T17:56:57.665+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SQL Server 2008" /><category scheme="http://www.blogger.com/atom/ns#" term="MCTS" /><category scheme="http://www.blogger.com/atom/ns#" term="MCP" /><category scheme="http://www.blogger.com/atom/ns#" term="certification" /><category scheme="http://www.blogger.com/atom/ns#" term="MCITP" /><title>Obtaining Microsoft BI Certification</title><content type="html">I&amp;nbsp;have been a little busy recently with getting certified with Microsoft. I am quite happy to announce I have passed both 70-448 and 70-452 exams in the last couple of weeks without reading a single page of preparation material. Now I am MCP, MCTS and MCITP in SQL Server 2008 BI.&lt;br /&gt;
&lt;br /&gt;
I have always wondered how important and relevant these certificates are. The common opinion around the industry professionals seems to be that experience is what really counts and certifications are for people without experience who are trying to get into the profession. I did it the other way and I am not sorry the least bit for it. An overview of my experience in regards to the two certifications:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;MCTS: Microsoft SQL Server 2008, Business Intelligence Development and Maintenance&lt;/strong&gt;&lt;br /&gt;
Exam: 70-448 Microsoft SQL Server 2008, Business Intelligence Development and Maintenance&lt;br /&gt;
&lt;br /&gt;
I passed this one with 857 (out of 1000). Since it was my first attempt at certification I did go through a few sample questions from a prep book based on MeasureUp, and a friend also flicked my way some really poor quality Braindumps, which contained some quite poor terminology and a fair bit of nonsense. On the MeasureUp tests I scored between 65-85%, so I decided to get a Free Second Shot voucher from Prometric and just go with no further preparation. As expected, my Data Mining skills did not quite cover the expectations and I had a few glitches around SSIS maintenance, but as expected I got more than 90% on all the development components and around 80% on all the administration/maintenance ones. After all I am a developer and I am not that experienced with administering BI solutions. So in general, my impression was that the test can be passed without much preparation from fairly inexperienced developers, who read some preparation materials.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;MCITP: Business Intelligence Developer 2008&lt;/strong&gt;&lt;br /&gt;
Exam: 70-452 PRO Designing a Business Intelligence Infrastructure Using Microsoft SQL Server 2008&lt;br /&gt;
&lt;br /&gt;
This one was harder, but I passed it with 92% with doing one sample test of 30ish questions before the attempt. I had another Prometric Free Second Shot voucher, so I was not stressing if I would pass or fail. The test had double the amount of questions than the MCTS one and it took me a fir while to go through all of them. Again - Data Mining was my weakest part (less than 50% right), while I managed to score 100% on SSRS, SSAS and "Designing the BI Architecture" part. SSIS was almost perfect too. Now, if a fairly inexpreienced developer passes MCTS, this test will definitely cause a lot more headaches. The questions are much more practical and much higher degree of relevant experience would be required to pass (or much more reading).&lt;br /&gt;
&lt;br /&gt;
In general, both of the tests are not easy and I do believe that if one can pass them without preparation (from experience), he is quite prepared to tackle the design, implementation and administration of Microsoft BI solutions. The Free Second Shot vouchers are also great for eliminating stress to some degree. However, on the not-so-good side, the tests can be passed with no experience and because the questions do follow a certain pattern and do not allow for much freedom in choosing the correct answer (short answer ones could be better), I think that there is a moderate chance of inexperienced and not that knowledgeable people to study, pass and then immediately forget the subject matter.&lt;br /&gt;
&lt;br /&gt;
Still, I have no idea how much my career will benefit from these certifications, however I did get a few PDF certificates signed by Steven A. Ballmer to wave at sutiable occasions :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-3520176685791656719?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=iD4aG3yl-Nk:JKVOr1t6siA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=iD4aG3yl-Nk:JKVOr1t6siA:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=iD4aG3yl-Nk:JKVOr1t6siA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=iD4aG3yl-Nk:JKVOr1t6siA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=iD4aG3yl-Nk:JKVOr1t6siA:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/iD4aG3yl-Nk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/3520176685791656719/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=3520176685791656719" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/3520176685791656719?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/3520176685791656719?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/iD4aG3yl-Nk/obtaining-microsoft-bi-certification.html" title="Obtaining Microsoft BI Certification" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2010/02/obtaining-microsoft-bi-certification.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04BSXcyfip7ImA9WxBVEEk.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-345261281373794250</id><published>2010-02-13T17:18:00.001+11:00</published><updated>2010-02-13T17:19:18.996+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-13T17:19:18.996+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="self-service BI" /><category scheme="http://www.blogger.com/atom/ns#" term="PowerPivot" /><title>To PowerPivot or Not</title><content type="html">Just last week I attended a Microsoft presentation with a subject: “SQL Server 2008 R2 for Developers”. The presenter went through most of the new features in R2 and in SQL Server 2008 but the largest chunk of the presentation was dedicated to PowerPivot. Unsurprisingly, the 50+ developers in the room had not heard anything about it and did not seem very interested in what the presenter had so say and show. I was not surprised not because the feature is insignificant, but mostly because .NET developers are naturally not the best audience for database presentations, let alone for new BI functionality which is tightly coupled with Excel.&lt;br /&gt;
&lt;br /&gt;
However, my eyes and ears were wide open for what the Technology Specialist had to say and he did alright – showed us how we can use Web Slices from SSRS 2008 R2 as a data source for PowerPivot, how we can publish reports through Excel Services, sorting and filtering 101 million rows in less than a second, etc. It was quite impressive.&lt;br /&gt;
&lt;br /&gt;
After the presentation a senior developer approached me (since I am the BI go-to guy) and asked me, among other easy questions, the following: “Who will be using all this?” and “How will users upload 101 million rows spreadsheet to SharePoint?”&lt;br /&gt;
&lt;br /&gt;
Since I had no straight answer for him, I thought it might be a good idea to ask the Microsoft national technology specialist. The replies (not literal quotes) we got were:&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;“How will users upload 101 million rows spreadsheet to SharePoint?”&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;Because PowerPivot uses column compression, 101 million rows actually take between 10 and 15 Mb, so uploading them over a network connection to SharePoint is not a problem.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;“Who will be using all this?”&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;I understand that the potential use scenarios for PowerPivot are quite limited, but we (Microsoft) believe that there will be some cases where power-users will need and want this sort of functionality.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Fair enough. However, both of the answers were not convincing. The problems with them are:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;1. What happens when we have a large number (say 1-2 million) dimension values, and a large number of facts as a source for PowerPivot? Obviously, column compression will not work that well in this case, which could be quite common.&lt;br /&gt;
&lt;br /&gt;
2. If PowerPivot is mainly for power-users, how powerful do they need to be to take advantage of it? It seems like only a tiny subset of power-users with some expert Excel knowledge will be able to operate this new Excel functionality. I will be quite surprised to see users managing live feeds, analysis services sources, DAX, etc.&lt;br /&gt;
&lt;br /&gt;
3. If BI developers first have to build a PowerPivot environment for the end-users, this does not seem like self-service BI at all, and I would be reluctant to do that if I can achieve the same and more though Analysis Services.&lt;/blockquote&gt;What I liked and I think would be quite useful are the numerous improvements to Excel 2010 as a data analysis and report generation tool. The product seems quite improved and I believe that it will get adopted quickly by heavy Excel users. However, I am somewhat perplexed by the buzz around self-service BI and PowerPivot in particular. Especially since we (BI developers) still need to get some extra functionality implemented to make our and our users’ everyday experience smoother and easier.&lt;br /&gt;
&lt;br /&gt;
Please feel free to let me know if you have better answers to my questions. For the time being I consider myself instead of an opponent, an unconvinced and cautious observer of the recent developments in the BI space, and from this point of view self-service BI seems a bit overhyped. Hopefully it’s me – not the product, what needs refinement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-345261281373794250?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=H_77i3L-k4g:iBlB7S4JgWQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=H_77i3L-k4g:iBlB7S4JgWQ:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=H_77i3L-k4g:iBlB7S4JgWQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=H_77i3L-k4g:iBlB7S4JgWQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=H_77i3L-k4g:iBlB7S4JgWQ:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/H_77i3L-k4g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/345261281373794250/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=345261281373794250" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/345261281373794250?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/345261281373794250?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/H_77i3L-k4g/to-powerpivot-or-not.html" title="To PowerPivot or Not" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.bp-msbi.com/2010/02/to-powerpivot-or-not.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIGRng_fSp7ImA9WxBWE04.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-7174944128024803548</id><published>2010-02-05T12:25:00.002+11:00</published><updated>2010-02-05T12:32:07.645+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-05T12:32:07.645+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MDX" /><category scheme="http://www.blogger.com/atom/ns#" term="Analysis Services" /><title>All Member Properties - Name, Key and Level</title><content type="html">I just tried to find some more information about the All Member in SSAS dimension hierarchies and since it was not readily available, I had to experiment a bit, so I thought I may as well share my findings. For some these may be obvious, but for some they could as well be interesting.&lt;br /&gt;
&lt;br /&gt;
So in brief, I will explore the Name, Key and Level of an All member in a dimension hierarchy. The one of choice was the Customer dimension and Customer Geography hierarchy in Adventure Works. There is an All member, called All Customers. As expected, .PROPERTIES("MEMBER_NAME") gives us "All Customers":&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="color: #660000;"&gt;WITH&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;MEMBER [Measures].[test] AS&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].CurrentMember.PROPERTIES("MEMBER_NAME")&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Measures].[test]&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 0,&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].Members&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 1&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;FROM [Adventure Works]&lt;/span&gt;&lt;/blockquote&gt;The first row shows us: &lt;strong&gt;All Customers&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Now, let's see what its key is:&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="color: #660000;"&gt;WITH&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;MEMBER [Measures].[test] AS&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].CurrentMember.PROPERTIES("KEY")&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Measures].[test]&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 0,&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].Members&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 1&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;FROM [Adventure Works]&lt;/span&gt;&lt;/blockquote&gt;This gives us &lt;strong&gt;0&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
And its level:&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="color: #660000;"&gt;WITH&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;MEMBER [Measures].[test] AS&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].CurrentMember.Level.Name&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Measures].[test]&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 0,&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].Members&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 1&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;FROM [Adventure Works]&lt;/span&gt;&lt;/blockquote&gt;The result this time is: &lt;strong&gt;(All)&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
So far so good. Now let's try using these to get only the All member:&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="color: #660000;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].[All Customers]&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 0&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;FROM [Adventure Works]&lt;/span&gt;&lt;/blockquote&gt;This works. Now if we try the Key:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="color: #660000;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].&amp;amp;[0]&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 0&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;FROM [Adventure Works]&lt;/span&gt;&lt;/blockquote&gt;Interestingly, since the All member is a calculated member and has no physical key, if we try to use the one that SSAS gave us does not actually work - we get nothing on Axis 0.&lt;br /&gt;
&lt;br /&gt;
Using the level works:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="color: #660000;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].[(All)].Item(0)&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 0&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;FROM [Adventure Works]&lt;/span&gt;&lt;/blockquote&gt;Also, after experimenting a bit further:&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="color: #660000;"&gt;SELECT&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; [Customer].[Customer Geography].[All]&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;} ON 0&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;FROM [Adventure Works]&lt;/span&gt;&lt;/blockquote&gt;This query also works even though the All member name is [All Customers], not just [All]. However, Analysis Services does recognise [All].&lt;br /&gt;
&lt;br /&gt;
In summary, the most robust options for referencing the All member in a dimension hierarchy that I have found are:&lt;br /&gt;
&lt;br /&gt;
1. [Dimension].[Hierarchy].[(All)].Item(0)&lt;br /&gt;
2. [Dimension].[Hierarchy].[All]&lt;br /&gt;
&lt;br /&gt;
These will always work - regardless of the dimension and hierarchy names.&lt;br /&gt;
&lt;br /&gt;
Another option is using [Dimension].[Hierarchy].[&lt;actual name=""&gt;&lt;actual name=""&gt;] - e.g. [Customer].[Customer Hierarchy].[All Customers]&lt;br /&gt;
&lt;br /&gt;
And, one that &lt;strong&gt;does not work&lt;/strong&gt; - referencing through its alleged key: [Customer].[Customer Hierarchy].&lt;strong&gt;&amp;amp;[0]&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Please let me know if there are any better alternatives, or why it would give me a key of 0 for the All member and would not work when actually using this key.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-7174944128024803548?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=Z-pqnXN-AI8:9o0wveBZkjY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=Z-pqnXN-AI8:9o0wveBZkjY:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=Z-pqnXN-AI8:9o0wveBZkjY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=Z-pqnXN-AI8:9o0wveBZkjY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=Z-pqnXN-AI8:9o0wveBZkjY:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/Z-pqnXN-AI8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/7174944128024803548/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=7174944128024803548" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/7174944128024803548?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/7174944128024803548?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/Z-pqnXN-AI8/all-member-properties-name-key-and.html" title="All Member Properties - Name, Key and Level" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://www.bp-msbi.com/2010/02/all-member-properties-name-key-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIBR3Y5cCp7ImA9WxBWEEo.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-1310314756040549484</id><published>2010-02-02T11:29:00.000+11:00</published><updated>2010-02-02T11:29:16.828+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-02T11:29:16.828+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="seminar" /><category scheme="http://www.blogger.com/atom/ns#" term="PALO" /><category scheme="http://www.blogger.com/atom/ns#" term="open-source" /><title>An Open-Source Approach to Business Intelligence</title><content type="html">Since Microsoft &lt;a href="http://www.bp-msbi.com/2009/01/post-mortem-thoughts-on.html"&gt;discontinued PerfromacePoint Planning&lt;/a&gt;, it is slightly unclear what is their strategy in this field. I have made a few suggestions in the past, some of which: &lt;br /&gt;
&lt;br /&gt;
• Stored-Procedure write-back from Excel&lt;br /&gt;
• SSAS write-back from Excel&lt;br /&gt;
• Better support for dimensional and measure group write-back&lt;br /&gt;
&lt;br /&gt;
Whether, when and how these may get implemented is an open question. I firmly believe that we should continue learning from any possible source – including our competitors. This is why I am quite interested in any possibility to extend my knowledge in the BI space regardless of who is presenting the ideas and solutions.&lt;br /&gt;
&lt;br /&gt;
Being lucky as I am, I received an open invite to the PALO Australia Roadshow 2010, presented by a company I &lt;a href="http://www.bp-msbi.com/2009/09/new-bi-company.html"&gt;recently posted&lt;/a&gt; about – &lt;a href="http://www.nakeddata.com/"&gt;Naked Data&lt;/a&gt;. In a brief, what you can expect from PALO and the presentation is:&lt;br /&gt;
&lt;br /&gt;
• In-memory MOLAP&lt;br /&gt;
• Rule-based forecasting and planning&lt;br /&gt;
• Some sci-fi GPU parallel processing&lt;br /&gt;
• Integration with Excel (PALO formulas and Pivot tables)&lt;br /&gt;
• .NET API&lt;br /&gt;
&lt;span style="color: #274e13;"&gt;• &lt;/span&gt;&lt;span style="color: #274e13;"&gt;Free breakfast&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I will be there trying to get some ideas for my future forecasting and planning implementations. Seats are limited, so make sure you &lt;a href="http://paloaustralia.com/"&gt;register&lt;/a&gt; soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-1310314756040549484?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=5GdP21k3lSc:WTDypNx0dRk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=5GdP21k3lSc:WTDypNx0dRk:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=5GdP21k3lSc:WTDypNx0dRk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=5GdP21k3lSc:WTDypNx0dRk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=5GdP21k3lSc:WTDypNx0dRk:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/5GdP21k3lSc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/1310314756040549484/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=1310314756040549484" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/1310314756040549484?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/1310314756040549484?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/5GdP21k3lSc/open-source-approach-to-business.html" title="An Open-Source Approach to Business Intelligence" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2010/02/open-source-approach-to-business.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIBRHczeyp7ImA9WxBXFUk.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-8916029478092536315</id><published>2010-01-20T17:30:00.005+11:00</published><updated>2010-01-27T09:22:35.983+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-27T09:22:35.983+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MDX" /><category scheme="http://www.blogger.com/atom/ns#" term="aggregations" /><category scheme="http://www.blogger.com/atom/ns#" term="Analysis Services" /><title>Average Aggregation in Analysis Services</title><content type="html">In SSAS we do not have a measure Average aggregation type. We do have AverageOfChildren (or Average over time), however it is semi-additive and works only along a Time dimension. Fortunately, we have Sum and Count, and since Average = Sum / Count, we can build our own Average aggregation when we need one. &lt;br /&gt;
&lt;br /&gt;
To do that:&lt;br /&gt;
&lt;br /&gt;
1. Create a measure&amp;nbsp;using the Sum aggregation&amp;nbsp;type (which is also the default). In our example, let's call it Amount.&lt;br /&gt;
2. Create a Count of Non-Empty Values (or Count of Rows)&amp;nbsp;measure. In example - [Measure Count].&lt;br /&gt;
3. Create the actual calculation - [Measures].[Amount]/[Measures].[Measure Count]&lt;br /&gt;
&lt;br /&gt;
We can either create a calculated measure, which performs the MDX calculation above:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #660000;"&gt;CREATE MEMBER CURRENTCUBE.[Measures].[Average Amount]&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;AS&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;[Measures].[Amount]/[Measures].[Measure Count]&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;,NON_EMPTY_BEHAVIOR = {[Measures].[Measure Count]}&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;,VISIBLE=1;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
, or if we really do not need the Sum base measure, we can set it to be replaced by the calculation with a SCOPE statement:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #660000;"&gt;SCOPE([Measures].[Amount]);&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&amp;nbsp; This = [Measures].[Amount]/[Measures].[Measure Count];&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;NON_EMPTY_BEHAVIOR(This) = [Measures].[Measure Count];&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;END SCOPE;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BMa6MDrkUyA/S1aipZD-dxI/AAAAAAAACm8/V6XVZtr1zaE/s1600-h/avg_results.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" mt="true" src="http://4.bp.blogspot.com/_BMa6MDrkUyA/S1aipZD-dxI/AAAAAAAACm8/V6XVZtr1zaE/s400/avg_results.png" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Voila! We have created a measure simulating an Average aggregation type. Then, we can hide the Count helper measure and from user point of view there is no evidence of our effort.&lt;br /&gt;
&lt;br /&gt;
Since the count will never be 0, we do not have to say "If not 0, divide, else - do not" and the NON_EMPTY_BEHAVIOR query hint may in fact improve performance, since the calculation will not be performed when the Count measure is NULL (instead of resulting in NULL/NULL=NULL).&lt;br /&gt;
&lt;br /&gt;
Mosha has previously blogged about &lt;a href="http://sqlblog.com/blogs/mosha/archive/2007/03/06/averages-ratios-division-by-zero-and-non-empty-behavior.aspx"&gt;NON_EMPTY_BEHAVIOR and division by zero&lt;/a&gt; and I strongly recommend reading his post.&lt;br /&gt;
&lt;br /&gt;
Another important consideration, which depends on the business scenario is the type of the Count aggregate. It could be &lt;strong&gt;Count of rows&lt;/strong&gt; (Row Bound)&amp;nbsp;or &lt;strong&gt;Count of non-empty values&lt;/strong&gt; (Column Bound). The difference is whether we want to include or exclude the empty values from our aggregate. Either way, the described technique will work equally well.&lt;br /&gt;
&lt;br /&gt;
I realise that this is a well-known approach, but since it is hard to find the solution online I thought it may be interesting for some less-experienced developers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-8916029478092536315?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=68KDdKYryNg:zYVzJEfjl6g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=68KDdKYryNg:zYVzJEfjl6g:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=68KDdKYryNg:zYVzJEfjl6g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=68KDdKYryNg:zYVzJEfjl6g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=68KDdKYryNg:zYVzJEfjl6g:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/68KDdKYryNg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/8916029478092536315/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=8916029478092536315" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/8916029478092536315?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/8916029478092536315?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/68KDdKYryNg/average-aggregation-in-analysis.html" title="Average Aggregation in Analysis Services" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_BMa6MDrkUyA/S1aipZD-dxI/AAAAAAAACm8/V6XVZtr1zaE/s72-c/avg_results.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2010/01/average-aggregation-in-analysis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8GRHs5eyp7ImA9WxBXEE4.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-7603974723453729780</id><published>2010-01-11T09:01:00.008+11:00</published><updated>2010-01-21T12:53:45.523+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-21T12:53:45.523+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SQL Server 2008" /><category scheme="http://www.blogger.com/atom/ns#" term="Reporting Services" /><title>Reporting Services 2008 Layout Properties Glitch</title><content type="html">Today while working with a basic sample dashboard in SSRS I noticed that for some reason one of my subreports disappeared:&lt;br /&gt;
&lt;br /&gt;
&lt;div align="center" class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BMa6MDrkUyA/S0pMoIEmGCI/AAAAAAAACmk/tQqkdD2Twt4/s1600-h/broken_report_with_a_map.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://3.bp.blogspot.com/_BMa6MDrkUyA/S0pMoIEmGCI/AAAAAAAACmk/tQqkdD2Twt4/s400/broken_report_with_a_map.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;While it got rendered on its own in Report Manager, when I placed it within a subreport (with no other containers around it) it just refused to show up. One of the properties I tried was the Layout menu item on the subreport:&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BMa6MDrkUyA/S0pNbK5H5YI/AAAAAAAACms/rjfk8vaLGCs/s1600-h/layout_menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://4.bp.blogspot.com/_BMa6MDrkUyA/S0pNbK5H5YI/AAAAAAAACms/rjfk8vaLGCs/s400/layout_menu.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
To my surprise, selecting the "Bring To Front" option solved my problem:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BMa6MDrkUyA/S0pNqMCmmkI/AAAAAAAACm0/Vypm4agZtcg/s1600-h/working_report_with_a_map.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" ps="true" src="http://3.bp.blogspot.com/_BMa6MDrkUyA/S0pNqMCmmkI/AAAAAAAACm0/Vypm4agZtcg/s400/working_report_with_a_map.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
This one was also hard to understand since it rendered correctly in BIDS, leading me to think that there is something wrong with my browser or report server setup. It seems like report items can be sent behind the report background, which at a first glance seems like a confusing and redundant bit of functionality. I also unsucessfully tried to reproduce this in SQL 2005, so it must be a new "feature". Also, it happened without any action on my part - I did not edit any layout options prior to its disappearance.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: white; color: #660000;"&gt;&lt;strong&gt;EDIT (15/01/2010)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: white; color: #660000;"&gt;The issue appears only with a subreport containing a Map. Interestingly, the Map actions - I have a Go To URL on the states still work, but the actual image gets lost somehow.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #660000;"&gt;&lt;strong&gt;EDIT (21/01/2010)&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #660000;"&gt;Microsoft replied with the following:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #783f04;"&gt;&lt;em&gt;&lt;a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=524175"&gt;Posted by Microsoft on 20/01/2010 at 11:25 AM&lt;/a&gt;&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: #783f04;"&gt;&lt;em&gt;Thank you for reporting this issue. It only happens if the Map is the first report item on the Subreport and there are no Data Sets specified. You can work around this problem by placing the Map into a Rectangle report item.&lt;/em&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-7603974723453729780?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=JdIqbnSi9Hk:z0sZrSibFXk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=JdIqbnSi9Hk:z0sZrSibFXk:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=JdIqbnSi9Hk:z0sZrSibFXk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=JdIqbnSi9Hk:z0sZrSibFXk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=JdIqbnSi9Hk:z0sZrSibFXk:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/JdIqbnSi9Hk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/7603974723453729780/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=7603974723453729780" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/7603974723453729780?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/7603974723453729780?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/JdIqbnSi9Hk/reporting-services-2008-layout.html" title="Reporting Services 2008 Layout Properties Glitch" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_BMa6MDrkUyA/S0pMoIEmGCI/AAAAAAAACmk/tQqkdD2Twt4/s72-c/broken_report_with_a_map.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2010/01/reporting-services-2008-layout.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMFRnwzeyp7ImA9WxBRFkg.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-8320511913017355393</id><published>2010-01-05T12:03:00.000+11:00</published><updated>2010-01-05T12:03:37.283+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-05T12:03:37.283+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="OLAP Browser" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft Connect" /><title>OLAP Browser Feature on Connect</title><content type="html">As there has been a considerable stir around a few blogs (including mine)&amp;nbsp;lately&amp;nbsp;in regards to the lack of a good OLAP browser/client in the Microsoft BI space, I just created a feature suggestion on Microsoft Connect. Please support me with some more ideas about how Microsoft can fill this apparent gap in the current BI stack. The link is here:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=523128"&gt;https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=523128&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Other posts about this issue:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://richardlees.blogspot.com/2009/09/which-cube-browser-for-microsoft-olap.html"&gt;http://richardlees.blogspot.com/2009/09/which-cube-browser-for-microsoft-olap.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://richardlees.blogspot.com/2009/10/whats-preventing-excel-from-being.html"&gt;http://richardlees.blogspot.com/2009/10/whats-preventing-excel-from-being.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://cwebbbi.spaces.live.com/blog/cns!7B84B0F2C239489A!5100.entry"&gt;http://cwebbbi.spaces.live.com/blog/cns!7B84B0F2C239489A!5100.entry&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://sqlblog.com/blogs/marco_russo/archive/2010/01/05/microsoft-doesn-t-play-the-traditional-bi-client-game.aspx"&gt;http://sqlblog.com/blogs/marco_russo/archive/2010/01/05/microsoft-doesn-t-play-the-traditional-bi-client-game.aspx&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.bp-msbi.com/2009/09/on-search-for-perfect-olap-browser.html"&gt;http://www.bp-msbi.com/2009/09/on-search-for-perfect-olap-browser.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-8320511913017355393?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=tq6YOaQ8_k8:klIDJZSFevc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=tq6YOaQ8_k8:klIDJZSFevc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=tq6YOaQ8_k8:klIDJZSFevc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=tq6YOaQ8_k8:klIDJZSFevc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=tq6YOaQ8_k8:klIDJZSFevc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/tq6YOaQ8_k8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/8320511913017355393/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=8320511913017355393" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/8320511913017355393?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/8320511913017355393?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/tq6YOaQ8_k8/olap-browser-feature-on-connect.html" title="OLAP Browser Feature on Connect" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://www.bp-msbi.com/2010/01/olap-browser-feature-on-connect.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MMSX0ycCp7ImA9WxBSE0U.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-6242613443419463474</id><published>2009-12-21T19:34:00.004+11:00</published><updated>2009-12-21T20:58:08.398+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-21T20:58:08.398+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Christmas" /><title>Merry Christmas and Happy New Year</title><content type="html">I now have 40 articles on this blog, around 183 subscribers and approximately 1500-1600 visits a month. It’s been a very pleasant and rewarding casual occupation to write about the world of Microsoft Business Intelligence.&lt;br /&gt;
&lt;br /&gt;
As my professional commitment for the new year I can promise that I will continue writing about new and interesting things I find while playing with SQL Server and the other great products which Microsoft puts on the market. &lt;br /&gt;
&lt;br /&gt;
Also, recently I have started visiting the MSDN SQL Server forums and I will continue doing so in the next year. I would encourage everyone who reads this blog to start sharing their knowledge and helping new developers there – the technologies Microsoft offers are only as good as the people who implement them – us. Working together builds us as professionals and in the end makes our lives easier.&lt;br /&gt;
&lt;br /&gt;
Many thanks to Nick Barclay for encouraging me to start this blog at the first place. Also, a big THANK YOU to Paul Hales, who even though hard to convince to start writing himself, has taught me quite a few things over the last couple of years and has always been the fiercest Microsoft advocate imaginable.&lt;br /&gt;
&lt;br /&gt;
To Paul and Nick, to everyone who I have had the pleasure to work closely with (Tamzyn Bielecka, Mark Dasco, Maxim Yefremov, Sue Hourigan, Chris Mentor, Edmund Harvey and many others) and to all bloggers and readers – have a &lt;strong&gt;really MERRY&lt;/strong&gt; Christmas and a &lt;strong&gt;very HAPPY&lt;/strong&gt; New Year!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-6242613443419463474?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=ra3lfSi1Uew:zkUa0dehUUE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=ra3lfSi1Uew:zkUa0dehUUE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=ra3lfSi1Uew:zkUa0dehUUE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=ra3lfSi1Uew:zkUa0dehUUE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=ra3lfSi1Uew:zkUa0dehUUE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/ra3lfSi1Uew" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/6242613443419463474/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=6242613443419463474" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/6242613443419463474?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/6242613443419463474?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/ra3lfSi1Uew/merry-christmas-and-happy-new-year.html" title="Merry Christmas and Happy New Year" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/12/merry-christmas-and-happy-new-year.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEASHw_eCp7ImA9WxBTF00.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-4580447096350305361</id><published>2009-12-13T22:27:00.000+11:00</published><updated>2009-12-13T22:27:29.240+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-13T22:27:29.240+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="blog" /><title>Blog Maintenance</title><content type="html">This is just a note that I have moved this blog to a custom domain - &lt;a href="http://www.bp-msbi.com/"&gt;http://www.bp-msbi.com/&lt;/a&gt;. Also, I changed the Subscribe To link on the blog to point to my feedburner feed.&lt;br /&gt;
&lt;br /&gt;
Based on some research, this change should not affect any existing subscribers and links to the previous address, as blogspot will redirect the older version of the blog URL and its older feed. However, I would really urge you to change your feed settings to point to the feedburner address just in case.&lt;br /&gt;
&lt;br /&gt;
And to justify this little amount of trouble I am causing for eveyone - I quite like some other alternatives, like WordPress, and the longer I keep my blog as a subdomain on blogspot, the harder it becomes to move it out. Plus, I am a Microsoft advocate, especially when it comes to SQL Server, so I find it slightly more suitable to have a non-blogspot (read Google) URL for $10/yr extra.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-4580447096350305361?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=TdSzhd9blTs:ioeL9VDtOzw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=TdSzhd9blTs:ioeL9VDtOzw:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=TdSzhd9blTs:ioeL9VDtOzw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=TdSzhd9blTs:ioeL9VDtOzw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=TdSzhd9blTs:ioeL9VDtOzw:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/TdSzhd9blTs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/4580447096350305361/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=4580447096350305361" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/4580447096350305361?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/4580447096350305361?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/TdSzhd9blTs/blog-maintenance.html" title="Blog Maintenance" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/12/blog-maintenance.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIMQnc6cCp7ImA9WxBTFEU.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-7653060587004459049</id><published>2009-12-10T00:25:00.003+11:00</published><updated>2009-12-11T09:19:43.918+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-11T09:19:43.918+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XMLA" /><category scheme="http://www.blogger.com/atom/ns#" term="SSIS" /><category scheme="http://www.blogger.com/atom/ns#" term="Analysis Services" /><category scheme="http://www.blogger.com/atom/ns#" term="AMO" /><category scheme="http://www.blogger.com/atom/ns#" term="PowerShell" /><category scheme="http://www.blogger.com/atom/ns#" term="ascmd" /><title>7 Ways to Process Analysis Services Objects</title><content type="html">&lt;p&gt;Being asked a bit too often how we can process Analysis Services databases (or cubes and dimensions) here is a list of 7 different methods:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. Through the GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This one is obvious. We can do it through both SSMS and BIDS.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. XMLA Script&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;To generate the script we can use the hefty Script button in SSMS. Simply configuring the processing settings and then instead of clicking the all too usual OK, we can as well click on the little button in the top left corner of the Process window:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_BMa6MDrkUyA/Sx-lGQ_zr3I/AAAAAAAAClc/7Y5YhY8S7-s/s1600-h/xmla_script%5B4%5D.png"&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: block; FLOAT: none; MARGIN-LEFT: auto; BORDER-TOP: 0px; MARGIN-RIGHT: auto; BORDER-RIGHT: 0px" title="xmla_script" border="0" alt="xmla_script" src="http://lh3.ggpht.com/_BMa6MDrkUyA/Sx-lId0ir6I/AAAAAAAAClo/t_VHP9_R9uk/xmla_script_thumb%5B2%5D.png?imgmax=800" width="344" height="309" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Then, we can just execute the generated query.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. SSIS Analysis Services Processing Task&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This Control Flow task allows us to configure any settings and then add it to our ETL process. Quite handy.&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_BMa6MDrkUyA/Sx-lKDeuH9I/AAAAAAAACl0/xjayDyjEdTg/s1600-h/image%5B2%5D.png"&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: block; FLOAT: none; MARGIN-LEFT: auto; BORDER-TOP: 0px; MARGIN-RIGHT: auto; BORDER-RIGHT: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_BMa6MDrkUyA/Sx-lNOsG6GI/AAAAAAAACmA/a51MCq442xo/image_thumb.png?imgmax=800" width="242" height="130" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4. SQL Server Agent Job&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This one is really an automation of Method #2 – XMLA Script. We can encapsulate it into a job of SQL Server Analysis Services Command type:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_BMa6MDrkUyA/Sx-lRe2tl0I/AAAAAAAACmM/e0-z6YIRYvU/s1600-h/image%5B8%5D.png"&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: block; FLOAT: none; MARGIN-LEFT: auto; BORDER-TOP: 0px; MARGIN-RIGHT: auto; BORDER-RIGHT: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_BMa6MDrkUyA/Sx-lTTdMfrI/AAAAAAAACmY/L0wQxi_y4ZU/image_thumb%5B4%5D.png?imgmax=800" width="344" height="314" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5. .NET Code&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This allows us to process cubes as a part of an application. Nice if we want to let our users process our cubes on-demand. Of course, better left to application developers, but still a good trick to know. Especially if we want to seem all-knowing when it comes to databases of any type. To achieve this objective, we use AMO (Analysis Management Objects). An API can be found here:&lt;/p&gt;&lt;p&gt;&lt;a title="http://technet.microsoft.com/en-us/library/microsoft.analysisservices(SQL.90).aspx" href="http://technet.microsoft.com/en-us/library/microsoft.analysisservices(SQL.90).aspx"&gt;http://technet.microsoft.com/en-us/library/microsoft.analysisservices(SQL.90).aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;6. Command Line - ascmd&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The command line utility can do a lot – including processing SSAS objects. For a full readme you can go here:&lt;/p&gt;&lt;p&gt;&lt;a title="http://msdn.microsoft.com/en-us/library/ms365187.aspx" href="http://msdn.microsoft.com/en-us/library/ms365187.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms365187.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;7. Command Line - PowerShell&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This PowerShell script will perform a Full Process of Adventure Works DW 2008 on localhost:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:78%;"&gt;[Reflection.Assembly]::LoadWithPartialName("Microsoft.AnalysisServices")&lt;br /&gt;$servername=New-Object Microsoft.AnalysisServices.Server&lt;br /&gt;$servername.connect("localhost")&lt;br /&gt;$databasename=New-Object Microsoft.AnalysisServices.Database&lt;br /&gt;$databasename=$servername.Databases.GetByName("Adventure Works DW 2008")&lt;br /&gt;$databasename.Process("ProcessFull")&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Using AMO we can do any maintenance tasks through PowerShell, including an object process.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Probably not a fully exhaustive list, but I hope it helps with giving developers some options when it comes to this trivial and crucial part of the development and deployment process. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-7653060587004459049?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FK2RkB-aJeY:Qn_JIKoHwXE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FK2RkB-aJeY:Qn_JIKoHwXE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FK2RkB-aJeY:Qn_JIKoHwXE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=FK2RkB-aJeY:Qn_JIKoHwXE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FK2RkB-aJeY:Qn_JIKoHwXE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/FK2RkB-aJeY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/7653060587004459049/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=7653060587004459049" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/7653060587004459049?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/7653060587004459049?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/FK2RkB-aJeY/7-ways-to-process-analysis-services.html" title="7 Ways to Process Analysis Services Objects" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/12/7-ways-to-process-analysis-services.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMDQHY6eCp7ImA9WxBTEko.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-1402935596873077254</id><published>2009-12-08T14:23:00.004+11:00</published><updated>2009-12-08T22:07:51.810+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-08T22:07:51.810+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="version control" /><category scheme="http://www.blogger.com/atom/ns#" term="T-SQL" /><category scheme="http://www.blogger.com/atom/ns#" term="source control" /><title>SQL Server DBMS Top 1 Wish List</title><content type="html">As an addition to &lt;a href="http://prologika.com/CS/blogs/"&gt;Teo Lachev's Top 10 Wishlists &lt;/a&gt;(SSAS and SSRS), I would like to contribute only 1 item to a possible SQL Server DBMS wishlist:&lt;br /&gt;&lt;br /&gt;1. Source Control.&lt;br /&gt;&lt;br /&gt;Not SourceSafe source control, but rather an automated version out-of-the-box, not relying on developers to check in/out. Rather, it should track the changes to the code as they are made, and a full version history should be available directly in the DBMS. It should not be too hard. After all, there is a nice database available, which can store code with its version numbers just like anything else.&lt;br /&gt;&lt;br /&gt;This would make a lot of developers' lives a bit less frustrating.&lt;br /&gt;&lt;br /&gt;OK, a SQL code "beautifier" would also be nice, but it is not all that important...&lt;br /&gt;&lt;br /&gt;&lt;a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=518835"&gt;Vote on Connect&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-1402935596873077254?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=HANFnCN-byU:B6h2aIelYmE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=HANFnCN-byU:B6h2aIelYmE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=HANFnCN-byU:B6h2aIelYmE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=HANFnCN-byU:B6h2aIelYmE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=HANFnCN-byU:B6h2aIelYmE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/HANFnCN-byU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/1402935596873077254/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=1402935596873077254" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/1402935596873077254?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/1402935596873077254?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/HANFnCN-byU/sql-server-dbms-top-1-wish-list.html" title="SQL Server DBMS Top 1 Wish List" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/12/sql-server-dbms-top-1-wish-list.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4ESHkycCp7ImA9WxNaEkw.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-4196336593856484271</id><published>2009-11-26T16:21:00.005+11:00</published><updated>2009-11-26T16:55:09.798+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-26T16:55:09.798+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MDX" /><category scheme="http://www.blogger.com/atom/ns#" term="Analysis Services" /><title>Filtering measures by indirectly related dimensions in MDX</title><content type="html">I have lately started visiting the SQL Server MSDN Forums and trying to answer some questions about Analysis Services and Reporting Services. One of the questions about MDX queries seems to get repeated quite often and I will try to address it in this post, so hopefully more people will get to read this rather than ask about it on MSDN.&lt;br /&gt;&lt;br /&gt;The actual question takes the form of:&lt;br /&gt;&lt;em&gt;"I have Dimension A and Dimension B, related to Measure 1. Dimension B is also related to Measure 2. How can I (is it possible to) get the values for Measure 1 filtered/sliced by Dimension A. I know it is easy to achieve with a join in SQL, but I do not know how to do it with MDX. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;This suggest the following dimension model:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 323px; DISPLAY: block; HEIGHT: 143px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5408278588001966162" border="0" alt="" src="http://2.bp.blogspot.com/_BMa6MDrkUyA/Sw4QuLQ1WFI/AAAAAAAAClM/hBKmUq3eod8/s400/dim-measure-ref.png" /&gt;&lt;br /&gt;&lt;br /&gt;One solution would be creating a many-to-many relationship between Dimension A and Measure Group 2. However, we may want to avoid that for some reason and answer the problem with a query.&lt;br /&gt;&lt;br /&gt;We can achieve the desired result in a number of ways but I will discuss the one using NONEMPTY. Others would be using FILTER and EXISTS.&lt;br /&gt;&lt;br /&gt;A sample script is:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;color:#663300;"&gt;SELECT&lt;br /&gt;{&lt;br /&gt; [Measures].[Measure 2]&lt;br /&gt;} ON 0,&lt;br /&gt;NON EMPTY&lt;br /&gt;{&lt;br /&gt; NONEMPTY( [Dimension B].[Dimension B Hierarchy].Members,&lt;br /&gt;           ([Measures].[Measure 1], [Dimension A].[Dimension A Hierarchy].&amp;amp;[Member_Key]))&lt;br /&gt;} ON 1&lt;br /&gt;FROM [Cube]&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;What this script does:&lt;br /&gt;&lt;br /&gt;1. Gets all Dimension B members, which have associated cells for Measure 1 and the specific Dimension A member (which we are filtering/slicing by)&lt;br /&gt;2. Gets the Measure 2 cells for the set of members retrieved in Step 1&lt;br /&gt;3. Removes members from Step 1, for which cells from Step 2 are empty&lt;br /&gt;&lt;br /&gt;An AdventureWorks example is:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color:#663300;"&gt;SELECT&lt;br /&gt;{&lt;br /&gt; [Measures].[Internet Order Count]&lt;br /&gt;} ON 0,&lt;br /&gt;NON EMPTY&lt;br /&gt;{&lt;br /&gt; NONEMPTY( [Product].[Product].Members,&lt;br /&gt;([Measures].[Reseller Order Count], [Reseller].[Reseller].&amp;amp;[238]))&lt;br /&gt;} ON 1&lt;br /&gt;FROM [Adventure Works]&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-4196336593856484271?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=yXHVE3JkTrc:VKPMyqXcP4w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=yXHVE3JkTrc:VKPMyqXcP4w:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=yXHVE3JkTrc:VKPMyqXcP4w:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=yXHVE3JkTrc:VKPMyqXcP4w:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=yXHVE3JkTrc:VKPMyqXcP4w:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/yXHVE3JkTrc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/4196336593856484271/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=4196336593856484271" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/4196336593856484271?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/4196336593856484271?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/yXHVE3JkTrc/filtering-measures-by-indirectly.html" title="Filtering measures by indirectly related dimensions in MDX" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_BMa6MDrkUyA/Sw4QuLQ1WFI/AAAAAAAAClM/hBKmUq3eod8/s72-c/dim-measure-ref.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/11/filtering-measures-by-indirectly.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EMQnk4eip7ImA9WxNVF00.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-6974424801336236931</id><published>2009-10-27T13:28:00.006+11:00</published><updated>2009-10-28T17:01:23.732+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-28T17:01:23.732+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NON_EMPTY_BEHAVIOR" /><category scheme="http://www.blogger.com/atom/ns#" term="MDX" /><category scheme="http://www.blogger.com/atom/ns#" term="formatting" /><category scheme="http://www.blogger.com/atom/ns#" term="FORMAT_STRING" /><category scheme="http://www.blogger.com/atom/ns#" term="truncation" /><title>Problems with FORMAT_STRING, VBA functions and NON_EMPTY_BEHAVIOR</title><content type="html">&lt;p&gt;Consider the following requirement: &lt;em&gt;"We want our measure to be truncated to 4 decimal places without any trailing 0s after the decimal point and a comma as a thousands separator."&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;First, let's focus on the truncation part. If we want that to happen for a measure, we can do it through the following formula, as I have described previously:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;font-size:85%;color:#000066;"&gt;SCOPE([Measures].[Our Measure]);&lt;br /&gt;This = Fix([Measures].[Our Measure]*10^4)/10^4;&lt;br /&gt;END SCOPE;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;This takes care of our truncation. So far so good.&lt;br /&gt;&lt;br /&gt;Now let's have a look at the formatting. If we want to apply custom formatting through FORMAT_STRING for a number such as 12345.1234, which states: "#,0.####", in order to obtain 12,345.1234 we run into a problem. The same FORMAT_STRING expression applied to 12345 gives us 12,345. - including a trailing decimal point (in our case a trailing period). There is no way to get rid of it through FORMAT_STRING. Even in the specifications for FORMAT_STRING it is pointed out that:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;If the format expression contains only number sign (#) characters to the left of the period (.), numbers smaller than 1 start with a decimal separator.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;This holds true for #s to the right of the period, as well.&lt;br /&gt;&lt;br /&gt;What we can do in this case is either conditionally format the number, with some sort of a rule, which checks if the number is whole or not (I will aviod that), or we can use the VBA Format function like this:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;font-size:85%;color:#000066;"&gt;SCOPE([Measures].[Our Measure]);&lt;br /&gt;Format([Measures].[Our Measure], "#,0.####");&lt;br /&gt;END SCOPE;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;This yields the correct result, so in the end, we can do:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-size:85%;color:#000066;"&gt;SCOPE([Measures].[Our Measure]);&lt;br /&gt;This = Format(Fix([Measures].[Our Measure]*10^4)/10^4, "#,0.####");&lt;br /&gt;END SCOPE;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;That may be achieveing the result, but let's look at perfromance of a calculated measure utilising this approach. The first thing I noticed when I implemented this is the huge increase in query processing time and the large number of 0 valued cells. It turned out that the VBA functions in MDX do not skip empty (NULL) cells. If you try &lt;span style="color:#000066;"&gt;Fix(NULL)&lt;/span&gt;, you'll get 0. So, after Fix-ing our measure, we get 0s for every empty cell in our cube. The same is valid for Format.&lt;br /&gt;&lt;br /&gt;Next step was trying to find a way to skip these empties. I tried:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;font-size:85%;color:#000066;"&gt;SCOPE([Measures].[Our Measure]);&lt;br /&gt;This = Format(Fix([Measures].[Our Measure]*10^4)/10^4, "#,0.####");&lt;br /&gt;NON_EMPTY_BEHAVIOR(This) = [Measures].[Our Measure];&lt;br /&gt;END SCOPE;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;but it did not work. I still got the 0s in my result set. I suppose that it got ignored by SSAS. Because of this issue I decided to write an IIF statement like this:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;font-size:85%;color:#000066;"&gt;SCOPE([Measures].[Our Measure]);&lt;br /&gt;This = IIF([Measures].[Our Measure] = 0, NULL, Format(Fix([Measures].[Our Measure]*10^4)/10^4, "#,0.####"));&lt;br /&gt;END SCOPE;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;This also worked. However, now we have an IIF statement, which serves no purpose other than filtering our empty cells, because of the VBA functions' behavior. It would be interesting if there is any other way of implementing this, avoiding the problem. It would be nice if:&lt;/p&gt;&lt;blockquote&gt;&lt;span style="color:#660000;"&gt;1. VBA functions can skip empty cells&lt;br /&gt;2. FORMAT_STRING behaves just like Format&lt;br /&gt;3. NON_EMPTY_BEHAVIOR actually works with SCOPE (in queries)&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;Please comment if you have a solution for the problems above and let me know if you would like to see the above issues fixed (I am considering raising a feedback/recommendation issue on Connect).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-6974424801336236931?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=uOy77QBoOoo:AmOlSG9_apE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=uOy77QBoOoo:AmOlSG9_apE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=uOy77QBoOoo:AmOlSG9_apE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=uOy77QBoOoo:AmOlSG9_apE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=uOy77QBoOoo:AmOlSG9_apE:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/uOy77QBoOoo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/6974424801336236931/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=6974424801336236931" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/6974424801336236931?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/6974424801336236931?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/uOy77QBoOoo/problems-with-formatstring-vba.html" title="Problems with FORMAT_STRING, VBA functions and NON_EMPTY_BEHAVIOR" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/10/problems-with-formatstring-vba.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAGRns9fip7ImA9WxBTF00.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-5496449030817957611</id><published>2009-10-15T13:53:00.024+11:00</published><updated>2009-12-13T22:12:07.566+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-13T22:12:07.566+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Excel" /><category scheme="http://www.blogger.com/atom/ns#" term="Data Visualisation" /><category scheme="http://www.blogger.com/atom/ns#" term="Report Design" /><title>Data Mystification Techniques</title><content type="html">I am a fan of studies in Data Visualisation. It is a creative and dynamic field with a lot of room for experiment. I am considering report and dashboard design, and within this frame Data Visualisation, as a form of practical art. Well designed and built reports are critical for solution adoption and usability. However, in this post I will concentrate on exactly the opposite topic - intentionally mystifying reports, obscuring the data and making it hard, for the report consumers to reach informed conclusions. I will also show how we can make the data visualisations as misleading as possible. This post is not as abstract as one may think, as it draws its examples from a very real project, for which I had to build a report under heavy pressure.&lt;br /&gt;
&lt;br /&gt;
Initially, I was asked to build a report based on a small data set (~450 rows) stored in an Excel workbook. The data was perfectly suitable for building a Pivot Table on top of it, so I did so and then I decided to use the pivot table as a source for my report. The users have one measure - Spending Amount and a few dimensions - Category and Focus for that spending. The request came in the form: "&lt;em&gt;We want to see the Amount by Category and Focus in both graphical and numeric form&lt;/em&gt;". So, I sat down and produced this prototype (with their colour theme): &lt;br /&gt;
&lt;div align="center"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5392654528356437330" src="http://3.bp.blogspot.com/_BMa6MDrkUyA/StaOuNcWTVI/AAAAAAAACkM/8vaOVEqSObg/s400/Prototype+1.png" style="cursor: hand; display: block; height: 234px; margin: 0px auto 10px; text-align: center; width: 382px;" /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;As you can see from the screenshot, the report is fairly simple - the bar graphs on the top clearly show how the Amount is distributed per Category and Focus. Also, because of an explicit request, I build the bar graph on the second row to show category and focus amounts combined, and in order to clarify the whole picture, I added the table at the bottom of the report. The report works for &lt;a href="http://www.bp-msbi.com/2009/07/developing-reports-for-colour-blind.html"&gt;colour-blind people&lt;/a&gt; too, as the details for the Focus per Category Expenditure bar graph are shown directly below in the data table.&lt;br /&gt;
&lt;br /&gt;
I sent the report prototype for review, and the response was:&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;1. Remove the table.&lt;br /&gt;
2. Change the bar graphs to make them more "flat". Meaning: there is too much difference between the bars.&lt;br /&gt;
&lt;/em&gt;&lt;br /&gt;
The reasoning - it is "too obvious" that the data is unevenly distributed. As the report is supposed to be presented to higher level management, discrepancies in the amount allocation would "look bad" on the people who requested me to create the report at the first place.&lt;br /&gt;
&lt;br /&gt;
Adding more fake data got rejected, so I was advised to prepare a new prototype report with the new requirements. It follows: &lt;br /&gt;
&lt;/div&gt;&lt;div align="center"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5392654882467154130" src="http://3.bp.blogspot.com/_BMa6MDrkUyA/StaPC0m7CNI/AAAAAAAACkU/sJZclaDwqxI/s400/Prototype+2.png" style="cursor: hand; display: block; height: 280px; margin: 0px auto 10px; text-align: center; width: 381px;" /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Now, &lt;a href="http://www.perceptualedge.com/blog/"&gt;Stephen Few &lt;/a&gt;would spew if presented with such a report. I did everything I could to obscure the report - added 3D effects, presented the amount in 100% stacked graphs when absolutely not necessary and, of course, I had to add a Pie Chart. A 3D Pie Chart. The whole report is totally useless. It is impossible to deduct the actual numbers of the various category/focus amounts. Furthermore, the Pie Chart combines the focus and category and uses virtually indistinguishable colours for the different slices. The 3D effect distorts the proportions of these slices and if printed in Black and White, or if viewed by a colour-blind person, the report looks like this:&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5392655249648624178" src="http://4.bp.blogspot.com/_BMa6MDrkUyA/StaPYMdzojI/AAAAAAAACkc/pJJQip3YbJI/s400/Prototype+2+BW.png" style="cursor: hand; display: block; height: 273px; margin: 0px auto 10px; text-align: center; width: 387px;" /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Since my goal of total mystification of the report was achieved, I sent the second prototype back.&lt;br /&gt;
The response was: "&lt;em&gt;It looks much better, and we really like the top right bar graph and the Pie Chart. Would it be possible to leave just those two and change the Pie Chart to show data broken down just by Category?&lt;/em&gt;”&lt;br /&gt;
&lt;br /&gt;
So, the users did not like my combined series. A point for them. Then I decided to remove the 3D cone graph, to remove all 3D effects, to make it more readable and to create the following 3rd prototype:&lt;br /&gt;
&lt;/div&gt;&lt;div align="center"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5392655570897771586" src="http://4.bp.blogspot.com/_BMa6MDrkUyA/StaPq5NknEI/AAAAAAAACkk/T3H3CRwyPGc/s400/Prototype+3.png" style="cursor: hand; display: block; height: 182px; margin: 0px auto 10px; text-align: center; width: 383px;" /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Here, we can see that the pie has the actual percentages displayed, and each category amount can be calculated from there. The stacked bar graph is again almost useless.&lt;br /&gt;
&lt;br /&gt;
The users liked it, but still thought that it was too revealing, and were particularly concerned with the fact that there are a couple of "invisible" categories (the ones with small percentages) on the Pie Chart. They had a new suggestion - change the pie chart back to a bar graph and play with the format, so that even the smallest amount is visible. I offered an option, made another prototype and it finally got approved. The exact words were: "&lt;em&gt;The graphs are exactly what we want&lt;/em&gt;". There it is: &lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5392655821378234626" src="http://3.bp.blogspot.com/_BMa6MDrkUyA/StaP5eUxKQI/AAAAAAAACks/eT_G6Aq7-9o/s400/Final+Report.png" style="cursor: hand; display: block; height: 146px; margin: 0px auto 10px; text-align: center; width: 379px;" /&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;The Y Axis in the first graph is interesting. Not only that there is a &lt;a href="http://www.informit.com/articles/article.aspx?p=374498"&gt;"scale break"&lt;/a&gt;, but in fact the scale is totally useless, as it is manually adjusted, because of the big gaps between the amounts. I needed two scale breaks, which for a series with 6 values is a bit too much. You can compare the normal linear scale of the first Prototype I created and this one. However, it hit the goal - my users were satisfied.&lt;br /&gt;
&lt;br /&gt;
I consider this effort to be contrary to be an exercise in &lt;strong&gt;"Data Mystification"&lt;/strong&gt;. It is very easy to draw the wrong conclusions from the report, and it achieves the opposite to the goals of Business Intelligence, as instead of empowering users, it could actually confuse them and lead them to making wrong decisions. &lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-5496449030817957611?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=M9z9K05ZTUg:39QxJBQKidc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=M9z9K05ZTUg:39QxJBQKidc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=M9z9K05ZTUg:39QxJBQKidc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=M9z9K05ZTUg:39QxJBQKidc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=M9z9K05ZTUg:39QxJBQKidc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/M9z9K05ZTUg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/5496449030817957611/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=5496449030817957611" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/5496449030817957611?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/5496449030817957611?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/M9z9K05ZTUg/data-mystification-for-business.html" title="Data Mystification Techniques" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_BMa6MDrkUyA/StaOuNcWTVI/AAAAAAAACkM/8vaOVEqSObg/s72-c/Prototype+1.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/10/data-mystification-for-business.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAMQH0yfyp7ImA9WxBWE08.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-509057370778541426</id><published>2009-09-22T13:09:00.010+10:00</published><updated>2010-02-05T11:13:01.397+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-05T11:13:01.397+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PALO" /><category scheme="http://www.blogger.com/atom/ns#" term="Naked Data" /><category scheme="http://www.blogger.com/atom/ns#" term="open-source" /><title>A new BI company</title><content type="html">Just a quick one - recently I learned that three former colleagues of mine had formed a new BI company in Australia - &lt;a href="http://www.nakeddata.com/"&gt;Naked Data&lt;/a&gt;. What makes it slightly different is that it is based on an open-source platform; and what makes this venture interesting for me is the people who are involved. All of them are exceptional professionals and I believe that if anyone can make it it is them.&lt;br /&gt;
&lt;br /&gt;
I am curious!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-509057370778541426?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=vSGmcyxDvOE:BrgmEkVPSxs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=vSGmcyxDvOE:BrgmEkVPSxs:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=vSGmcyxDvOE:BrgmEkVPSxs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=vSGmcyxDvOE:BrgmEkVPSxs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=vSGmcyxDvOE:BrgmEkVPSxs:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/vSGmcyxDvOE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/509057370778541426/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=509057370778541426" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/509057370778541426?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/509057370778541426?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/vSGmcyxDvOE/new-bi-company.html" title="A new BI company" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/09/new-bi-company.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMHSXo9fyp7ImA9WxNWFUg.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-823772346861025214</id><published>2009-09-22T11:54:00.012+10:00</published><updated>2009-10-15T08:57:18.467+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-15T08:57:18.467+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Reporting Services" /><category scheme="http://www.blogger.com/atom/ns#" term="ProClarity" /><category scheme="http://www.blogger.com/atom/ns#" term="PerformancePoint" /><category scheme="http://www.blogger.com/atom/ns#" term="Panorama" /><category scheme="http://www.blogger.com/atom/ns#" term="OLAP Browser" /><category scheme="http://www.blogger.com/atom/ns#" term="BI Companion" /><category scheme="http://www.blogger.com/atom/ns#" term="ad-hoc reporting" /><category scheme="http://www.blogger.com/atom/ns#" term="Dundas" /><title>On the search for the perfect OLAP browser</title><content type="html">&lt;span style="font-family:arial;color:#000000;"&gt;Browsing Analysis Services cubes is &lt;em&gt;typically&lt;/em&gt; done by power users in SQL Server Management Studio or Excel. However, because of a requirement stating that intranet and non-intranet users need to be able to access and browse an OLAP cube I had to go out there and try to find the best OLAP browser on the market. The client had been using Dundas OLAP Services with mixed success, and had purchased PerformancePoint with ProClarity but never used it because of infrastructure issues. That is why they used Dundas as an interim solution. Dundas’s OLAP Services is a user-friendly tool, but tis performance is not ideal when it comes to large grids, so my client wanted something combining Dundas’s usability with Excel’s performance, which could be used both internally and externally.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;I contacted Microsoft with a question: “What tools can I use?” They came back to me with the following suggestions:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;IntelliMax Solutions OLAP Browser (an Australian partner)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;BI Companion&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Panorama&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Dundas&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;ProClarity&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:arial;color:#000000;"&gt;I added PerformancePoint to the list, as well as Radar-Soft’s OLAP Browser, so my final list was:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;IntelliMax&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;BI Companion&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Panorama&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Dundas&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;ProClarity&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;PerformancePoint&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Radar-Soft&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;IntelliMax Solutions&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;A sales guy told me that they will organise an online demo for me, and then if I am interested, they will organise an evaluation installation of their product on our servers. That just happened half an hour ago and it immediately became apparent that the product lack one critical piece of functionality - it does not support attribute hierarchies. So, I cannot use anything but user-defined custom hierarchies, because according to the support person, including attribute hierarchies make the grids and reports "too big". I, however, definitely need these big grids/reports. Otherwise, the tool is nice and simple with very obvious support for Custom Data - you can define this property from the UI, which makes it easier to work on non-Kerberos enabled environments. It also should integrate with PerformancePoint and Reporting Services, but I did not test those parts, because of the aforementioned problem with attribute hierarchies.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;BI Companion&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;They were very friendly and responsive. I got an evaluation install, tried it out and it worked fine, apart from a small bug with non-aggregatable dimension hierarchies, which they fixed immediately. I was quite impressed with the product. It seemed to perform slightly better than Dundas, but it also was slightly less user-friendly. The interface imitates Cube Browser and is very feature-rich. Unfortunately, the HTML version did not work with Firefox, so they suggested using a SilverLight version, which was not supported by my client. As one of my requirements was cross-browser operability (IE and Firefox at least), BI Companion became a no-go-to for me.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Panorama&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Panorama’s NovaView product competed with PerformancePoint as a dashboard creation tool and I have no idea why Microsoft recommended a competitor. I contacted their reseller in Australia and the sales person organised an online demo. I could play with their grid analytics components and it seemed OK. NovaView comes in two versions – a legacy Java version, as well as a new Flash version still in development. The Flash version is quite nice, but still harder to use than BI Companion or Dundas. As a big miss in the current version, Panorama NovaView does not let the user to add/remove dimension hierarchies from its grid columns. It can be done on rows, but not on columns, which is frustrating and ultimately a critical lack of functionality in my case. The Panorama support person told me that “they did not want to release all features yet” and that they have it going in their lab. He also advised me to use the Java version until the Flash version gets updated. I did and found out that the Java version is indeed fast, but not as fast as Excel and ProClarity. Furthermore, Panorama’s product is just too big for our needs and all of its administrative functionality, which includes user management, security and what-not, is just not necessary. Otherwise it looks nice.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Dundas&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;The Dundas OLAP Services OLAP grid is very usable – all the users need to do is drag and drop dimension hierarchies to browse the cubes they have access to. Unfortunately, it is a bit buggy and very slow when the cells, which need to be displayed, hit the &gt; 10 000 range. After performance testing, we found out that about 50-80% of the processing time takes place on the client machines, where the browser renders a huge HTML table. It turns out that it is not only Dundas which has the same issues. Any HTML OLAP tool I tested suffers from exactly the same problem. This includes Dundas, BI Companion and Radar-Soft. Nothing we can do. Dundas supports paging, so the results can be split in a number of pages. It performs better if that feature is turned on, but requires hacking when exporting to Excel, because in order to export the whole grid, by default the user needs to export all the pages individually and then manually concatenate them in Excel. Since the HTML table problem cannot be rectified by Dundas or us, Dundas’s OLAP Services remain what they were intended to be – an interim solution.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;ProClarity&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Dated, but FAST. ProClarity still beats all other solutions with its performance. It was as fast as Excel and much, much faster than anything else. Although it lacks the apparent user-friendliness of some of the other solutions, it does allow users to conveniently browse OLAP cubes. Furthermore, it integrates well with PerformancePoint. Unfortunately, 6.2 is its last ever version. Whether its functionality gets implemented as a part of SharePoint 2010 is still to be announced by Microsoft. By the current way things look, ProClarity is still the best solution for ad-hoc OLAP browsing. It is stable and even though its installation is not quite smooth (e.g. requires IIS to be running gin 32bit mode), it does offer what most users would feel comfortable with. Its drawbacks are: tabbed interface, no drag-drop, and outdated graphics. Not perfect, but good enough. Oh, and it works with Firefox.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;PerformancePoint&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;The Microsoft dashboarding tool offers an Analytics Grid part, which can be used for ad-hoc analysis. Unfortunately, it does not allow the users to add more dimension hierarchies on rows or columns. What is does well is drilling up or down the hierarchies and slicing by other hierarchies. Unfortunately this is hardly enough when it comes to full-featured ad-hoc reporting.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Radar-Soft&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;The small OLAP browser Radar-Soft is offering seems fast at a first glance. It would have been a nice small tool if it did not have one major problem – paging. It pages everything. It even creates a number of pages within cells. This improves performance but makes it impossible to use if we want to export a whole grid to Excel. I guess that some of the paging can be disabled, but I am quite sure that, since it is HTML, it will have the aforementioned issues with performance when it comes to displaying a relatively large HTML table.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Conclusion&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;The three HTML solutions - Radar-Soft, Dundas and BI Companion all had the same issue with performance. My guess is that there is no HTML solution which is faster, because in the end it comes to browser performance rather than MDX or .NET implementation.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;&lt;br /&gt;Panorama with its Java and Flash versions is maybe a good solution for a full-featured dashboarding and reporting, but is a massive overkill for our circumstances. Also, it is not very user-friendly and not very fast.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;PerformancePoint and ProClarity are my favourite and I believe that Microsoft’s offering provides the best capabilities for our users at least until something better comes from the Microsoft workshop. These integrate nicely with SharePoint and perform very well. While PerformancePoint is very user friendly, I would not say that for ProClarity. Hopefully in the future we will see nicer OLAP browsing by Microsoft based on these two tools.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;A word about SilverLight and Excel&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;While SilverLight OLAP browsers are available by various software houses (most notable BI Companion has one in Beta), it is a relatively new technology and was not an option for me as it was not in my client’s SOE. Also, from my testing it does not seem like it is much faster than HTML, but definitely looks nicer. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Excel is, in my opinion, the best tool for browsing OLAP cubes inside the organisation. It is fast, and provides a rich set of analytics capabilities. There are a lot of discussions about Excel as a report authoring tool on various blogs, but I believe that for ad-hoc reporting there is nothing out there which beats Excel. Despite this, I could not recommend it to my client, as the solution is exposed to external users and letting them connect to our cubes directly though Excel is just impossible considering our security infrastructure. Also, Excel Services does not provide enough ad-hoc functionality, as it does not allow users to modify the Pivot Tables.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Wishes&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000000;"&gt;I wish and hope that Microsoft releases a full-featured, user-friendly and performant OLAP browser as part of Visual Studio and .NET or as a part of SharePoint 2010. Such a tool is just a must and a serious miss in the Microsoft BI stack. The combination of Excel+PerformancePoint+ProClarity does the trick for now, but as ProClarity is getting discontinued, there must be something in the future toolset, which takes its place.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;color:#000000;"&gt;A few other bloggers wrote posts closely related to this topic:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;color:#000000;"&gt;Richard Lees - &lt;a href="http://richardlees.blogspot.com/2009/09/which-cube-browser-for-microsoft-olap.html"&gt;Which cube browser for Microsoft OLAP&lt;/a&gt;&lt;br /&gt;Richard Lees - &lt;a href="http://richardlees.blogspot.com/2009/10/whats-preventing-excel-from-being.html"&gt;What's preventing Excel from being the ubiquitous cube browser&lt;/a&gt;&lt;br /&gt;Chris Webb - &lt;a href="http://cwebbbi.spaces.live.com/blog/cns!7B84B0F2C239489A!5100.entry"&gt;Proclarity Migration Roadmap (or lack thereof)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-823772346861025214?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=jmkdZh7GuBY:z4H206Wbnxk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=jmkdZh7GuBY:z4H206Wbnxk:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=jmkdZh7GuBY:z4H206Wbnxk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=jmkdZh7GuBY:z4H206Wbnxk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=jmkdZh7GuBY:z4H206Wbnxk:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/jmkdZh7GuBY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/823772346861025214/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=823772346861025214" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/823772346861025214?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/823772346861025214?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/jmkdZh7GuBY/on-search-for-perfect-olap-browser.html" title="On the search for the perfect OLAP browser" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">10</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/09/on-search-for-perfect-olap-browser.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQHRHY_cSp7ImA9WxNSFko.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-4549571422491387945</id><published>2009-08-30T10:07:00.004+10:00</published><updated>2009-08-31T09:18:55.849+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-31T09:18:55.849+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SSIS" /><category scheme="http://www.blogger.com/atom/ns#" term="inferred members" /><title>Inferred Members Implementation Best Practise</title><content type="html">&lt;p&gt;Just last week a colleague of mine and I did a very thorough research on the best implementation practises in regards to Inferred Members. We went through a few web sites and we also had a look at previous implementations through SSIS. There are quite a few resources on the subject and the best two methods we found were based on Project REAL and a SQL CAT recommendation. So, in the end we agreed that we can recommend three approaches, which have their advantages and disadvantages and could be all successfully used when we need to have Inferred Member (early arriving dimensions = late arriving facts) support in a solution.&lt;/p&gt;&lt;p&gt;Our findings can be summarised in the following table:&lt;/p&gt;&lt;table border="1" cellspacing="0" cellpadding="2" width="401"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="133"&gt;Method&lt;/td&gt;&lt;td valign="top" width="133"&gt;Pros&lt;/td&gt;&lt;td valign="top" width="133"&gt;Cons&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="133"&gt;Stored procedures&lt;/td&gt;&lt;td valign="top" width="133"&gt;&lt;p&gt;No need to use SSIS&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="133"&gt;&lt;p&gt;Slow&lt;/p&gt;&lt;p&gt;Complicated development&lt;/p&gt;&lt;p&gt;Need to link source and target data server instances.&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="133"&gt;Script Component (SSIS)&lt;/td&gt;&lt;td valign="top" width="133"&gt;&lt;p&gt;Fast&lt;/p&gt;&lt;p&gt;High reusability&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="133"&gt;&lt;p&gt;.NET skills required&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="133"&gt;Double Lookup (SSIS)&lt;/td&gt;&lt;td valign="top" width="133"&gt;&lt;p&gt;Fast&lt;/p&gt;&lt;p&gt;High reusability&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="133"&gt;&lt;p&gt;Performance issues with multiple dimensions&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;I will go through each of these methods and provide some more details about them.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. Stored Procedures&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If SSIS data flow tasks are not an option for our ETL we can implement inferred member support through SQL code. The basic idea behind this method is:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Find new dimension members in the fact data and add them to the dimension &lt;/li&gt;&lt;li&gt;Move the fact data from source to target (i.e. staging to datamart) with surrogate keys from the dimension table&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If we have our source and target data on separate instances of SQL Server it becomes quite inconvenient to utilise this approach. We need to link the two instances to use tables from both tables in the same stored procedure. This is a major issue and it is easily avoided by using SSIS. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. SQL Server Integration Services&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A general design of SSIS solutions can be represented with the following diagram:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_BMa6MDrkUyA/SpnCfI3cyxI/AAAAAAAACjk/2VmV6kGm8tA/s1600-h/Inferred%20Members%20Small%5B7%5D.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title="Inferred Members Small" border="0" alt="Inferred Members Small" src="http://lh6.ggpht.com/_BMa6MDrkUyA/SpnCiUPnBmI/AAAAAAAACjo/xiRaN7aewTg/Inferred%20Members%20Small_thumb%5B5%5D.png?imgmax=800" width="400" height="573" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;We can implement this in the following ways:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2.1. Script Component (Project REAL)&lt;/p&gt;&lt;p&gt;The Data Flow task for this approach is:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_BMa6MDrkUyA/SpnCkNC9wFI/AAAAAAAACjs/G33GtoHAnOw/s1600-h/image%5B12%5D.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_BMa6MDrkUyA/SpnCnqayAMI/AAAAAAAACjw/jT9mKF_vmYc/image_thumb%5B8%5D.png?imgmax=800" width="209" height="441" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;After looking up missing states, we pass them to a Script Component, which hashes the misses and hits the database only when a genuinely new miss occurs. We have a stored procedure in place which simply adds the new dim member in the dimension table in the database and returns the new surrogate key, which then gets sent to the fact table.&lt;/p&gt;&lt;p&gt;Using .NET we can efficiently hash all values in a object collection and we can also handle both character and numerical data.&lt;/p&gt;&lt;p&gt;Because we are using a fully cached lookup, this data flow item is case-sensitive, therefore we should make sure we equalise the case in both fact and reference table data before we compare the two. We should also make sure that in this case the Script Component is case-insensitive, because if it is we will end up with multiple different rows in our dimension table for each case variation of our inferred members.&lt;/p&gt;&lt;p&gt;Additionally, the Script Component task should be built either accepting a parameter for the dimension name, or it can read its name (in our implementation) and find the first word in it to determine the dimension it is used for. In the above diagram, the Script Component task is handling the State dimension, therefore its name starts with State – . This makes the implementation of multiple Script Components for multiple dimensions very easy – all we need to do is change its name and it just works. There can also be some .NET code for auditing purposes. This is also fairly easy to implement and an entry level of .NET should be sufficient for development and maintenance. A sample of this approach can be found in &lt;a href="http://www.microsoft.com/sqlserver/2005/en/us/project-real.aspx"&gt;Project REAL&lt;/a&gt; and it is thoroughly discussed in the SSIS paper produced with it.&lt;/p&gt;&lt;p&gt;2.2. Double Lookup (SQL CAT)&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_BMa6MDrkUyA/SpnCsNCJ41I/AAAAAAAACj0/onz8YH9psks/s1600-h/image%5B11%5D.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_BMa6MDrkUyA/SpnCwf5tRnI/AAAAAAAACj4/a-NsRVW1JFY/image_thumb%5B7%5D.png?imgmax=800" width="403" height="434" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Here, we are doing the same as before – matching fact rows against a State dimension. If a mismatch is found in the first (fully cached) lookup, we pass the row to the second one. The New StateSK is a partially cached lookup. Its purpose is similar to a hash table – it caches new rows, and when there is a brand new mismatch it adds it to the database by executing a stored procedure. Then we Union All our inferred members with the rest of the fact data.&lt;/p&gt;&lt;p&gt;Because the second lookup task is utilising partial lookup, it is case-insensitive and case variations of the same character term will not lead to multiple dimension rows for the same member. However the first fully-cached lookup is case-sensitive, so we should make sure that both source and reference data is in the same case because that would be more efficient. Furthermore, In SQL Server 2005 partial caching must have a specified memory limit and if we have a large number of early arriving dimension members, we may run out of memory for them. In that case SQL Server 2005 will start discarding the least used values from its cache, which may have performance implications. The latter problem is overcome in SQL Server 2008.&lt;/p&gt;&lt;p&gt;Another problem with this approach is the use of Union All tasks. These are semi-blocking and may impact performance when used multiple times in our ETL package.&lt;/p&gt;&lt;p&gt;For much more detailed description, including samples you can go to:&lt;/p&gt;&lt;p&gt;&lt;a href="http://sqlcat.com/msdnmirror/archive/2009/05/13/assigning-surrogate-keys-to-early-arriving-facts-using-integration-services.aspx"&gt;SQL CAT - Assigning surrogate keys to early arriving facts using Integration Services&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;From our testing and research we reached the conclusion that using Script Component is the best approach, closely followed by Double Lookups. The stored procedure approach is slow, hard to maintain and may be impossible to implement in a production environment. Using SSIS with .NET proves to be efficient, convenient and fast.If avoiding .NET is preferable, handling inferred members in SSIS is a very good alternative.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-4549571422491387945?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=-jDExv_Pilw:O0TBKF6Z9vY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=-jDExv_Pilw:O0TBKF6Z9vY:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=-jDExv_Pilw:O0TBKF6Z9vY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=-jDExv_Pilw:O0TBKF6Z9vY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=-jDExv_Pilw:O0TBKF6Z9vY:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/-jDExv_Pilw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/4549571422491387945/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=4549571422491387945" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/4549571422491387945?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/4549571422491387945?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/-jDExv_Pilw/inferred-members-implementation-best.html" title="Inferred Members Implementation Best Practise" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/08/inferred-members-implementation-best.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08CQng_eip7ImA9WxNSEEo.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-3328117671237054084</id><published>2009-08-24T12:03:00.005+10:00</published><updated>2009-08-24T12:11:03.642+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-24T12:11:03.642+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="non-technical" /><category scheme="http://www.blogger.com/atom/ns#" term="employment" /><category scheme="http://www.blogger.com/atom/ns#" term="off-topic" /><title>Trouble with Employment Agencies</title><content type="html">&lt;span style="font-family:arial;"&gt;I would normally not write about anything not Microsoft BI related, but in this case I will break my own rule because of an issue which concerns all developers who work on a contract for their employer.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Dealing with employment agents is something everyone dislikes because of their usually quite arrogant attitude. Since their job is to find us jobs and when we are independent contractors in some cases process our pay, I do not see a reason for their arrogance. We are purchasing services through them (paying them quite a lot for trivial tasks) and they should treat us with utmost respect. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;In a recent case, which made me write this, a colleague and a friend of mine, who is well respected in the Microsoft BI community was treated in a disrespectful manner by &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;&lt;span style="color:#660000;"&gt;Aurec&lt;/span&gt;&lt;/span&gt;. The case had to do with a clause in his contract stating that he cannot do work for his employer for 12 months after finishing his contract, unless he signs again through them. It is an usual BS clause, which would not pass through any court of justice in Australia because it limits our rights of free trade (or at least that's how I understand it). After his refusal to sign a restrictive contract, they refused to let him work for his employer. To make the matters worse, he had brought to them the contract at the first place and they had already strong-armed him (by threatening to increase their rates) into bringing his payroll to them too.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Since his employer had already given him the position through &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;span style="color:#660000;"&gt;Aurec&lt;/span&gt;&lt;/span&gt;, it would be unfair if he goes through another agent for the same position (as far as the employer is concerned), so they are in a position to dictate their own terms, regardless of the fact that he is the one who found the contract, got approved by the employer, and most importantly - would do the job.&lt;br /&gt;This whole matter enrages me as it prevents a really good expert from working for his chosen employer due to a profiteering agent, who should just shut up and do their insignificant bit in the whole matter.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;In conclusion, I know that there are other agents like this out there, and please speak up if you have had similar experiences because the community needs to weed out the bad seeds. And one more thing - based on the described situation, my personal advice to you is never to sign anything through &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Aurec&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;P.S. In case &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;&lt;span style="color:#660000;"&gt;Aurec&lt;/span&gt;&lt;/span&gt; are interested in accusing me of defamation, I can provide full evidence (emails) and a witness, proving that the above article truthfully represents their actions and the case I am describing.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-3328117671237054084?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=AHyMUMxVd8s:MoBOQvR7zME:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=AHyMUMxVd8s:MoBOQvR7zME:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=AHyMUMxVd8s:MoBOQvR7zME:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=AHyMUMxVd8s:MoBOQvR7zME:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=AHyMUMxVd8s:MoBOQvR7zME:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/AHyMUMxVd8s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/3328117671237054084/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=3328117671237054084" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/3328117671237054084?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/3328117671237054084?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/AHyMUMxVd8s/trouble-with-employment-agencies.html" title="Trouble with Employment Agencies" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/08/trouble-with-employment-agencies.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8EQH0-fCp7ImA9WxNXGEs.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-6558865563799279944</id><published>2009-08-02T15:53:00.006+10:00</published><updated>2009-10-07T09:06:41.354+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-07T09:06:41.354+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rounding" /><category scheme="http://www.blogger.com/atom/ns#" term="MDX" /><category scheme="http://www.blogger.com/atom/ns#" term="int" /><category scheme="http://www.blogger.com/atom/ns#" term="bankers' rounding" /><category scheme="http://www.blogger.com/atom/ns#" term="round" /><category scheme="http://www.blogger.com/atom/ns#" term="math" /><category scheme="http://www.blogger.com/atom/ns#" term="fix" /><title>Custom Rounding and Truncation of Numbers in MDX</title><content type="html">&lt;p&gt;&lt;em&gt;Article published in &lt;a href="http://www.sqlservercentral.com/articles/MDX/67928/"&gt;SQL Server Central&lt;/a&gt; on 2009/03/26&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In some scenarios we need to be able to round or truncate decimals to achieve correct calculation results. In SQL we have ROUND, which can do either of these. It rounds like we are used to - 0.5 rounds up to 1, can round up or down and we rarely get a project where as a part of the requirements we are implementing our own rounding or truncation algorithm. &lt;/p&gt;&lt;p&gt;However, in MDX we have Round() which performs a "strange" operation - bankers' rounding, which our business users have usually not been exposed to, and if we decide to truncate to an integer number through casting with Int or cInt, we also get some strange results. To illustrate the problem with MDX please consider the value of these expressions: &lt;/p&gt;&lt;p&gt;Round(2.15, 1) = 2.2&lt;br /&gt;Round(2.25, 1) = 2.2&lt;br /&gt;Round(2.35, 1) = 2.4&lt;br /&gt;Round(2.45, 1) = 2.4 &lt;/p&gt;&lt;p&gt;Int(1.9) = 1&lt;br /&gt;Int(-1.9) = -2&lt;br /&gt;cInt(1.9) = 1&lt;br /&gt;cInt(-1.9)= -2 &lt;/p&gt;&lt;p&gt;These are usually considered wrong, because they are not the obvious results. Even though they are mathematically well founded, if we round 2.25 to 2.2, our users will come back at us with wrong numbers on their reports. Same goes for "trimming" -1.9 to -2. &lt;/p&gt;&lt;p&gt;To resolve the first problem with rounding, we can use our own math formula: &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;color:#000099;"&gt;Fix([Measures].[???] * Factor + 0.5 * Sgn([Measures].[???])) / Factor&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Where Factor is the rounding factor - 1 for 0 decimal places, 10 for 1 and so on (defined by 1/Factor). Of course, Factor of 0 will give us Div by 0 error. (Reference: &lt;a href="http://support.microsoft.com/kb/196652"&gt;http://support.microsoft.com/kb/196652&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;If we have the Excel function libraries intalled on our server, we can also simply use Excel!Round() as &lt;a href="http://social.msdn.microsoft.com/forums/en-US/sqlanalysisservices/thread/3133ef66-4529-466c-bfa4-db733eff3917/"&gt;Chris Webb advises&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;As for the Int and cInt in MDX, we can use the Fix() VBA function to remove decimal places: &lt;/p&gt;&lt;p&gt;Fix(1.9) = 1&lt;br /&gt;Fix(-1.9) = -1 &lt;/p&gt;&lt;p&gt;Also, for truncation of values to a certain decimal point in MDX, we can use the following formula: &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;span style="color:#000099;"&gt;Fix(&amp;lt;value&amp;gt;*10&lt;strong&gt;&lt;span style="color:#000066;"&gt;^1&lt;/span&gt;&lt;/strong&gt;)/10&lt;/span&gt;&lt;span style="color:#000066;"&gt;&lt;strong&gt;^1&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000066;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;All we need to adjust in order to change the decimal places is to replace 10^1 with another power of 10 - in example, to truncate 3.156 to 3.15 we can use: Fix(3.156*10^2)/10^2. To make things simpler, in all our formulas the power of 10 is what determines how many decimal paces we need to round to; negative powers will give us rounding to tens, thousands and so on. If we use ^0 we will round to whole numbers.&lt;/p&gt;&lt;p&gt;Using these we can avoid bankers' rounding and some strange results with converting to integers in MDX.&lt;/p&gt;&lt;p&gt;&lt;span style="color:#000000;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-6558865563799279944?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=C8tgFDAFXls:pCbpa67lksk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=C8tgFDAFXls:pCbpa67lksk:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=C8tgFDAFXls:pCbpa67lksk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=C8tgFDAFXls:pCbpa67lksk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=C8tgFDAFXls:pCbpa67lksk:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/C8tgFDAFXls" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/6558865563799279944/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=6558865563799279944" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/6558865563799279944?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/6558865563799279944?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/C8tgFDAFXls/custom-rounding-and-truncation-of.html" title="Custom Rounding and Truncation of Numbers in MDX" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/08/custom-rounding-and-truncation-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUER389fCp7ImA9WxJVFU0.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-8507881631592688789</id><published>2009-07-02T13:58:00.003+10:00</published><updated>2009-07-02T14:00:06.164+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-02T14:00:06.164+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Reporting Services" /><category scheme="http://www.blogger.com/atom/ns#" term="Report Design" /><category scheme="http://www.blogger.com/atom/ns#" term="Colour Blindness" /><title>Developing reports for colour-blind people</title><content type="html">&lt;p&gt;According to Wikipedia 8% of all males and 0.4% of all females in Australia are colour-blind to some degree. The percentages are slightly different in the USA – 7% for males and 0.4% for females. It is estimated that these would be similar to other countries in the world, which means that a very high percentage of people may have difficulties distinguishing colours. Therefore, a significantly large part of our potential report users may not be able to interpret some of our graphs and charts correctly (There would be around 400 colour-blind males and 20 colour-blind females in an organisation which employs 10000 people).&lt;/p&gt;  &lt;p&gt;In example, the following &lt;strong&gt;chart&lt;/strong&gt; is quite nice and simple but can be useless to colour-blind people:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_BMa6MDrkUyA/SkwwHw7J7lI/AAAAAAAACNc/qZX0wzYZQmg/s1600-h/chart-colour%5B3%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="chart-colour" border="0" alt="chart-colour" src="http://lh5.ggpht.com/_BMa6MDrkUyA/SkwwIzexm6I/AAAAAAAACNg/x4eeSjDg8NQ/chart-colour_thumb%5B1%5D.png?imgmax=800" width="405" height="243" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;versus:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_BMa6MDrkUyA/SkwwJ_YX3OI/AAAAAAAACNk/jhOhicwH3mI/s1600-h/chart-grey%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="chart-grey" border="0" alt="chart-grey" src="http://lh3.ggpht.com/_BMa6MDrkUyA/SkwwLDlmVeI/AAAAAAAACNo/S18zAMyKNGc/chart-grey_thumb%5B2%5D.png?imgmax=800" width="407" height="248" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Similarly, this &lt;strong&gt;table&lt;/strong&gt; is somewhat confusing if we remove the colours:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_BMa6MDrkUyA/SkwwL08vLpI/AAAAAAAACNs/3As7uThWOw0/s1600-h/table-colour%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="table-colour" border="0" alt="table-colour" src="http://lh6.ggpht.com/_BMa6MDrkUyA/SkwwM8nCZ3I/AAAAAAAACNw/PtmcopAZg7U/table-colour_thumb.png?imgmax=800" width="244" height="74" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;versus:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_BMa6MDrkUyA/SkwwNw9u6VI/AAAAAAAACN0/7gyZXU6sOOU/s1600-h/table-grey%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="table-grey" border="0" alt="table-grey" src="http://lh3.ggpht.com/_BMa6MDrkUyA/SkwwPAEOPwI/AAAAAAAACN4/nuX7QHScVU0/table-grey_thumb.png?imgmax=800" width="244" height="74" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We have to be very careful with design of &lt;strong&gt;KPIs and dashboards&lt;/strong&gt; in general:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_BMa6MDrkUyA/SkwwP7Cvx2I/AAAAAAAACN8/8kC7m0jJDnA/s1600-h/kpi-colour%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="kpi-colour" border="0" alt="kpi-colour" src="http://lh5.ggpht.com/_BMa6MDrkUyA/SkwwQ7FBs4I/AAAAAAAACOA/TGzn9TeWkgk/kpi-colour_thumb.png?imgmax=800" width="244" height="74" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;versus:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_BMa6MDrkUyA/SkwwRr2QrkI/AAAAAAAACOE/TTW376kT_L0/s1600-h/kpi-grey%5B2%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="kpi-grey" border="0" alt="kpi-grey" src="http://lh5.ggpht.com/_BMa6MDrkUyA/SkwwSidiTJI/AAAAAAAACOI/GECaUfpRhv0/kpi-grey_thumb.png?imgmax=800" width="244" height="74" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As we can clearly see from the above examples, not being able to clearly distinguish colours makes our poorly designed charts and tables confusing.&lt;/p&gt;  &lt;p&gt;We should always keep in mind the following considerations when designing and implementing our most-common report items to ensure that they can be used by everyone in our client organisation:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;KPI indicators must be different in shape rather than just colour&lt;/li&gt;    &lt;li&gt;Line charts should utilise markers with different shapes&lt;/li&gt;    &lt;li&gt;Bar graphs should include a marker on the top of each bar&lt;/li&gt;    &lt;li&gt;Avoid colour-coded pie-charts – they can be extremely difficult to read for a person with even the slightest colour-blindness condition&lt;/li&gt;    &lt;li&gt;Avoid colour-coding tables – either backgrounds or text colours are usually unacceptable&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Other more general suggestions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Shapes are much more important than colours&lt;/li&gt;    &lt;li&gt;Greyscale and shades of the same colour are acceptable, as a colour-blind person can distinguish between those&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Of course, even after all our efforts to create reports readable by everyone, we may miss some detail. The best way to ensure that we have done a good job is to test. There are two good and easy ways to do that:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Printing – print the report in black and white and see if all information is well presented&lt;/li&gt;    &lt;li&gt;Changing display to greyscale – Windows lets us choose how many colours we want to display on our screen. Choosing greyscale and then playing with our report is possibly the best way to ensure that colour-blind people can use our reports.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;It is fairly simple and easy to always apply these design principles when creating reports. I have found that most organisations are quite happy to include minor tweaks to their dashboards and reports when they understand how important they could be for some of their employees. Furthermore, it helps to promote accessibility to technology regardless of minor disabilities and gender.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-8507881631592688789?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=viIip7tLwzE:vDp0Xdg7rsg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=viIip7tLwzE:vDp0Xdg7rsg:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=viIip7tLwzE:vDp0Xdg7rsg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=viIip7tLwzE:vDp0Xdg7rsg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=viIip7tLwzE:vDp0Xdg7rsg:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/viIip7tLwzE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/8507881631592688789/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=8507881631592688789" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/8507881631592688789?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/8507881631592688789?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/viIip7tLwzE/developing-reports-for-colour-blind.html" title="Developing reports for colour-blind people" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/07/developing-reports-for-colour-blind.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YMSHg9cCp7ImA9WxJRF00.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-2769045558261957299</id><published>2009-05-19T12:16:00.000+10:00</published><updated>2009-05-19T12:46:29.668+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-19T12:46:29.668+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Reporting Services" /><title>Reporting Services Styles in a Database Table</title><content type="html">&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;em&gt;Article published in &lt;/em&gt;&lt;a href="http://www.sqlservercentral.com/articles/Reporting+Services/66077/"&gt;&lt;em&gt;SQL Server Central&lt;/em&gt;&lt;/a&gt;&lt;em&gt; on 2009/03/26&lt;/em&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;As it was previously discussed by Adam Aspin in his series Add Styles to Your Reportng Services Reports on SQLServerCentral, it is very useful to be able to change various report attributes, such as colours and borders properties, in a centralised way just like by using CSS files or Skins. Currently, Reporitng Services does not allow us to use a similar approach, so Adam showed us how to apply a "style" to a report by using custom code in Reporting Services - either by embedding the code for all attriibutes directly in the report, or by referencing an external source. However, there is another way to handle such attributes and that is by storing them in a database table. There are certain advantages in doing so, but there could be some disadvantages, as well.&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;I will proceed to show how to build a report utilising this apporach and then I will discuss its strengths and weaknesses.&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;&lt;span class="Apple-style-span" style="FONT-WEIGHT: bold"&gt;Database Table&lt;/span&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;I would suggest to keep your database tables stroing values such as report attributes, Reporting Services environment settings (for using dynamically generated javascript) and other dynamic report properties separated by naming them in a unified way. I have used the CTL (for control) prefix in the past. For illustrative purposes I will provide a simple definition of a database table called CTLReportColours:&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;CTLReportColours (&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:Georgia;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;HeaderColour nvarchar(10),&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:Georgia;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;FooterColour nvarchar(10),&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:Georgia;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;BodyTextColour nvarchar(10)&lt;br /&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;As actual values we can store either the Reporting Services colour name (WhiteSmoke, SteelBlue, etc), or the colour codes (#00AA00, #CCBB66, etc). I am mentioning this because I have had issues with printers in the past, which recognise Red as Pink and changing to hex colour codes fixed the problem. This should be the topic for another article, so I will drop the subject here.&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;&lt;span class="Apple-style-span" style="FONT-WEIGHT: bold"&gt;Stored Procedure &lt;/span&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;We can either retrieve the values from the database table in a sotred procedure we are already using on our report, or we can create a new one, specifically built for getting report attributes. We can use the first approach if our report uses one data set only. Then we can assign all report items to that data set and simply use the Fields collection items in our expressions. However, if we have multiple data sets assigned to different report items, such as tables(ixes), we may find that we need to code the retrieval of our report attributes in many many stored procedures. To overcome this limitation, we can ceate a spearate stored procedure, which returns the set of values stored in the database table. A simple example is code like:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span class="Apple-style-span"  style="font-size:13;"&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;CREATE usp_CTL_Get_Report_Colours&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:16;"&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt;SELECT HeaderColour&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-tab-count: 2"&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;, FooterColour&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-tab-count: 2"&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="COLOR: rgb(102,51,0)"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;, BodyTextColour&lt;br /&gt;FROM CTLReportColours&lt;br /&gt;END&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;&lt;span class="Apple-style-span" style="FONT-WEIGHT: bold"&gt;Data Set&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;In Reporting Services we can use usp_CTL_Get_Report_Colours to construct a data set, which will have three fields named like the column names.&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;&lt;span class="Apple-style-span" style="FONT-WEIGHT: bold"&gt;Usage&lt;/span&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;To use a separate data set means that we need to be able to use its fields in some tables which already have a data set assigned to them. Since we can have only one data set per report element, we need to create separate parameters for each of the fileds in the attributes data set we have created. In our case, we need to create three parameters: HeaderColour, FooterColour and BodyTextColour. All of these should be hidden and should be populated by our data set in the outermost report only - if we have subreports, they should get their values from the parent report, so we avoid multiple execution of the usp_CTL_Get_Report_Colours stored procedure.&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;&lt;span class="Apple-style-span" style="FONT-WEIGHT: bold"&gt;Conclusion&lt;/span&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;The described method for handling report attributes can be preferable because:&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -36pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbolfont-family:Symbol;font-size:10;"  &gt;&lt;span style="mso-list: Ignore"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;We do not need to know anything about coding to create dynamic reports&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -36pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbolfont-family:Symbol;font-size:10;"  &gt;&lt;span style="mso-list: Ignore"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;Reports are dynamic with no need to re-deploy them&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -36pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbolfont-family:Symbol;font-size:10;"  &gt;&lt;span style="mso-list: Ignore"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;Report attributes are in a database table, which makes their management easy&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -36pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbolfont-family:Symbol;font-size:10;"  &gt;&lt;span style="mso-list: Ignore"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;Various management screens can be built on top of the database table in .NET with relative ease&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -36pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbolfont-family:Symbol;font-size:10;"  &gt;&lt;span style="mso-list: Ignore"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;Retireving the values through a stored procedures allows us to pass back parameters, which then can drive what colours get displayed - making the retrieval flexible if we need to display different colours for different departments or people&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -36pt; LINE-HEIGHT: normal; mso-list: l0 level1 lfo1; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="FONT-FAMILY: Symbol; mso-fareast-font-family: Symbolfont-family:Symbol;font-size:10;"  &gt;&lt;span style="mso-list: Ignore"&gt;·&lt;span style="FONT: 7pt 'Times New Roman'"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;Centralised and secured storage to all report attributes - environment settings, styles, etc.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-family:'Arial','sans-serif';font-size:10;"&gt;&lt;o:p&gt;The drawback is one as I see it: having to create multiple report parameters in all our reports. In my opinion it is a much smaller issue than having to manually change report properties with every change in the requirements and overall it is well worth the effort.&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-2769045558261957299?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=nWB7FColNzo:CBZ2g-EPoiI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=nWB7FColNzo:CBZ2g-EPoiI:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=nWB7FColNzo:CBZ2g-EPoiI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=nWB7FColNzo:CBZ2g-EPoiI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=nWB7FColNzo:CBZ2g-EPoiI:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/nWB7FColNzo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/2769045558261957299/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=2769045558261957299" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/2769045558261957299?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/2769045558261957299?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/nWB7FColNzo/reporting-services-styles-in-database.html" title="Reporting Services Styles in a Database Table" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/02/reporting-services-styles-in-database.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYER30zcCp7ImA9WxNQFU0.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-1944967437879494969</id><published>2009-04-04T15:51:00.015+11:00</published><updated>2009-09-21T12:28:26.388+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-21T12:28:26.388+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Kerberos" /><category scheme="http://www.blogger.com/atom/ns#" term="security" /><title>Enhanced Security and Integration of Microsoft BI Solutions with Kerberos</title><content type="html">&lt;p class="MsoNormal"&gt;&lt;span style="font-family:arial;"&gt;The following is an overview of an article prepared by Mark Dasco and myself. The full article is around 4800 words and is attached to the end of this post. Basically, the article is a quite thorough description of how to implement Kerberos and the benefits Kerberos provides when implementing Microsoft BI solutions.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="FONT-WEIGHT: bold;font-family:arial;" class="Apple-style-span" &gt;Table of Contents&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:arial;"&gt;1&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Overview&lt;br /&gt;2&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;The Double Hop&lt;br /&gt;3&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;The NTLM Protocol&lt;br /&gt;4&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;The Kerberos Protocol&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;&lt;br /&gt;5&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Business Intelligence Case&lt;br /&gt;6&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Implementation&lt;br /&gt;6.1&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Considerations&lt;br /&gt;6.2&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Implementation&lt;br /&gt;6.2.1&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Getting Started&lt;br /&gt;6.2.2&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Configure Clients for Kerberos Authentication&lt;br /&gt;6.2.3&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Defining SPNs&lt;br /&gt;6.2.4&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Using Negotiation&lt;br /&gt;6.2.5&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Enable Impersonation and Delegation&lt;br /&gt;6.3&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Checking that it all works&lt;br /&gt;7&lt;span style="WHITE-SPACE: pre" class="Apple-tab-span"&gt; &lt;/span&gt;Conclusion&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="FONT-WEIGHT: bold;font-family:arial;" class="Apple-style-span" &gt;Overview&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;When developing Microsoft Business Intelligence solutions we frequently need to rely on tight security integration between various tools. The NTLM protocol provides enough features for simple implementations, but when we need to provide enterprise-class solutions we invariably feel constrained by it. With Windows 2000 and later versions Microsoft provides an alternative security protocol - Kerberos, which addresses certain limitations of NTLM, provides improved security and better performance. The implementation of Kerberos could be fairly simple or very complex depending on the requirements. Configuring a few default server instances with no constraints on their services secured through Kerberos could be almost trivial, while for some more specific cases it could be a major cause of frustration.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;As a base for this study we will examine a specific BI case – a digital dashboard, which involves all layers of the Microsoft BI stack:&lt;/span&gt;&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;p style="TEXT-INDENT: -18pt; MARGIN-LEFT: 32.2pt; mso-list: l0 level1 lfo1; tab-stops: list 32.2pt" class="MsoNormal"&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Symbol;"&gt;&lt;span style="mso-list: Ignore"&gt;&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;SQL Server 2005&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Symbol;"&gt;&lt;span style="mso-list: Ignore"&gt;&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;SQL Server Analysis Services&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Symbol;"&gt;&lt;span style="mso-list: Ignore"&gt;&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;SQL Server Reporting Services&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Symbol;"&gt;&lt;span style="mso-list: Ignore"&gt;&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;PerformancePoint 2007 Monitoring and Analytics for building a dashboard&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;SharePoint Server as a organisational portal hosting the dashboard&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Furthermore, each of the servers exists on two environments – Development and UAT. Also, we will show how we can implement Kerberos only between the services utilised by the servers, not affecting the rest of the domain and effectively isolating the implementation.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:arial;"&gt;Typically, solutions not configured for Kerberos authentication and delegation fall back to the default NTLM authentication protocol. Whilst NTLM is completely transparent and very easy to use on a Windows domain, it falls short when we need to pass user credentials across a few server layers. This is commonly known as a &lt;i style="mso-bidi-font-style: normal"&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;double hop issue&lt;/span&gt;&lt;/i&gt;. If we depend solely on NTLM for user authentication, passing user names to servers on lower levels of our server topology involves including them in our connection strings or passing them programmatically, which is hardly the right choice for an enterprise-grade security framework.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;On the other hand solutions which correctly implement Kerberos are advantaged with cross-server delegation and authentication, thus allowing the use of Integrated Windows Authentication throughout the whole solution. The ability to capture user credentials on any server is essential if we want to be able to secure and control access to each server independently and minimise the damage resulting from a potential security breach.&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;a href="http://cid-6ed56dc26156fcc2.skydrive.live.com/self.aspx/.Public/Enhanced%20Security%20and%20Integration%20of%20Microsoft%20BI%20Solutions%20with%20Kerberos.doc"&gt;Download Full Article&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; by Mark Dasco and Boyan Penev&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-1944967437879494969?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=-SvNHMigXBw:0KHw42fmxeU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=-SvNHMigXBw:0KHw42fmxeU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=-SvNHMigXBw:0KHw42fmxeU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=-SvNHMigXBw:0KHw42fmxeU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=-SvNHMigXBw:0KHw42fmxeU:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/-SvNHMigXBw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/1944967437879494969/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=1944967437879494969" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/1944967437879494969?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/1944967437879494969?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/-SvNHMigXBw/enhanced-security-and-integration-of.html" title="Enhanced Security and Integration of Microsoft BI Solutions with Kerberos" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/04/enhanced-security-and-integration-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YNRXw-fyp7ImA9WxVbGE8.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-792441348481344782</id><published>2009-02-28T15:13:00.003+11:00</published><updated>2009-04-04T15:59:54.257+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-04T15:59:54.257+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Analysis Services" /><category scheme="http://www.blogger.com/atom/ns#" term="dimensions" /><title>Attribute Relationships in Analysis Services - RIGHT vs WRONG</title><content type="html">&lt;p&gt;Just a quick one - I just saw &lt;em&gt;again&lt;/em&gt; that someone has built his attribute relationships wrong. And that is in SSAS 2008 even after there is a nice graphical interface to it. I believe it is wrong by design. To illustrate:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The dimension:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_BMa6MDrkUyA/Sai54BIaAFI/AAAAAAAABtU/1tbrN___4EE/s1600-h/wrong11.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="143" alt="wrong1" src="http://lh3.ggpht.com/_BMa6MDrkUyA/Sai545bXDPI/AAAAAAAABtY/WeUPoSRpeaM/wrong1_thumb1.png?imgmax=800" width="404" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Current version (&lt;span style="color:#ff0000;"&gt;WRONG&lt;/span&gt;):&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_BMa6MDrkUyA/Sai55NHWskI/AAAAAAAABtc/suSPQRESBBw/s1600-h/wrong24.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="230" alt="wrong2" src="http://lh5.ggpht.com/_BMa6MDrkUyA/Sai558A1Q1I/AAAAAAAABtg/FcrZbyj2Jhg/wrong2_thumb4.png?imgmax=800" width="402" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Desirable version (&lt;span style="color:#008000;"&gt;RIGHT&lt;/span&gt;):&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_BMa6MDrkUyA/Sai56sR26pI/AAAAAAAABtk/xYvG_Ri1A-Y/s1600-h/right1%5B1%5D.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="80" alt="right1" src="http://lh3.ggpht.com/_BMa6MDrkUyA/Sai57T61k3I/AAAAAAAABto/h9xXYNieJm8/right1_thumb%5B1%5D.png?imgmax=800" width="407" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;It is not hard - you have:&lt;/p&gt;  &lt;p&gt;One-to-Many Chart Names for a Version,  &lt;br /&gt;One-to-Many Ledger Names for a Chart Name, and &lt;br /&gt;One-to-Many Finance Structures per Ledger Name. &lt;/p&gt;  &lt;p&gt;They form a hierarchy, which has levels. &lt;/p&gt;  &lt;p&gt;Each Finance Structure relates to a Ledger Name,  &lt;br /&gt;each Ledger Name relates to a Chart Name, and   &lt;br /&gt;each Chart Name relates to a Version.&lt;/p&gt;  &lt;p&gt;Having the correct set-up allows Analysis Services to create aggregations correctly, so the cube performance is optimised and MDX queries run quicker. Also, if the aggregations are wrong we can sometimes get wrong results for our queries...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-792441348481344782?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=AsnQW5SqTuU:twXksVGTCMA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=AsnQW5SqTuU:twXksVGTCMA:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=AsnQW5SqTuU:twXksVGTCMA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=AsnQW5SqTuU:twXksVGTCMA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=AsnQW5SqTuU:twXksVGTCMA:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/AsnQW5SqTuU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/792441348481344782/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=792441348481344782" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/792441348481344782?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/792441348481344782?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/AsnQW5SqTuU/attribute-relationships-in-analysis.html" title="Attribute Relationships in Analysis Services - RIGHT vs WRONG" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/02/attribute-relationships-in-analysis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQGR3k9eCp7ImA9WxVWFEk.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-747366009561139216</id><published>2009-02-24T12:49:00.015+11:00</published><updated>2009-02-24T14:48:46.760+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-24T14:48:46.760+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Analysis Services" /><category scheme="http://www.blogger.com/atom/ns#" term="Slowly Changing Dimension" /><category scheme="http://www.blogger.com/atom/ns#" term="dimensions" /><category scheme="http://www.blogger.com/atom/ns#" term="hierarchies" /><title>Combining Slowly Changing Dimensions and Current Dimension Versions</title><content type="html">&lt;div style="text-align: left;"&gt;When we need to see historical changes of a dimension in our OLAP cube the common practice is to implement it as a SCD - or a Slowly Changing Dimension. There are a few ways to do this and a really good definition of the different types of SCDs can be found in Wikipedia: &lt;a href="http://en.wikipedia.org/wiki/Slowly_changing_dimension"&gt;Slowly Changing Dimension&lt;/a&gt;. Also, there are quite a few articles on Implementing SCD ETLs in SSIS, two of which are: &lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.conchango.com/jamiethomson/archive/2005/06/06/1543.aspx"&gt;SCD Wizard Demo&lt;/a&gt; - SSIS Junkie blog example of a package using the Slowly Changing Dimension transformation in SSIS&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms141715.aspx"&gt;MSDN Article&lt;/a&gt; on the Slowly Changing Dimension transformation in SSIS&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;  &lt;p&gt;Since SQL Server Integration Services 2005 and 2008 include a SCD transformation it is not too hard to implement such dimensions.&lt;/p&gt;  &lt;p&gt;Here I am discussing a typical requirement - to be able to have a SCD and a Current version of the dimension.&lt;/p&gt;  &lt;p&gt;First, it is important to notice that a SCD should have two dimension keys: a unique surrogate key identifying every version of the dimension members and a non-unique code, which is common for all versions for a dimension member. This is also very important if we want to be able to determine the current version of a dimension member. An example of a very simple dimension table utilising this design is:&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); "&gt;&lt;img src="http://2.bp.blogspot.com/_BMa6MDrkUyA/SaNrx0GB-7I/AAAAAAAABss/oVLHwR1cPR4/s400/table8.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5306203289514277810" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 359px; height: 121px; " /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Here we have two distinct dimension members with Code of 1 and 2. Member1 has two versions and Member2 has three. The SKeys (surrogate keys) for these versions are unique but the codes stay the same for each member. Also, notice the From and To dates which allow us to distinguish the periods for the member versions. We can have an IsActive or IsCurrent bit column, which shows us the latest version of a node, but we can also just filter on dates which are 9999-12-31, which will give us the same result.&lt;/p&gt;  &lt;p&gt;Assuming the described design I will move on to discuss the ways to build a dimension in SSAS.&lt;/p&gt;  &lt;p&gt;First, the standard way to link the dimension table to our fact table is through the surrogate key. We can have a regular relationship between the two tables. As the fact data is usually also linked to a Time dimension, fact records linked against the periods between the From and To dates of our SCD will be linked to that versions SKey. An example of a fact table with a few rows, which can be linked to the dimension table above is:&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); "&gt;&lt;img src="http://1.bp.blogspot.com/_BMa6MDrkUyA/SaNrx8EgQMI/AAAAAAAABsk/w3NFWx8nC3E/s400/table7.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5306203291655356610" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 53px; " /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;The row with a FactKey of 1 will be linked against Member1Ver1, while FactKey 2 will go against Member1Ver2. Therefore, when we slice our cube by Time and our dimension we will see:&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_BMa6MDrkUyA/SaNrp59Vx7I/AAAAAAAABsE/hsj49Zcbjts/s1600-h/table3.PNG"&gt;&lt;img src="http://2.bp.blogspot.com/_BMa6MDrkUyA/SaNrp59Vx7I/AAAAAAAABsE/hsj49Zcbjts/s400/table3.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5306203153649485746" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 358px; height: 61px; " /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238); "&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;This is the standard way to implement our SCD and these are the results we would expect. Now, we get a new requirement. We want to be able to see both this and an aggregation against the current version of our dimension. We have a few ways to implement it. One obvious way is to create another dimension containing only the current dimension members. This can be easily achieved if we add a Named Query in our DSV, which shows only the current dimension members:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt;SELECT&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt;SKey&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt;, Code&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt;, Description&lt;br /&gt;FROM DimTable&lt;br /&gt;WHERE ToDate = '9999-12-31'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The result will be:&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_BMa6MDrkUyA/SaNsrr89ZgI/AAAAAAAABs0/l_LQO5AvLV0/s1600-h/table4.PNG"&gt;&lt;img src="http://1.bp.blogspot.com/_BMa6MDrkUyA/SaNsrr89ZgI/AAAAAAAABs0/l_LQO5AvLV0/s400/table4.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5306204283761157634" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 257px; height: 60px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;Then we need to replace our fact table with a Named Query, which shows the DimSKeys for current version dimension members:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;SELECT&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;ft.FactSkey&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;, dt_current.DimSKey&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;, ft.TimeKey&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;, ft.Amount&lt;br /&gt;FROM FactTable ft&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;INNER JOIN DimTable dt&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;ON ft.DimSKey = dt.SKey&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;INNER JOIN DimTable dt_current&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;ON dt.Code = dt_current.Code&lt;br /&gt;WHERE dt_current.ToDate = '9999-12-31'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This will give us the following result:&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_BMa6MDrkUyA/SaNrqNT9PCI/AAAAAAAABsU/CVYIfcfG35Q/s1600-h/table5.PNG"&gt;&lt;img src="http://3.bp.blogspot.com/_BMa6MDrkUyA/SaNrqNT9PCI/AAAAAAAABsU/CVYIfcfG35Q/s400/table5.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5306203158844619810" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 358px; height: 60px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;When we slice our cube, all records for Member1 will be against the latest version:&lt;/p&gt;&lt;blockquote&gt;&lt;p style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_BMa6MDrkUyA/SaNtD9y-o2I/AAAAAAAABtE/A3nbPo6dLh0/s1600-h/table6.PNG"&gt;&lt;img src="http://3.bp.blogspot.com/_BMa6MDrkUyA/SaNtD9y-o2I/AAAAAAAABtE/A3nbPo6dLh0/s400/table6.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5306204700867994466" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 359px; height: 40px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Implementing this, we can have two dimensions in our cube, so our users can use the one that makes more sense for their needs:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Dimension&lt;/strong&gt; and&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Dimension (Historical)&lt;/strong&gt;, and the &lt;em&gt;Historical&lt;/em&gt; designation stands for, in technical terms, a SCD&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;However, we can also implement this in a different way, which allows us to avoid building such logic in a view or our DSV. The trade-off is some space on our disks and one more column in our fact table. Instead of adding a new column through writing SQL, we can simply add the dimension Code in the fact table. Then, we can build our dimension again by getting the latest versions, but instead of having the SKey as a dimension key, we can use the Code. It is of course unique across all dimension members, as long as we filter our the non-current versions. The query for doing this is exactly the same as the one we used before. However, we need to change our fact table design and add a DimCode column:&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_BMa6MDrkUyA/SaNtMypllOI/AAAAAAAABtM/K3jEz9WC1s4/s1600-h/table7.PNG"&gt;&lt;img src="http://2.bp.blogspot.com/_BMa6MDrkUyA/SaNtMypllOI/AAAAAAAABtM/K3jEz9WC1s4/s400/table7.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5306204852494636258" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 53px; " /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Then, we create two dimensions again, but we link the Historical dimension with the DimSKey column and the Current one with the DimCode column. The result of slicing the cube by the current version is exactly the same as before. The trade-off is space vs. processing time and CPU usage. It is up to the developer to choose the more appropriate way to build the solution.&lt;/p&gt;  &lt;p&gt;&lt;span style="color:#000000;"&gt;So far I discussed two ways of having our SCD and Current Version dimension in different dimensions in our cubes. There is, however a way to combine both in the same dimension. To do this, we need to have two levels in the dimension: a parent level, which contains the current version of the dimension members, and a child level, which contains the historical versions. In example:&lt;/span&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 0, 153);"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Member1Ver2&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Member1Ver1&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Member1Ver2&lt;br /&gt;Member2Ver3&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Member2Ver1&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Member2Ver2&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Member2Ver3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;span style="color:#000000;"&gt;This way the historical versions aggregate up to the current version and we can use either level, depending on what we want to achieve. To build this, we can use our current dimension table and add a parent level through SQL. This way, we do not need to update all records when a new version comes:&lt;/span&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 51, 0);"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;SELECT&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;dt.SKey&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;, dt.Code&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;, dt.Description&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;, dt_p.SKey AS ParentSKey  &lt;br /&gt;FROM DimTable dt&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;INNER JOIN DimTable dt_p&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;ON dt.Code = dt_p.Code&lt;br /&gt;WHERE dt_p.ToDate = '9999-12-31'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The result is:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 0, 153);"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); "&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_BMa6MDrkUyA/SaNrp4rE5nI/AAAAAAAABr0/lUaCRnu58yc/s1600-h/table1.PNG"&gt;&lt;img src="http://1.bp.blogspot.com/_BMa6MDrkUyA/SaNrp4rE5nI/AAAAAAAABr0/lUaCRnu58yc/s400/table1.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5306203153304446578" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 101px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Then, we can build our Parent-Child dimension and we can use the Parent level is we want to have current versions and the Child level for the historical ones.&lt;/p&gt;  &lt;p&gt;This approach allows us to combine the two dimensions into one. It is also possible to implement it in a non-parent child fashion because the hierarchy is not ragged.&lt;/p&gt;  &lt;p&gt;It is always advisable to make sure we actually need a SCD and avoid it whenever possible because it is not always intuitive for users to use one. Splitting our fact data on multiple rows can be surprising for users and understanding how the historical dimension works and the multiple nodes it consists of can be a problem. However, it lets us satisfy a common requirement and therefore it is quite important to know how to build.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-747366009561139216?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FNOpiztNE6M:spWVylXDVYc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FNOpiztNE6M:spWVylXDVYc:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FNOpiztNE6M:spWVylXDVYc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=FNOpiztNE6M:spWVylXDVYc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=FNOpiztNE6M:spWVylXDVYc:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/FNOpiztNE6M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/747366009561139216/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=747366009561139216" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/747366009561139216?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/747366009561139216?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/FNOpiztNE6M/combining-slowly-changing-dimensions.html" title="Combining Slowly Changing Dimensions and Current Dimension Versions" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_BMa6MDrkUyA/SaNrx0GB-7I/AAAAAAAABss/oVLHwR1cPR4/s72-c/table8.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/02/combining-slowly-changing-dimensions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4FQno7eyp7ImA9WxVXFkw.&quot;"><id>tag:blogger.com,1999:blog-2781752892209685472.post-1641958771078282681</id><published>2009-02-14T23:00:00.002+11:00</published><updated>2009-02-14T23:01:53.403+11:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-14T23:01:53.403+11:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Reporting Services" /><title>Improving performance and maintainability by keeping logic out of our reports</title><content type="html">&lt;p&gt;As Reporting Services allows us to implement some quite complex logic, report authors are often tempted to build a lot of it in their reports. Having some simple calculations there does not generally cause harm, as simple + and – operations specific to a report should probably be built in it. However, I have seen aggregations, complex queries and code hacks, which would normally be performed fairly easily in Analysis Services or SQL Server built in Reporting Services.&lt;/p&gt;  &lt;p&gt;There are a few distinct benefits we can get from keeping logic out of our reports. &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Firstly, by having our MDX scripts and SQL Queries (stored procedures) in the back-end allows us to use them in different reports with no need to maintain them by painfully synchronizing them with every change. Also, this allows business MDX-ignorant users to use complex measures, increasing the value of the BI solution for them.&lt;/li&gt;    &lt;li&gt;Then, normally, our database server is usually maintained by people who have skills in SQL or MDX, and can analyse and optimise the scripts there instead of relying on report authors to do so. Even if we have BI professionals maintaining the whole solutions, it is far more convenient to have most of the logic stored on the same server. Whether it is a performance bottleneck, or a bug, it is far easier to fix it by tracing either cube calculations or stored procedures than logic stored in a report.&lt;/li&gt;    &lt;li&gt;Sending a large amount of data between the back-end server and SSRS is increasing the stress on the network, which can be critical when multiple requests with millions of rows in results are passed to it.&lt;/li&gt;    &lt;li&gt;Caching is important when different reports use the same stored procedures or MDX calculations.&lt;/li&gt;    &lt;li&gt;And a last point: a database/OLAP server is just faster in calculations that SSRS.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In general, using stored procedures as SQL Server data sources instead of building queries in SSRS; or alternatively, keeping MDX in calculations in the OLAP cubes is the first step towards avoiding excessive code accumulation in SSRS. Then, avoiding anything more complex than simple sums and groupings in the reports and moving them to the stored procedures or MDX calculations is another desirable way to structure our solutions. Finally, even simple things like Actual – Budget variance measure should be built in MDX or SQL rather than in the reports. Following these simple rules and keeping ourselves disciplined when building reporting solutions improves their performance, maintainability and even usability.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2781752892209685472-1641958771078282681?l=www.bp-msbi.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=teNOrHUYC9s:pJXWPB2kZS8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=teNOrHUYC9s:pJXWPB2kZS8:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=teNOrHUYC9s:pJXWPB2kZS8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?i=teNOrHUYC9s:pJXWPB2kZS8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/bp-msbi?a=teNOrHUYC9s:pJXWPB2kZS8:YwkR-u9nhCs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/bp-msbi?d=YwkR-u9nhCs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bp-msbi/~4/teNOrHUYC9s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.bp-msbi.com/feeds/1641958771078282681/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2781752892209685472&amp;postID=1641958771078282681" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/1641958771078282681?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2781752892209685472/posts/default/1641958771078282681?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/bp-msbi/~3/teNOrHUYC9s/improving-performance-and.html" title="Improving performance and maintainability by keeping logic out of our reports" /><author><name>Boyan Penev</name><uri>http://www.blogger.com/profile/06611947672367978163</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00710832500387316816" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.bp-msbi.com/2009/02/improving-performance-and.html</feedburner:origLink></entry></feed>
