A company I am working for requests a KPI concerning overtime hours booked. They want to measure if it's below their set threshold of 3%. There is a calculated member, named [Measures].[Percentage of Overtime Hours (%)], which can be used.
However, they want to limit the KPI to just the 2 departments they are available for.
I tried to limit the value by specifying this KPI Value expression:
([Measures].[Percentage of Overtime Hours (%)], {[Project].[Project Department].&[Department A], [Project].[Project Department].&[Department B]})
However, that gives me the following error message:
#Error The function expects a string or numeric expression for the argument. A tuple set expression was used.
On MSDN I could not find an answer to this. Google didn't yield me any decent results because I don't know what exactly to search for. Limiting a measure just gives me tons of articles about how the FILTER expression works, which seems not to be what I'm looking for.
How can I limit the KPI value to just the 2 departments?
I tried using SCOPE statement as suggested.
CREATE MEMBER CURRENTCUBE.[Measures].[Percentage of Overtime Hours (%) for AB] AS null;
SCOPE([Measures].[Percentage of Overtime Hours (%) for AB]);
This = NULL;
SCOPE([Project].[Project Department].&[Company A]);
This = ([Measures].[Percentage Overtime (%)], [Project].[Project Department].&[Company A]);
END SCOPE;
SCOPE([Project].[Project Department].&[Company B]);
This = ([Measures].[Percentage Overtime (%)], [Project].[Project Department].&[Company B]);
END SCOPE;
SCOPE([Project].[Project Department].[All]);
This = AGGREGATE({[Project].[Project Department].&[Company A], [Project].[Project Department].&[Company B]}, [Measures].[Percentage Overtime (%)]);
END SCOPE;
END SCOPE;
This however seems to push the same issue down one level deeper. It becomes clear when viewing [Measures].[Percentage of Overtime Hours (%) for AB] at the [Project].[Project Department].[All] level. It returns NULL. Any other suggestions?
You're getting the error because you're using a tuple (...) and inside the tuple you have a single member, followed by a set:
( //<<braces indicate a tuple
[Measures].[Percentage of Overtime Hours (%)] //<<single member
,{
[Project].[Project Department].&[Department A] //<<two member set
,[Project].[Project Department].&[Department B]
}
)
If your adding this to your cube script then can you do a scoped assignment?
I have very limited experience with these assignments but maybe something like the following:
CREATE MEMBER currentcube.[Measures].[Percentage of Overtime Hours (%) for AB]
AS null;
SCOPE( ({
[Project].[Project Department].&[Department A]
,[Project].[Project Department].&[Department B]
},
[Measures].[Percentage of Overtime Hours (%)]
));
this = [Measures].[Percentage of Overtime Hours (%)];
END SCOPE;
Related
I am new to MDX queries. I have written a query which uses lead function to get values for (Current Week plus 1) as a new column for each of the metrics. Basically comparing current week value with last week's value. Without the new members the query runs within seconds. After adding the new members it runs forever. Pls suggest ways to optimize this query
Thanks for help.
WITH
SET [Range] as strtomember
(" [Time].[Week].&["+ Format(DateAdd('d', - DatePart('w', Now(), 2), Now()+7), "yyyy-MM-ddT00:00:00")
+"]")
:strtomember
(" [Time].[Week].&["+ Format(DateAdd('d', - DatePart('w', Now(), 2), Now()+14), "yyyy-MM-ddT00:00:00")
+"]")
MEMBER [Measures].[SalesNew] as
CASE WHEN [Time].[Year].CURRENTMEMBER IS [Time].[Year].&[2019] THEN
sum([Time].[Day].CURRENTMEMBER.LEAD(7),[Measures].[Sales Prev])
ELSE null
END,FORMAT_STRING = "$#,###.00"
MEMBER [Measures].[Order UnitsNew] as
CASE WHEN [Time].[Year].CURRENTMEMBER IS [Time].[Year].&[2019] THEN
sum([Time].[Day].CURRENTMEMBER.LEAD(7),[Measures].[Order Units Prev])
ELSE null
END,FORMAT_STRING = "#,##0"
MEMBER [Measures].[Count of OrdersNew] as
CASE WHEN [Time].[Year].CURRENTMEMBER IS [Time].[Year].&[2019] THEN
sum([Time].[Day].CURRENTMEMBER.LEAD(7),[Measures].[Count of Orders Prev])
ELSE null
END,FORMAT_STRING = "#,##0"
SELECT
{ [Measures].[Sales],[Measures].[Sales Prev],[Measures].[SalesNew],[Measures].[Order Units],[Measures].[Order Units Prev],
[Measures].[Order UnitsNew], [Measures].[Count of Orders],[Measures].[Count of Orders Prev], [Measures].[Count of OrdersNew]} ON COLUMNS ,
[Range] *
[Time].[Day].[Day].ALLMEMBERS * -- 4
[Time].[Hour].ALLMEMBERS *
[Product].[Merch Dept].ALLMEMBERS *
[Product].[Class].ALLMEMBERS ON ROWS
FROM [Cube]
Your MDX looks pretty cool.
Optimizing MDX is a little bit black magic - you need to just try alternatives.
Initially I'd try:
1.Swapping in strToSet rather than the two strToMember functions.
2.Do you need the condition [Time].[Year].CURRENTMEMBER IS [Time].[Year].&[2019] ? Reason I ask is that [Range] seems to
already be 2019 and you cross-join to that set so do you need to
worry about 2019?
3.You can use a simple Tuple instead of the aggregate SUM
4.Maybe while testing it might be worth removing the format_strings - shouldn't make a difference but if so you can add back.
I've not tested the following so please excuse typos:
WITH
SET [DateSet] AS
strtoSet
(
"[Time].[Week].&["
+ Format(DateAdd('d', - DatePart('w', Now(), 2), Now()+7), "yyyy-MM-ddT00:00:00")
+ "]:[Time].[Week].&["
+ Format(DateAdd('d', - DatePart('w', Now(), 2), Now()+14), "yyyy-MM-ddT00:00:00")
+"]"
)
MEMBER [Measures].[SalesNew] AS
(
[Time].[Day].CURRENTMEMBER.LEAD(7)
,[Measures].[Sales Prev]
)
MEMBER [Measures].[Order UnitsNew] AS
(
[Time].[Day].CURRENTMEMBER.LEAD(7)
,[Measures].[Order Units Prev]
)
MEMBER [Measures].[Count of OrdersNew] AS
(
[Time].[Day].CURRENTMEMBER.LEAD(7)
,[Measures].[Count of Orders Prev]
)
SELECT
{
[Measures].[Sales]
,[Measures].[Sales Prev]
,[Measures].[SalesNew]
,[Measures].[Order Units]
,[Measures].[Order Units Prev]
,[Measures].[Order UnitsNew]
,[Measures].[Count of Orders]
,[Measures].[Count of Orders Prev]
,[Measures].[Count of OrdersNew]
} ON COLUMNS ,
[DateSet] *
[Time].[Day].[Day].ALLMEMBERS *
[Time].[Hour].ALLMEMBERS *
[Product].[Merch Dept].ALLMEMBERS *
[Product].[Class].ALLMEMBERS ON ROWS
FROM [Cube];
SCOPE ([Measures].[Net IMS Volume]);
( [Time].[Time Calculations].[MTD] )
= SUM(
MTD([Time].[Time Hierarchy 1].CURRENTMEMBER)
,[Time].[Time Calculations].[Current Time]
);
END SCOPE;
I was expecting my MTD to be displayed across the dates of the month. but the result is that I just get data at the Month Level.
When I do the same thing over at SSMS w/ the ff.:
WITH MEMBER [Time].[Time Calculations].MIKE2 AS
SUM
(
MTD([Time].[Time Hierarchy 1].CURRENTMEMBER)
,[Time].[Time Calculations].[Current Time]
)
SELECT
{
([Time].[Time Calculations].[MTD],[Measures].[Net IMS Volume])
,([Time].[Time Calculations].MIKE2,[Measures].[Net IMS Volume])
} ON 0
,[Time].[Time Hierarchy 1].[Date] ON 1
FROM [My Cube];
I get data at Date Level. I'm experiencing this on YTD function also.
Your time dimensions may not be typed correctly. Specific typing is required for the YTD and MTD to function as expected.
MSDN reference to YTD function: https://msdn.microsoft.com/en-us/library/ms146039.aspx
In the "remarks" section of the definition:
If a member expression is not specified, the default is the current
member of the first hierarchy with a level of type Years in the first
dimension of type Time in the measure group.
The Ytd function is a shortcut function for the PeriodsToDate function where the Type
property of the attribute hierarchy on which the level is based is set
to Years. That is, Ytd(Member_Expression) is equivalent to
PeriodsToDate(Year_Level_Expression,Member_Expression). Note that this
function will not work when the Type property is set to FiscalYears.
You could test if this is your problem by converting to the use of PeriodsToDate:
WITH MEMBER [Time].[Time Calculations].MIKE2 AS
SUM
(
PeriodsToDate(
[Time].[Time Hierarchy 1].[Month Level]
, [Time].[Time Hierarchy 1].CURRENTMEMBER
)
,[Time].[Time Calculations].[Current Time]
)
SELECT
{
([Time].[Time Calculations].[MTD],[Measures].[Net IMS Volume])
,([Time].[Time Calculations].MIKE2,[Measures].[Net IMS Volume])
} ON 0
,[Time].[Time Hierarchy 1].[Date] ON 1
FROM [My Cube];
i want to ask, if there is some function in MDX language, which returns me a same value in any case..
I created a calculated member, that's indicate how much value was sold on last year. It's work fine. But if I in slicer or filter exclude year value of the last year, i get nothing. Is there any function, that calculate a value with no filter?
For example, I need function like calculate in DAX in power pivot.
Thanks
Edit:
MDX calculated member for [Mat value]:
CREATE MEMBER CURRENTCUBE.[Measures].[MAT value]
AS SUM([03 Datumy].[MAT].&[MAT],[Measures].[Sales value]),
FORMAT_STRING = "#,##0.00;-#,##0.00",
VISIBLE = 1 , DISPLAY_FOLDER = 'Sales value' , ASSOCIATED_MEASURE_GROUP = '04 Hodnoty' ;
MDX calculated member for [Mat-1 value]:
CREATE MEMBER CURRENTCUBE.[Measures].[MAT-1 value]
AS SUM([03 Datumy].[MAT].&[MAT-1],[Measures].[Sales value]),
FORMAT_STRING = "#,##0.00;-#,##0.00",
VISIBLE = 1 , DISPLAY_FOLDER = 'Sales value' , ASSOCIATED_MEASURE_GROUP = '04 Hodnoty' ;
mat2014 http://www.attanon.eu/mat2014.PNGmat2013 http://www.attanon.eu/mat2013.PNG
filters http://www.attanon.eu/filters.PNGall http://www.attanon.eu/allmat.PNG
Edit2:
MAT and MAT-1 is based on column with this value. I have dimension like this:
dimension http://www.attanon.eu/dimension.PNG
And data looks that:
datumy http://www.attanon.eu/datumy.PNG
Relationship in [03 Datumy]:
relations http://www.attanon.eu/relations.PNG
The mat is calculated in SQL server. Because, i don't have much time to calculate the hiearchy in cube.
(discussion updates were removed as lack of necessity)
UPDATE to fix an issue:
Since your calculation, that determines months belonging to certain month, based on SQL, you can filter-out Date hierarchy by rewriting MAT-measures with adding [03 Datumy].[Year].[All]:
CREATE MEMBER CURRENTCUBE.[Measures].[MAT value]
AS ([03 Datumy].[MAT].&[MAT],[03 Datumy].[Year].[All],[Measures].[Sales value]),
FORMAT_STRING = "#,##0.00;-#,##0.00",
VISIBLE = 1 , DISPLAY_FOLDER = 'Sales value' , ASSOCIATED_MEASURE_GROUP = '04 Hodnoty' ;
and the same for next one:
CREATE MEMBER CURRENTCUBE.[Measures].[MAT-1 value]
AS ([03 Datumy].[MAT].&[MAT-1],[03 Datumy].[Year].[All],[Measures].[Sales value]),
FORMAT_STRING = "#,##0.00;-#,##0.00",
VISIBLE = 1 , DISPLAY_FOLDER = 'Sales value' , ASSOCIATED_MEASURE_GROUP = '04 Hodnoty' ;
Actually, it's an equivalent of old SSAS-2000 function .Ignore.
I'm getting the error: Query (9, 7) The '[Total Earnings]' member was not found in the cube when the string, [Measures].[Total Earnings], was parsed.
-- common enough, but I just don't see where in the query. Hopefully one of you will spot it, or have a better approach Here's what I have:
with
member measures.[Total all Earnings] as [Total Earnings]
(measures.[Total GS Earned]) + (measures.[Total DSE Earned]) + (measures. [Total Shares Earned])
set [Top 10 Interstate Earnings] as
topcount
(
{Stores.[Interstate]. [Interstate].members},
10,
(Measures.[Total Earnings], [Time].[C Year].[2011])
)
select
{([Measures].[Total Earnings])} on columns,
{[Top 10 Interstate Earnings]} on rows
from LoyaltyMeasurements
Where (Time.[C Year].[2012]);
I am a dufus... never mind. I didn't see until I pasted it!
the first line should be as follows for the calculated member:
with
member measures.[Total Earnings] as
Using the illustrated mockup
(Note not all DimB members show so the total for DimA is larger than the sum of the displayed DimB, ignore this):
Query is showing (months,revenue) on 0, (dima,dimb) on 1 from cube
I would like some assistance in creating the calculated member that would calculate the running total across "Months" here (not a real time dimension).
Earlier i was using this one, but it was wrong on so many levels:
[Measures].[Accumulated Revenue] =
IIF(
([DimMonths].[Months].CurrentMember,[Measures].[Revenue]) = 0
AND ([DimMonths].[Months].CurrentMember.NextMember,[Measures].[Revenue]) = 0
,
IIF(
AGGREGATE({
[DimMonths].[Months].CurrentMember :
[DimMonths].[Months].Parent.LastChild
},[Measures].[Revenue]) = 0
,
NULL
,
Aggregate( {
[DimMonths].[Months].Parent.FirstChild :
[DimMonths].[Months].CurrentMember.PrevMember
}
,[Measures].[Revenue])
)
,
Aggregate( {
[DimMonths].[Months].Parent.FirstChild :
[DimMonths].[Months].CurrentMember
}
,[Measures].[Revenue])
)
Sounds like a job for a "scoped assignment". Basically, using a scoped assignment, you can overwrite the value of your calculated measure along the [Member_DimA_01] slice so that these values represent a running total instead of a sum of children.
Here's a good tutorial from Chris Webb on scoped assignments to help get you started...
Edit: here's a template for the running total calculation...
WITH
SET [Months] AS
{
[Date].[Calendar Month].&[2011 - Jan]
:
[Date].[Calendar Month].&[2011 - Dec]
}
MEMBER [Measures].[Running Total] AS
SUM(
{
[Date].[Calendar Hierarchy].[Calendar Month].&[2011 - Jan]
:
[Date].[Calendar Hierarchy].CurrentMember
}
,[Measures].[Revenue]
)
SELECT
NON EMPTY{
[Months]
} ON 0,
NON EMPTY{
[DimA].[Member].Allmembers *
[DimB].[Member].Allmembers
} ON 1
FROM
[<<cube name>>]
WHERE
[Measures].[Revenue Running Total]