Convert MDX calculated measure, to scope in SSAS calculations - ssas

I have got a measure, getting the last value of a currency exchange rate. The fact having the exchange rates, is configured in the dimension usage with the time dimension, and is daily based. So, using MDX, I am successfully getting my converted measure in my currencies, by using a calculated measure:
with member [Measures].[Calculated Comp Money In] as
SUM([Dim Time].[Date Key].CurrentMember,
[Measures].[Comp Money In]/[Measures].[Last Currency Rate])
And then in the where clause, I would filter out what currency I am reporting figures on
[Dim Currency].[Currency Key].&[200]
However, what I don't like is that I have a [Measures].[Comp Money In], and a [Measures].[Comp Money In Calculated].... Can I use the SCOPE function in MDX, so that [Measures.[Comp Money In] is configured with the calculation above? I would then add this calculation in the calculations section of SSAS.

If you use the Enterprise edition of SSAS, you can use the measure expression property of your measure do currency conversion. This is not very well documented in the Analysis Services documentation, but works as follows: You use only one measure (i. e. either [Measures].[Calculated Comp Money In] or [Measures].[Comp Money In], and in the "Measure expression" property of this measure, enter the expression that you have in your question above:
[Measures].[Comp Money In] / [Measures].[Last Currency Rate]
Then the Analysis Services engine will take care of the rest for you. Note that this expression may only contain the measure on which you define it, times or divided by one other measure (normally he exchange rate) and nothing else.
If you do not have The Enterprise edition of Analysis Services, you can more or less copy your definition to a calculated member:
To be able to continue using the existing measure, possibly rename the measure [Measures].[Comp Money In] to [Measures].[_Comp Money In] (and make that measure invisible when you have checked that everything is fine). Then define a calculated member with the same name as the original measure:
create member CurrentCube.[Measures].[Comp Money In] as
SUM([Dim Time].[Date Key].CurrentMember,
[Measures].[_Comp Money In]/[Measures].[Last Currency Rate])
Better still, use SCOPE to calculate the measure, and avoid the aggregation for single days: Assuming the only common dimension between the measure group containing [Measures].[Comp Money In] and the measure group containing [Measures].[Last Currency Rate] is [Dim Time] and this has the key attribute [Dim Time].[Date Key], and your date hierarchy is named [Dim Time].[Date], you could just use
CREATE MEMBER CurrentCube.[Measures].[Comp Money In] as NULL;
SCOPE([Dim Time].[Date Key].[Date Key].members);
[Measures].[Comp Money In] =
[Measures].[_Comp Money In] / [Measures].[Last Currency Rate];
END SCOPE;
SCOPE([Dim Time].[Date].Members);
[Measures].[Comp Money In] =
Sum(EXISTING [Dim Time].[Date Key].[Date Key].members);
END SCOPE;

Related

Switch for different Measures

I would like to use three currencies for the reporting. These currencies come as columns in the facts. So we have 3 meausures
[Measures].[Amount EUR]
[Measures].[Amount USD]
[Measures].[Amount CHY]
for the Amount in EUR, USD, CHY.
The user can select his currency preferably in the global filter menu. Therefore, we use an additional Dimension [Currency Reporting] which contains the three currencies EUR, USD, CHY, which is not mapped to the Cube.
Depending on the selection, the different measures should be used in all the MDX statements of all widgets.
Currently, we use the function currencyCheck to check which element of the currency dimension was selected, and it accordingly chooses the measure.
Is there a standard way of doing this? Do you have any experience with this, and an idea of the best practise way to do it?
iif
(Curr_Member is [Currency Reporting].[Currency Reporting].[Currency Reporting].[EUR],
[Measures].[Amount EUR],
iif(Curr_Member is [Currency Reporting].[Currency Reporting].[Currency Reporting].[USD],
[Measures].[Amount USD],
[Measures].[Amount CHY])
)
CREATE CALCULATED MEMBER [Measures].[Amount] as
currencyCheck([Currency Reporting].[Currency Reporting].CurrentMember )
It is an option if you have a few measures that are amounts (need fx).
If no another option is using a 'Utility/Statistical dimension' for doing fx calculations. You can inspire yourself from.
Note, if fx rates are time dependent you'll have to apply the fx for each month / day. Here it's not the case as you've the amounts already calculated for the different currencies

SSAS Calculated Member - how to do percent of total based on another measure

I am currently trying to create a calculated measure for an SSAS 2008 R2 cube. In a financial cube dealing with accounts receivable data, I have a "Gross Balance" measure, and a "Days Since DOS" measure. The "Days Since DOS" measure is invisible to the user because it is only used in combination with a couple others to gain an average.
I would like the new calculated measure to show the percent of the total gross balance that has a Days Since DOS value > 90.
For example, if the total gross balance were $1000, the total gross balance for records with days since DOS > 90 being $500, the Percent Over 90 Days calculated measure would show 50%.
Would it be possible to do this with my current setup, and if so, how would I go about writing the expression?
I found out that it is in fact possible.
First, create a new named calculation in the DSV using a case statement (for example, call it [Gross Bal Over 90]):
CASE
WHEN [Days Since DOS] > 90 THEN [Gross Balance]
ELSE 0
END
Then, the calculated measure would simply be:
Sum([Gross Bal Over 90])/Sum([Gross Balance])
You can then make [Gross Bal Over 90] invisible to the user, keeping a cleaner look.

SSAS - Count Time Dimension

I looked at this topic, Calculating the number of days in a time dimension node - with Grand Total, but can't seem to get it.
I have a Time Dimension; [Invoice Date].
I want to count the number of Work Days in that dimension for a specified time period. I'm new to MDX.
Here's what I have.
Count(
Descendants(
[Invoice Date].CurrentMember,
[Invoice Date].[Work Date].[Work Date]
)
)
I'm getting a cube error now.
An easy way to implement this reliably would be to create a physical measure "Day Count". To do this, create a new measure group on the Date dimension table, and define "Day Count" as the Count. On the dimension usage tab, make sure you set a relationship from this measure group to the Invoice Date cube dimension and not the other dimensions.

MDX: How to calculate earned premium (i.e. prorata a measure between two time dimensions)

A simple cube has 1 measure and three time dimensions:
[Measures].[Amount Paid]
[Date Paid]
[Cover Start Date]
[Cover End Date]
Earned Premium =
0% if Cover Start Date is before the period in question
100% if Cover End Date has passed
else [Cover End - Cover Start] * Days Since Start
For any given cell, how do I traverse all the start and end dates and determine what the amount earned for a period is?
I assume other dimension are missing, e.g. one like [ContractId], if no what comes after doesn't make real sense.
The problem here is that your actual measure,earned premium, is a function (Amount Paid, Cover Start Date, Cover End Date, date) and this for each deal. You can not aggregate over a set of deals at once as the function is not associative - or something like this :-).
So I would feed my cube with the premium for each deal over the period [Cover Start Date], [Cover End Date] with the daily premium for this contract. Once you've this you can easily aggregate this measure over your dimensions. -> Now daily premium is not anymore a function of Cover dates..
MDX is not a real calculation engine, so you're pushing the system out of it's limit. Solving this with scopes, calculated measures can produce an amazingly slow cube...

