<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.adatis.co.uk/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'MDX', 'Business Intelligence', and 'PEL'</title><link>http://blogs.adatis.co.uk/search/SearchResults.aspx?o=DateDescending&amp;tag=MDX,Business+Intelligence,PEL&amp;orTags=0</link><description>Search results matching tags 'MDX', 'Business Intelligence', and 'PEL'</description><dc:language>en-US</dc:language><generator>CommunityServer 2007 SP2 (Build: 20611.960)</generator><item><title>PEL Business Rule Re-use and Pre-defined What If Scenarios</title><link>http://blogs.adatis.co.uk/blogs/sachatomey/archive/2008/04/30/pel-business-rule-re-use-and-pre-defined-what-if-scenarios.aspx</link><pubDate>Wed, 30 Apr 2008 21:17:11 GMT</pubDate><guid isPermaLink="false">8d7d37f8-4a66-4c95-9fba-293fa87607dc:4784</guid><dc:creator>sachatomey</dc:creator><description>&lt;p&gt;You’ve built a rule set to satisfy an original set of business requirements for calculating budget, and all is good with the world.&amp;nbsp; Then, a change order is raised and approved that requires, for want of a better description, a set of pre-defined what if* scenarios to apply to the calculated budget. &lt;p&gt;The pre-defined what-if’s are essentially the same business rule calculations with a slight factor or variance applied so it makes sense to want to re-use the existing rules. Not an unreasonable request. &lt;p&gt;What’s the best way to implement this change request without introducing the burden of duplicated rules and keeping your model clean and well structured? &lt;p&gt;&lt;b&gt;Background&lt;/b&gt; &lt;p&gt;This is the rule set in question: &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/WindowsLiveWriter/PELBusinessRuleReuseandPredefinedWhatIfS_13A8C/image_4.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="175" alt="image" src="http://blogs.adatis.co.uk/blogs/sachatomey/WindowsLiveWriter/PELBusinessRuleReuseandPredefinedWhatIfS_13A8C/image_thumb_1.png" width="458" border="0" /&gt;&lt;/a&gt;  &lt;p&gt;These rules utilise an assumption model that contains values such as salary levels, training days, tax assumptions etc and calculate various budget lines based on headcount information collected from a variety of regional cost centres. &lt;p&gt;The rules are pretty straightforward as the Salary rule outlined below shows: &lt;p&gt;&lt;font face="Courier New" size="2"&gt;scope&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;(&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;&lt;br /&gt;[Scenario].[All Members].[Budget],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Account].[Detail].[Salary Costs],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Role].[Role].[All Roles], 0, after),&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Time].[Quarterly].[Year2008], 0, after),&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Region].[Region].[Global], 0, after)&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;) ;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;this =&lt;/font&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;(&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;(Model([Drivers]), &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Account].[Detail].[Annual Salary],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Time].[Quarterly].CurrentMember.Ancestor([Time].[Quarterly].[Year]),&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Role].[Role].CurrentMember,&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Region].[Region].CurrentMember,&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Scenario].[All Members].[Budget]) / 4&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;)&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;*&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;(&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;[Account].[Detail].[Headcount], &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Time].[Quarterly].CurrentMember, &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Role].[Role].CurrentMember, &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Region].[Region].CurrentMember,&lt;br /&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;[Scenario].[All Members].CurrentMember&lt;b&gt;&lt;/b&gt;&lt;/font&gt;&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;end scope;&lt;/font&gt; &lt;p&gt;Essentially, for each quarter, for each role within each region we are multiplying the appropriate annual salary from the assumption model (divided by 4 for quarters) by the appropriate headcount to give us the budget salary figure. &lt;p&gt;&lt;b&gt;New Requirement&lt;/b&gt; &lt;p&gt;Our change order requires a view of the budget as if we were to increase or decrease the headcount for each role within each region by 30%. Our new scenario dimension will look like this: &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/WindowsLiveWriter/PELBusinessRuleReuseandPredefinedWhatIfS_13A8C/image_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="81" alt="image" src="http://blogs.adatis.co.uk/blogs/sachatomey/WindowsLiveWriter/PELBusinessRuleReuseandPredefinedWhatIfS_13A8C/image_thumb.png" width="213" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;The last two members have been added to cope with this new requirement – you could argue that these members could exist in a separate ‘what-if’ style dimension that could then be applied to any of the scenarios independently. I actually prefer that approach, but for simplicity let’s just limit this explanation to the scenario dimension. &lt;p&gt;Okay, we have our new scenario members, we now need to wire up some rules to calculate these alternate budgets. &lt;p&gt;&lt;b&gt;Design&lt;/b&gt; &lt;p&gt;Our first problem is how we can make the existing rules generic across budget scenarios. We have the budget scenario factors (a +30% and a -30%) to work in somewhere. We could hard-code these values into the rules but that would require a rule set per budget scenario thus duplicating all rules. Nasty. &lt;p&gt;We could store the factors in an assumption model against the appropriate budget scenario, this could then be referenced within the rule. That would potentially allow us to re-use the business rules. However, I’m not keen on this approach at all as I feel that the budget factors are fixed, scalar values and to store them in an assumption model is overkill and would potentially require much more implementation effort. &lt;p&gt;So, what option(s) are we left with? Not many, in this situation I would be tempted to create a member property on the Scenario dimension that held the factor against the appropriate member. The business rules could then simply (yeah right, see later!) reference the member property and apply the factor. So, in the case of the main Budget scenario we would have a factor of 1, for Budget +30% Headcount we would store a factor of 1.3 and 0.7 would be set against Budget -30% Headcount. &lt;p&gt;So, on the face of it you can then update each rule to multiply every reference of Headcount by the appropriate factor held in a member property. &lt;p&gt;However, there is a problem. That problem lies with the PEL function ‘Properties’. Unlike the MDX equivalent, the PEL version always returns a string, irrespective of the data type you assign to the member property itself. You cannot multiply by a string value and PEL does not contain any data type conversion functions to overcome this issue. &lt;p&gt;&lt;b&gt;Implementation&lt;/b&gt; &lt;p&gt;The workaround: Use a Native MDX implementation. That sounds worse than it is; I’m not suggesting that you re-write all the business rules in MDX, although that is certainly an option. &lt;p&gt;Alternatively, you can add a single MDX business rule to the top of the rule set that re-calculates Headcount, using the value of the member property: &lt;p&gt;&lt;font face="Courier New" size="2"&gt;scope&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;(&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;{&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Scenario].[All Members].[Scenario].&amp;amp;[402],[Scenario].[All Members].[Scenario].&amp;amp;[501]},&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Time].[Quarterly].[Year].&amp;amp;[2008], 0, AFTER),&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Account].[Detail].[Level 02].&amp;amp;[5001],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Region].[Region].[Level 02].&amp;amp;[5201], 0, AFTER),&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Role].[Role].[Level 02].&amp;amp;[101], 0, AFTER)&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;);&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;([Measures].[Value])=&lt;/font&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;(&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;[Scenario].[All Members].[Budget],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Time].[Quarterly].CurrentMember,&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Account].[Detail].[Headcount],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Region].[Region].CurrentMember,&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Role].[Role].CurrentMember&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;)&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;*&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;[Scenario].[All Members].CurrentMember.Properties(&amp;#39;OffsetPercent&amp;#39;);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;end scope;&lt;/font&gt; &lt;p&gt;Apart from the fact the MDX rule is very PEL like, notice the last line of the rule. Here the headcount for each role, region and quarter is multiplied by the Scenario member property OffsetPercent. &lt;p&gt;With this in place, the subsequent rules will calculate the budget scenarios based on the appropriate revised headcount value. (Due to the natural solve order of the rules in the rule set). &lt;p&gt;The final step is to update each of the rules scope to include each of the budget scenarios (leaving the main bulk of the rule in place, untouched).  &lt;p&gt;Here’s the updated version of the Salary rule we looked at earlier (Modification in &lt;font color="#008000"&gt;green&lt;/font&gt;) &lt;p&gt;&lt;font face="Courier New" size="2"&gt;scope&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;(&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" color="#008000" size="2"&gt;{&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" color="#008000" size="2"&gt;[Scenario].[All Members].[Budget],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" color="#008000" size="2"&gt;[Scenario].[All Members].[BudgetPlus30PcntHCount],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" color="#008000" size="2"&gt;[Scenario].[All Members].[BudgetMinus30PcntHCount]&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" color="#008000" size="2"&gt;},&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Account].[Detail].[Salary Costs],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Role].[Role].[All Roles], 0, after),&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Time].[Quarterly].[Year2008], 0, after),&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;Descendants([Region].[Region].[Global], 0, after)&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;) ;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;this =&lt;/font&gt;  &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;(&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;(Model([Drivers]), &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Account].[Detail].[Annual Salary],&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Time].[Quarterly].CurrentMember.Ancestor([Time].[Quarterly].[Year]),&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Role].[Role].CurrentMember,&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Region].[Region].CurrentMember) / 4&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;*&lt;/font&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;(&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Account].[Detail].[Headcount], &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Time].[Quarterly].CurrentMember, &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Role].[Role].CurrentMember, &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;[Region].[Region].CurrentMember&lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New" size="2"&gt;);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;font face="Courier New" size="2"&gt;end scope;&lt;/font&gt; &lt;p&gt;For completeness, our modified rules set will look like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.adatis.co.uk/blogs/sachatomey/WindowsLiveWriter/PELBusinessRuleReuseandPredefinedWhatIfS_13A8C/image_6.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="171" alt="image" src="http://blogs.adatis.co.uk/blogs/sachatomey/WindowsLiveWriter/PELBusinessRuleReuseandPredefinedWhatIfS_13A8C/image_thumb_2.png" width="398" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Notice the new (MDX) rule ‘Headcount’, this will be calculated first, for each of the budget scenarios ensuring the subsequent rules use the appropriately factored headcount figure.&lt;/p&gt; &lt;p&gt;The support for Business Rule re-use is limited in PPS-P v1 but as this example hopefully illustrates, with a little thought and application, re-use is occasionally achievable.&amp;nbsp; I hope there will be better support for re-use in future versions ! &lt;p&gt;--------------------------------------- &lt;p&gt;&lt;font size="1"&gt;* Generally, what-if’s are used dynamically; you change a few numbers in a data entry worksheet, re-calculate the sheet and view the results, repeating the process as necessary. This is a great feature and really quite powerful, however, there are some situations where pre-defined what-if’s are required to easily and frequently show standard what-if scenarios.&lt;/font&gt;</description></item></channel></rss>