Help needed on resolving a string into MDX expression - ssas

The string is stored in a parameter.
Say, #FiscalPeriod = "[Date].[Fiscal Dates].[Fiscal Quarter]"
Now,
I need to use the parameter as
SELECT Measures.[Revenue] ON 0,
CLOSINGPERIOD("Parameter Here") ON 1
FROM [Sales]
STRTOMEBER function gives error because it is looking for a member at the leaf left such as
[Date].[Fiscal Dates].[Fiscal Quarter].&[Q1 - 2009]
How can I resolve the string into the mdx expression to use it with closing period??

The following should work:
SELECT Measures.[Revenue] ON 0,
STRTOMEMBER("CLOSINGPERIOD(" + #FiscalPeriod + ")") ON 1
FROM [Sales]

Related

SSRS Group Sort Using Group Variable

I'm looking to sort group Part using variable Coverage. The variable's expression:
=( IIF(ISNOTHING( SUM(Fields!OnhandQty.Value) ), 0, SUM(Fields!OnhandQty.Value)) +
IIF(ISNOTHING( Fields!WIP.Value ), 0, Fields!WIP.Value)
) / IIF(ISNOTHING( SUM(Fields!RequiredQuantity.Value) ), 0, SUM(Fields!RequiredQuantity.Value) )
I'm able to save report (using Report Builder) with no errors, but I get the error:
The processing of SortExpression for the table ‘TablixCustomer’ cannot be performed. The comparison failed. Please check the data type returned by the SortExpression. (rsProcessingError)
Why?
Your expression SUM(...Value) will fail if .Value is ever null and becomes a String value of #error. So try changing your expressions to this: Note that it checks the value before aggregating the value instead of aggregating before checking for null.
=( SUM(IIF(ISNOTHING(Fields!OnhandQty.Value), 0, Fields!OnhandQty.Value)) +
IIF(ISNOTHING( Fields!WIP.Value ), 0, Fields!WIP.Value)
) / SUM(IIF(ISNOTHING(Fields!RequiredQuantity.Value), 1, Fields!RequiredQuantity.Value))

How to tuple with Member_Key MDX SSAS?

I want to tuple using member key of [Dim].[Country]
{[Dim].[Country].CurrentMember.Member_Key},
STRTOSET("[User].[ID].&[" + mid(username, instr(username, "\")+1) + "]")
But when I use CurrentMember.Member_Key function I get the following error:
The function expects a tuple set expression for the 1 argument. A string or numeric expression was used.
If I write it like this using "members" is works. But then it will tuple with the full name (100 - Norway) but my goal is to tuple it with just the key part e.g "100"
{[Dim].[Country].members},
STRTOSET("[User].[ID].&[" + mid(username, instr(username, "\")+1) + "]")
Best regards,
Rubrix
Instead of [Dim].[Country].CurrentMember.Member_Key you should do something like this:
with member [Measures].CountryKey as [Dim].[Country].CurrentMember.Member_Key
So something like this could work (on Adventure Works):
with member [Measures].CountryKey as [Geography].[Country].CurrentMember.Member_Key
SELECT ([Measures].CountryKey, StrToSet ('[Geography].[State-Province].Members') )
ON 0
FROM [Adventure Works]

Using a set in the filter condition

I am trying the following query on the demo Sales cube of icCube:
WITH
SET [Amer.Countries]
AS Descendants([North America],[Country])
SELECT
Filter([Amer.Countries],([Measures].[Amount], {[2009], [2010]}) > 13240) on Rows,
[Measures].members on Columns
FROM [Sales]
WHERE [Time].[2011]
What is wrong with the condition ([Measures].[Amount], {[2009], [2010]}) > 13240 and how do I fix it?
I get the following error message from icCube:
operator '>' syntax error (left-operand:'set')
(right-operand:'numeric')
The only thing I understand from this message is that the use of the set  {[2009], [2010]} is out of place. However, I do not understand why that is the case and what the fix should be.
 
 
 
 
 
 
([Measures].[Amount], {[2009], [2010]}) > 13240
The left side of 13240 expects a numerical value or at least an expression that can be evaluated to a value. What you wrote is not a tuple and could be thought of as a crossjoin. To calculate the aggregated [Amount] for the year 2009 & 2010 of the current country:
([Measures].[Amount], {[2009], [2010]})
you can use eval function to compute the filtering value:
eval( {[2009], [2010]}, [Measures].[Amount] )
And use it within the SELECT to compute a static set that is ignoring the year [2011] specified in the slicer:
with
static set [Amer.Countries] as
filter( [North America].children ,
eval( {[2009], [2010]}, [Measures].[Amount]) >= 13240
)
select [Measures].members on 0, [Amer.Countries] on 1
from [Sales] where [Time].[2011]
You can have a look to the following introduction of MDX to better understand the notions of tuples, sets, etc...
Hope that helps.

The Axis0 function expects a tuple set expression for the argument

I just want to get the invoices distinct count of sales on March. I got this MDX query.
My MDX Query:
select
distinctcount([Measures].[Sales #]) on columns,
--[Measures].[Sales #] on columns,
non empty ([Customer].[Store Group].[Store Group]) on rows
from
(
select
{
[Calendar].[Month].[March 2015]
}
ON columns
from [F1_SalesBI])
But I got the following error, whenever I tried executing this.
Executing the query ...
The Axis0 function expects a tuple set expression for the argument. A string or numeric expression was used.
Execution complete
Here is the definition from msdn:
https://msdn.microsoft.com/en-us/library/ms145519.aspx
Syntax:
DistinctCount(Set_Expression)
You're doing this when you use Measures as the argument:
DistinctCount(Numeric_Expression)
Something like the following should hopefully run ok:
WITH
SET [mySet] AS
[Customer].[Store Group].[Store Group] * {[Measures].[Sales #]}
MEMBER [Measures].[setDistCount] AS
DistinctCount([mySet])
SELECT
{
[Measures].[setDistCount]
,[Measures].[Sales #]
} ON 0
,NON EMPTY
[Customer].[Store Group].[Store Group] ON 1
FROM
(
SELECT
{[Calendar].[Month].[March 2015]} ON 0
FROM [F1_SalesBI]
);
To return the number of invoices for the month try the following:
WITH
SET [mySet] AS
{[Calendar].[Month].[March 2015]} * {[Measures].[Sales #]}
MEMBER [Measures].[setDistCount] AS
DistinctCount([mySet])
SELECT
{
[Measures].[setDistCount]
} ON 0
FROM [F1_SalesBI];
If the above returns 1 then try inspecting the set via this script:
SELECT
{} on 0,
{[Calendar].[Month].[March 2015]} * {[Measures].[Sales #]} ON 0
FROM [F1_SalesBI];
Does this just return 1 member?
How about this (without the set braces around the measure)?:
SELECT
{} on 0,
{[Calendar].[Month].[March 2015]} * [Measures].[Sales #] ON 0
FROM [F1_SalesBI];

Convert "YYYYMMDD" format string to date in MDX?

I have some issue with applying date related functions on the "YYYYMMDD" format string in MDX. For example, if I have this query below:
with
member foo as WEEKDay("2013-03-21")
select
foo on 0
from
[Some Cube]
It will correctly output "5" for foo in SSMS. But if I change the second line to:
member foo as WEEKDay("20130321")
Unfortunately, it will throw "type mismatch" error.
So what I want to do is that converting the string to some recognizable date format and then applying the functions on it. Any ideas for the easiest way, e.g. using existing functions?
Please note that the string is actually inputted from members in any cube where the MDX is running on. So the string format could have been recognizable, e.g. "YYYY-MM-DD". So hard coded string converting algorithm may not be ok.
Topic is too old, but maybe this may help someone. Technique is quite brute, but scalable.
with
member foo_false as WeekDay("20130321")
member foo_true as WeekDay("2013-03-21")
member foo_brute as
case when IsError(WeekDay("20130321"))=False then WeekDay("20130321") else
case
/* YYYYMMDD */
when
IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
and IsError(WeekDay(Left("20130321",4)+'-'+Right(Left("20130321",6),2)+'-'+Right("20130321",2)))=False
then WeekDay(Left("20130321",4)+'-'+Right(Left("20130321",6),2)+'-'+Right("20130321",2))
/* DDMMYYYY */
when
IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
and IsError(WeekDay(Right("20130321",4)+'-'+Right(Left("20130321",4),2)+'-'+Left("20130321",2)))=False
then WeekDay(Right("20130321",4)+'-'+Right(Left("20130321",4),2)+'-'+Left("20130321",2))
/* MMDDYYYY */
when
IsError(WeekDay("20130321"))=True AND IsNumeric("20130321")=True
and IsError(WeekDay(Right("20130321",4)+'-'+Left("20130321",2)+'-'+Right(Left("20130321",4),2)))=False
then WeekDay(Right("20130321",4)+'-'+Left("20130321",2)+'-'+Right(Left("20130321",4),2))
/* Unsupported Message */
else "Unsupported Format" end
end
select
{foo_false,foo_true,foo_brute} on 0
from
[DATA Cube]
Adding supportable formats to the end before "Unsupported", use any input string instead of "20130321".
But the easiest way is to use another layer (e.g. SQL function CONVERT) before inserting to MDX if possible, sure thing.
The vba function isDate can be used to check if the passed date is well formatted. If not then format it first using dateserial and mid and use them.
with
member foo as "20130321"
member bar as
iif(vba!isdate(foo) = TRUE,
WEEKDay(foo), //--if the date is already well formatted, it can be used
WEEKday(vba!dateserial(vba!mid(foo, 0, 4), vba!mid(foo, 5, 2), vba!right(foo, 2))))
select
bar on 0
from
[some cube]
EDIT
The above code can be modified to accommodate other checks such as MMDDYYYY or DDMMYYYY, but the thing is it is impossible in lot of cases for the engine to intuitively know if the passed value is in YYYYMMDDDD or DDMMYYYY or MMDDYYYY. Take for example the string 1111111
This could easily be in any date format as it is a valid date howsoever you break it.
I would suggest that you have another member which can store the date format as well. That way looking at this member, string can be parsed.
e.g.
with
member foo as
// "20130321" //YYYYMMDD
// "03212013"//MMDDYYYY
"21032013"//DDMMYYYY
MEMBER dateformat as "ddmmyyyy"
member bar as
iif(vba!isdate(foo) = TRUE,
WEEKDay(foo),
IIF(dateformat = "yyyymmdd", //YYYYMMDD
WEEKday(vba!dateserial(vba!mid(foo, 0, 4), vba!mid(foo, 5, 2), vba!right(foo, 2))),
IIF(dateformat = "mmddyyyy", //MMDDYYYY
WEEKday(vba!dateserial(right(foo, 4), vba!mid(foo, 0, 2), vba!mid(foo, 3, 2))),
IIF(dateformat = "ddmmyyyy", //DDMMYYYY
WEEKday(vba!dateserial(right(foo, 4), vba!mid(foo, 3, 2), vba!mid(foo, 0, 2))),
null
)
)
)
)
select
bar on 0
from
[aw cube]
With FooMember being an int here, representing a yyyyMMdd date I could convert it to Date using the following code
=Format(CDate(Left(CSTR(Fields!FooMember.Value),4)
+ "-" + Mid(CSTR(Fields!FooMember.Value), 5, 2)
+ "-" + Right(CSTR(Fields!FooMember.Value), 2)),
"dd/MM/yyyy")
use it in a cube using the following code
Format(CDate(Left([Measures].[FooMember],4)
+ "-" + Mid([Measures].[FooMember], 5, 2)
+ "-" + Right([Measures].[FooMember], 2)),"yyyy/MM/dd")