PowerBI - Column output based on another column value and time function - switch-statement

I have a table like that:
I'm comparing values from CurrentMonth vs PreviousMonth (based on the month selected in the slicer) for all of the KPIs, and based on that, I assign a specific result.
However, for each KPI, there is a logic behind when comparing. The logic is:
So, for KPI A, the CurrentMonth value must be 10% higher then PreviousMonth. When this is true, then assign 1. If not true, then 0. For KPI B, it has to be 3% higher. And for KPI C, it just needs to be higher.
To pull the CurrentMonth and PreviousMonth values, I created two measures, one of them with a time function:
CurrentMonth = SUM( [KPIValue] )
and
PreviousMonth = CALCULATE (
SUM( [KPIValue] );
PREVIOUSMONTH( [Date] )
)
I tried to create a Column in my table to assign the output (Result), and used a Switch function like this:
Result = SWITCH (
[KPIName];
"KPI A"; IF( [CurrentMonth] >= [PreviousMonth]*1.10;1;0 );
"KPI B"; IF( [CurrentMonth] >= [PreviousMonth]*1.03;1;0 );
"KPI C"; IF( [CurrentMonth] >= [PreviousMonth];1;0 );
)
My issue is that when I try to use this Switch, it does not work since the PreviousMonth comes as blank (it can not calculate a time function for each row of the table - only works as a measure).
I'm now lost how should I proceed from here. I tried to create a Measure instead of a Column, but then the Switch function does not accept the KPIName as a parameter.
Any ideas? Hope I've been clear here, if not, let me know what further information you need.

Found the solution. As a Measure (not column), include SELECTEDVALUE to be able to retrieve KPIName.
Result = SWITCH (
SELECTEDVALUE([KPIName]);
"KPI A"; IF( [CurrentMonth] >= [PreviousMonth]*1.10;1;0 );
"KPI B"; IF( [CurrentMonth] >= [PreviousMonth]*1.03;1;0 );
"KPI C"; IF( [CurrentMonth] >= [PreviousMonth];1;0 );
)

Related

How to use correctly IN filter in Acumatica Report Designer?

A bit new in Acumatica, I've been tasked to update a report which it in on itself is pretty easy, just adding a new value to a filter.
The part of the query I'm modifying is:
( [INRegister].[TransferType] = '1' AND [INTran].[TranDate] BETWEEN CONVERT(DATETIME, '20220101 0:0:0.000') AND CONVERT(DATETIME, '20230112 0:0:0.000') AND ( [INRegister].[DocType] = 'I' OR [INRegister].[DocType] = 'A') AND ( [INTran].[ReasonCode] = 'Null' OR [INTran].[ReasonCode] = 'BAJACADUCA' OR [INTran].[ReasonCode] = 'INISSUED' OR [INTran].[ReasonCode] = 'Null') AND ( [InventoryItem].[PreferredVendorID] = NULL OR NULL IS NULL ))
ORDER BY [InventoryItem].[ItemClassID], [InventoryItem].[PreferredVendorID], [INTran].[TranDate] OPTION(OPTIMIZE FOR UNKNOWN)
I need to use In when ReasonCode is INISSUED because it should have another value (BAJAMERCADERIA) too but everytime I try to use the In filter the second value is ignored or truncated when I check the trace.
The second value is primarily used for the between clause. Have you tried a comma delimited list in value1? i.e. BAJAMERCADERIA,INISSUED

MDX - rewrite a query using scope

I have an MDX query
IIF
(
IsLeaf([PnL].[PnL_A].CurrentMember)
,
[Measures].[PnL - Plan] * [PnL].[Flag 5].CurrentMember.MemberValue
,Sum
(
[PnL].[PnL_A].CurrentMember.Children
,[Measures].[PnL- Plan (signed)]
)
)
What it does:
The whole thing represents profit and loss. Unfortunately, it is constructed in a way that there are two columns: value of a profit or loss, and flag in the other column.
So if the flag ([PnL].[Flag 5]) is set to -1, the value ([Measures].[PnL - Plan]) is a loss, if the flag is a 1 - the value is a profit. I can't change that.
The query finds leaves of the hierarchy (single deepest source of a profit or loss) and multiplies the flag with the value. For non-leaf members it just aggregates it's leaves.
My problem is that it works too slow - I wanted to rewrite this query using SCOPE but I have no idea how.
Since I have absolutely no idea on your cube structure, let's say your member structure is
Pnl-->Pnl_A-->NonLeaf-->Leaf
You could define scope as below -
CREATE MEMBER CurrentCube.[Measures].[ProfitOrLossValue] AS NULL;
//Current member is leaf and Flag5 is 1
SCOPE
(
[Measures].[ProfitOrLossValue],
[PnL].[Flag 5].&[1],
[PnL].[PnL_A].[Leaf].[All].CHILDREN
);
This = [Measures].[PnL - Plan];
END SCOPE;
SCOPE
(
[Measures].[ProfitOrLossValue],
[PnL].[Flag 5].&[-1],
[PnL].[PnL_A].[Leaf].[All].CHILDREN
);
This = ([Measures].[PnL - Plan] * -1);
END SCOPE;
//Current member is non-leaf
SCOPE
(
[Measures].[ProfitOrLossValue],
[PnL].[PnL_A].[NonLeaf].[All].CHILDREN
);
This = Sum
(
[PnL].[PnL_A].CurrentMember.Children,
[Measures].[PnL- Plan (signed)]
);
END SCOPE;
Hope it helps.

MDX return fiscal PriorMTD date as value