How to override SSAS Business Intelligence 'Currency Conversion' for Liability calculation

I'm setting up a new cube in Analysis Services, and used the Business Intelligence wizard to work out the currency conversion issues. Now this all works perfectly, money is converted at the leaf level and summed up for display in the user's choice of reporting currency.
My problem now is the calculation of liability. For liability, I need to sum up the money in each currency, then convert it using the most recent 'End of Day Rate'. I have 'End of Day Rate' as a LastNonEmpty measure, but I can't see how to avoid the leaf-level conversion as shown below:
// This is the Many to One section
// All currency conversion formulas are calculated for the pivot currency and at leaf of the time dimension
Scope ({ Measures.[Money] } );
Scope( Leaves([Date]) ,[Reporting Currency].[GBP], Leaves([Currency]));
// Convert Local value into Pivot currency for selected Measures that must be converted with Measure rate [End Of Day Rate]
Scope( { Measures.[Money] } )
This = [Reporting Currency].[Local] * Measures.[End Of Day Rate];
End Scope;
End Scope;
// This is the One to Many section
// All currency conversion formulas are calculated for the non pivot currency and at leaf of the time dimension
Scope( Leaves([Date]) , Except([Reporting Currency].[Currency].[Currency].Members, {[Reporting Currency].[Currency].[Currency].[GBP], [Reporting Currency].[Currency].[Currency].[Local]}));
// This section overrides the local values with the Converted value for each selected measures needing to be converted with Measure rate [End Of Day Rate]…
// LinkMember is used to reference the currency from the source currency dimension in the rate cube.
Scope( { Measures.[Money] } );
This = [Reporting Currency].[Currency].[GBP] / (Measures.[End Of Day Rate], LinkMember([Reporting Currency].[Currency].CurrentMember, [Currency].[Currency]));
End Scope;
End Scope; // Leaves of time, all reporting currencies but local and pivot currency
End Scope; // Measures
The [Money] measure is paid in in different currencies, and each currency is keyed to a currency dimension and an 'End of Day Rate.
What is my best plan for calculating the liability? I'm considering replicating the [Money] measure, but it seems wasteful to have extra measures in just to avoid the currency conversion - Plus in the real cube there are several more measures that require the calculation so it won't just be the extra one.
Anyone else faced something similar?
OK so I ended up creating an invisible [Measures].[Money - Liability] which wasn't auto-converted by the above code, and I ended up with the following calculation in the script:
[Measures].[Liability] =
(
SUM
( [Currency].[Currency].[Currency],
SUM
(
{ NULL : [Date].[Date Key].CurrentMember },
(
[Money - Liability]
)
)
/ [Measures].[End Of Day Rate]
)
* (Measures.[End Of Day Rate], LinkMember([Reporting Currency].[Currency].CurrentMember, [Currency].[Currency]))
);