Showing posts with label selecting. Show all posts
Showing posts with label selecting. Show all posts

Monday, March 12, 2012

MDX to dynamically insert calculated members into row?

I need some help writing the MDX for selecting Row members in a particular
query. Here's the background:

The query shows sales results by region and office. The row members should
be like this:

OfficeA
OfficeB
OfficeD
Region1
Region1 (SOC)
OfficeE
OfficeF
OfficeG
OfficeJ
Region2
Region2 (SOC)
World
World (SOC)

There are two things to note about this:

1. The set of offices is being filtered to only show the "active" ones (i.e.
offices which are operational - offices C, H & I have closed down)

2. The Region1, Region2 and World members are straightforward sums of their
(active) children. However, the Region1 (SOC), Region2 (SOC) and World (SOC)
members are calculated - the idea is that they represent a "Same Office
Comparison", in other words only sum the offices that were active both last
year and this year.

The dimensions used to generate the row members are:

1. Region with levels Region and Office
2. Active Office with levels Active (True/False) and SOC (True/False)

This is the MDX I used to generate the members EXCEPT for the "SOC" members:

Member [Region].[World] as
' [Region].[All Region] ' , solve_order = 1

Non Empty
{
Filter(
Hierarchize( Except( [Region].Members , [Region].[All Region] } )
, POST ) ,
[Active Office].[All Active Office].[True] > 0) ,
[Region].[World]
}
ON ROWS

Where I am stuck is generating the "SOC" members and including them in the
set of row members in the correct order. I need to do this without hard
coding any references to specific regions or offices (regions and offices
change over time).

Any ideas?

Many thanks

HI Laurence,

As you have no doubt found, it is hard to insert a calculated member in a specific location in a hierarchy. What I would suggest is to create "real" members in your dimension tables for the "(SOC)" members, but don't have any data associated with them. Then use an assignment in your MDX script to calcuate the value for these members

You could hard code a calculation something like the following:

([Region 1 (SOC)]) = Aggregate([Region].[Region].&[Region 1].Chidren,[Region].[SOC].[True])

But if it were me I think I would probably want to make the calc more generic. You could possibly add an attribute or add a "Total" member to the SOC attribute so that you could pull out just the SOC total members and then grab the children of the previous member and filter them by [SOC].[True] - or something like that Smile

|||

I do need to make the solution as generic as possible as the regions do change .... can you explain a bit more what you mean by '.... add an attribute or add a "Total" member to the SOC attribute ....'

|||

Sure. When I said "add an attribute" I was thinking that you could either change your existing [SOC] column to contain another value, so it would have "True", "False" & "Total" or you could add another column to your dimension table. Then what I would do is to add another row into your dimension table at the same level as the "Region 1" member, but called "Region 1 SOC" and tagged with a specific attribute value so that you could filter down to just these members .You would not have any facts associated with these members, they would simply be placeholders at a specific positions in the dimension. You would then use an assignment in the MDX Script to set the values for these members.

You might then be able use an assignment similar to the following (which is more psuedo code, but hopefully it will help illustrate my thought process)

Code Snippet

SCOPE [Region].[SOC].[SOC].[SOC Total] -- grab just the members tagged as "SOC Total"

-- i'm not clear on your exact structures and logic, but assuming

-- that the "SOC total" members are ordered after the real region totals,

-- the code below grabs the real region's children and adds them up,

-- filtering on only those members where [SOC] is true.

this = aggregate({[Region].[Region].[Region].Prevmember.children

, [Region].[SOC].[SOC].&{True]})

END SCOPE;

|||

Ah-ha, I think I got it! I will try it out, thanks very much.

Friday, March 9, 2012

MDX range not working

I've come across an issue with MDX with regards to selecting a range of consolidation units. On my MDX statement,

Code:
SELECT {[Measures].[0CS_TRN_LC], [Measures].[0CS_TRN_QTY]
} ON COLUMNS, NON EMPTY {CROSSJOIN(
{
[ZCS_UNIT].[DPCO991-CONSCORR]:[ZCS_UNIT].[DPCO991-99001000]
},
[0CS_ITEM].[All]:[0CS_ITEM].
)}

If the first entry in ZCS_UNIT is valid and contains data in it, my mdx statement retrieves the data accordingly. However, if the first entry is valid and does not contain any data, I do not retrieve any data at all (even if the other cons unit in the range contain data) ! Since the users put in the range of cons unit in the selection screen, there is no way to validate if the first cons unit has data or not. I tried removing the "NON EMPTY" before cross join but nothing changed.

Seems that the first entry is critical, as it has to be both valid and contains data for me to be able to retrieve anything.

This is my first MDX report (no formal training), I am writing this report for the BW system in SAP.

Is this an MDX/SAP bug, or is there something wrong with my MDX statement contruction?

Thanks.

I would advise asking your question in the SQL Server Analysis Services forum: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=83&SiteID=1 as this specific forum is targeted at reporting in the context of Team Foundation Server

Thanks,

Othmane