I am trying to create MDX Calculated member which returns prior mtd date.
This is Calculated member I've created:
CREATE MEMBER CURRENTCUBE.[Measures].PriorMTDDate
AS cousin(
[Date].[Fiscal].CurrentMember,
[Date].[Fiscal].CurrentMember.parent.parent.lag(1)
),
VISIBLE = 1 ;
And this is query, but it returns just null:
select {[Measures].[PriorMTDDate]} on 0
from [WH_Cube]
WHERE ( [Date].[Fiscal].[Date].&[2014-09-12T00:00:00] )
Any idea what am I doing wrong?
EDIT: Another example returning null:
WITH MEMBER Measures.x AS
[Date].[Fiscal].CurrentMember
SELECT Measures.x ON 0
FROM [WH_Cube]
WHERE ( [Date].[Fiscal].[Date].&[2014-09-30T00:00:00] )
Does a measure need to be a numeric value?:
CREATE MEMBER CURRENTCUBE.[Measures].PriorMTDDate
AS cousin(
[Date].[Fiscal].CurrentMember,
[Date].[Fiscal].CurrentMember.parent.parent.lag(1)
).MemberValue ,
VISIBLE = 1 ;
.CurrentMember is evaluated at the row level, doesn't look into the slicer. The slicer is a global restriction on the cube, providing a sub-cube domain for your query.
In your query, [Date].[Fiscal].CurrentMember is underfined, as there is nothing on the Rows clause.
Try
select {[Measures].[PriorMTDDate]} on 0,
[Date].[Fiscal].[Date].&[2014-09-12T00:00:00] on 1
from [WH_Cube]

Using TopCount in MDX query

I'm trying to select the top 10 of a specified data set for use in a report. However, I'm not sure where it would go in the query. My current MDX query is below and mostly resembles what is automatically generated by the designer. What I'm trying to get is the top 10 Subcontractors by the value of Revised Value. Currently when I try to run this I get the error "Error running the data source query"
SELECT
TopCount([Dim Subcontractor].[Subcontractor Name].[Subcontractor Name].ALLMEMBERS, 10, [Measures].[Revised Value]),
{ [Dim Subcontractor].[Subcontractor Name].[Subcontractor Name].ALLMEMBERS }
ON COLUMNS,
{ [Measures].[Revised Value] }
ON ROWS
FROM [BGDEMO]
WHERE ( [Dim Project].[Project Name].DEFAULTMEMBER, [Dim Date].[Full Date].DEFAULTMEMBER )
CELL PROPERTIES VALUE, FORMATTED_VALUE, CELL_ORDINAL, FONT_FLAGS, FORE_COLOR, BACK_COLOR
Any help with this is appreciated.
Figured it out. I'll post it here in case others might find it useful:
SELECT
{ TOPCOUNT([Dim Subcontractor].[Subcontractor Name].[Subcontractor Name],10, [Measures].[Revised Value]) }
ON COLUMNS,
{ [Measures].[Revised Value] }
ON ROWS
FROM [BGDEMO]
WHERE ( [Dim Project].[Project Name].DEFAULTMEMBER, [Dim Date].[Full Date].DEFAULTMEMBER )
CELL PROPERTIES VALUE, FORMATTED_VALUE, CELL_ORDINAL, FONT_FLAGS, FORE_COLOR, BACK_COLOR

How to filter using calculated date value based on parameter in MDX

I'm trying to fetch the values based on a Date value passed as parameter (named AsOnDate) into a Performance Point report's MDX from a Webpart Date Filter. It's an Accounts database and the scenario is to fetch the Dormant accounts data. The problem I'm facing is that I need to fetch the Accounts having Dormant Date till 6 months before the AsOnDate value, i.e. AsOnDate -6 months, I managed to calculate the 6 month old date using DateAdd() function, like following:
DateAdd('m', -6, DateValue('<<AsOnDate>>'))
Now, I cann't figure out how to pass this value in place of the paramter in WHERE clause, MDX query looks like:
WITH
SET [Products] AS { <<Product>> }
MEMBER [Measures].[Dormant A/C Count] AS ([Measures].[Account Head Count])
MEMBER [Measures].[Dormant A/C Vol.] AS ([Measures].[LC Balance])
MEMBER [AH].[Subhead - Description].[Totals] AS Aggregate([Products])
SELECT
{ [Measures].[Dormant A/C Count], [Measures].[Dormant A/C Vol.]}
ON COLUMNS,
{[Products], [AH].[Subhead - Description].[Totals]}
ON ROWS
FROM
[MyCUbe]
WHERE (
[AH].[Is Dormant].&[1],
[AH].[Is Inoperative].&[0],
{NULL : [AH].[Dormant Date].&[ DateAdd('m', -6, DateValue('<<AsOnDate>>')) ]}
)
I get this error:
Error running data source query.
The 'DateAdd('m', -6, DateValue('2012-12-03'))'
string cannot be converted to the date type.
I have tried StrToMember() like:
WHERE (
[AH].[Is Dormant].&[1], [AH].[Is Inoperative].&[0],
{ NULL : StrToMember("[AH].[Dormant Date].&["+DateAdd('m', -6, DateValue('<<AsOnDate>>'))+"]")}
)
However, passing the Date Filter value directly as following works fine:
WHERE ( [AH].[Is Dormant].&[1], [AH].[Is Inoperative].&[0],
{ NULL : [AH].[Dormant Date].&[<<AsOnDate>>T00:00:00]} )
Figured it out, after some hit n trials.. managed to hack a combination of StrToMember() and Format() to convert calculated Date into string and feed it into MDX as Member, here's the working WHERE clause:
WHERE ( [AH].[Is Dormant].&[1], [AH].[Is Inoperative].&[0],
{ NULL : StrToMember("[AH].[Dormant Date].&[" + Format(DateAdd('m', -6, DateValue('<<AsOnDate>>')), 'yyyy-MM-dd') + "T00:00:00]") } )
Hope it will prove helpful for someone out there..

Resources