SSAS MDX Calculated Measure - COUNT of [ITEMS].[Item] grouped [Items].[Item Group] - excel

In Excel connected to SSAS, I am trying to build a pivot table and add a custom Measure Calculation using "OLAP Tools" and/or "OLAP Pivot Table Exensions". I am trying to add a calculation that is really simple in my mind, but I cannot get it to work. The calc I need is:
GOAL: A record count of the [Items] dimension records grouped by any of the
[Items] dimension fields.
In particular I am trying to group by [Items].[Items Groups] and [Items].[Item]. Item is the lowest grain, so the count should return value "1". I have created a couple calculations that are kind of in the ballpark (see below). But the calcs don't appears to be working as desired.
What I have tried:
Attempt #1 -- [Measures].[Items Count (With net amount values)]
DISTINCTCOUNT( {[Items].[Item].MEMBERS} )
The calc 'Items Count (With net amount values)' appears to be
returning a decent count value, but it appears it only counts the Item
if there are transnational records found (not sure why). Also, when
at the lowest grain level the calc returns that value for the parent
group, not the dimension level selected on the rows.
Attempt #2 -- [Measures].[Items Count (All)]
[Items].[Item].[Item].Count
This calc returns the TOTAL item count for the entire dimension
regardless of the dimension level placed on the rows.
Attempt #3 -- [Measures].[Items Count]
COUNT ( { [Items].[Item].MEMBERS}, EXCLUDEEMPTY)
This calc freezes up Excel and I have to quit Excel. No idea why. I have seen this sytnax recommended on a few different sites.
Screenshot:
Help please? This seems really simple, but I am not very skilled with MDX. In DAX and SSAS TABULAR this would be very simple expression. But I'm struggling to count the rows with MDX in SSAS MD.
The "Outside Purchased Beef" group has 18 items with transactions, but 41 items in total. I do not know how to calculate the "41" value.
SSAS Excel-CalcMeasure-CountRows.png

Take a look at the following samples on AdventureWorks.
with member [Measures].[CountTest]
as
count(existing [Product].[Subcategory].members - [Product].[Subcategory].[All])
select
{
[Measures].[Internet Sales Amount],[Measures].[CountTest]
}
on columns,
{
([Product].[Category].[Category]
,[Product].[Subcategory].[Subcategory] -- comment this line for the second result
)
}
on rows
from [Adventure Works]
Now comment the indicated line for the parent view.

Related

How to access non-pivot data in a pivot measure in Excel

Excel - I have built a pivot table showing the number of projected transactions. I have changed my screenshot to make it a little easier to understand. I have total projected vehicle sales in a pivot table. I have another section of data which shows how many reps we have for each vehicle type. I have set up a relationship between these 2 objects. I want to create a measure (which I can then add to the pivot table) which divides the various numbers by the rep count... In effect I want each number in the cars section divided by 62, each number in the Trucks section divided by 39, and each number in the Motorcycles section divided by 34.
The code I am using is
=[Distinct Count of Opportunities] / LOOKUPVALUE(Table1[Reps], Table1[Vehicle Type]], [Vehicle Type])
To try to simplify, I am just using the 2nd part of the calculation...
=LOOKUPVALUE(Table1[Reps], Table1[Vehicle Type]], [Vehicle Type])
I am getting the error: The value for Vehicle Type cannot be determined. Either Vehicle Type doesn't exist or there is no current row for a column named 'Vehicle Type'.
What am I doing wrong here?

EXCEL CUBE functions, filter by slicer

I have two datasources as following:
Orders.csv
DepartmentID;Status;OrderID;Amount
1001;C;3;756,00
1002;B;4;45,00
1002;C;5;51,00
1003;A;6;321,00
1004;B;7;51,00
1004;C;8;21,00
Departments.csv
DepartmentID;DepartmentName;CostCenter
1001;Sales;10
1002;Accounting;20
1003;HR;30
1004;HQ;40
I have:
created a PowerPivot model with join on DepartmentID
defined a slicer Slicer_DepartmentName from the Departments table
defined a measure TotalAmount as SUM([Orders].Amount)
Now using Cube functions I want to get
CostCenter for DeparmentName selected by the slicer
Distinct statuses in Order table filtered by the slicer
The only solution I came up with are following
Cost Center:
CUBERANKEDMEMBER("ThisWorkbookDataModel";"EXISTS([Departments].[CostCenter].children,[Departments].[DepartmentName].[All].["&CUBERANKEDMEMBER("ThisWorkbookDataModel";Slicer_DepartmentName;1)&"])";1)
Statuses:
CUBERANKEDMEMBER("ThisWorkbookDataModel";"NONEMPTY([Orders].[Status].[ALL].children,([Measures].[TotalAmount],[Departments].[DepartmentName].[All].["&CUBERANKEDMEMBER("ThisWorkbookDataModel";Slicer_DepartmentName;1)&"]))";1)
changing the last parameter for the 1..3
I find my solution quite ugly and the "Statuses" part works only if there is only one DepartmentName selected in the slicer. Is there any better solution?

How to compare one row to others in DAX in Excel

I have this table which has foreign keys from several other keys:
Basically, this table shows which students registered in which module run by which teacher in what term.
I want to query the following:
How many students have registered for more than one module run by a given tutor?
It will look something like this:
For example, Vasiliy Kuznetsov runs two modules: FunPro and NO. If one student registers for both of them, he is counted as one.
My sql oriented mind is telling me this: Count all the rows in which student_id and tutor_id are the same. For example, in one row student_id is 5 and tutor_id is 10, and the same is true for the third row. Then, I count it as one.
How can I do that with DAX formulas?
RowCount:=
COUNTROWS( ModuleRegistration )
StudentsWithTwoOrMoreRegistrations:=
COUNTROWS(
FILTER(
VALUES( ModuleRegistration[Student_ID] )
,[RowCount] >= 2
)
)
I refer to arguments positionally, thus the first argument to a function is (1), the second (2), and so on.
So, [RowCount] is trivial.
[StudentsWithTwoOrMoreRegistrations] is a bit more involved. DAX, being a functional language, is best understood inside-out.
FILTER() takes a table expression in (1) and evaluates a boolean predicate, (2), for each row in (1). It returns all rows from (1) for which (2) evaluates to true.
Our FILTER()'s (1) is VALUES( ModuleRegistration[Student_ID] ). VALUES() returns the unique rows from a field based on current filter context (it respects slicers and filters in the pivot table). Thus, we will return some subset of the unique list of [Student_ID]s.
Our FILTER()'s (2) is [RowCount] >= 2. For each [Student_ID] in (1), we'll evaluate [RowCount], checking how many times that student appears in ModuleRegistration. [RowCount] is evaluated in the combination of filter context from the pivot table (the [Faculty Name] field in your sample pivot provides filter context) and row context from FILTER()'s (1). Thus it counts how many times the student appears in ModuleRegistration for the [Faculty Name] on the pivot table row.
We check that [RowCount] is >= 2.
You've not indicated if your measure needs to handle grand totals, or how you might want to see that. If you need more help for the grand total to get it to behave the way you like, let me know.
Edit for grand total
There are a few ways you might want to handle grand totals. I'm gong to assume that you want a unique count of students.
StudentsWithTwoOrMoreRegistrations:=
COUNTROWS(
SUMMARIZE(
FILTER(
SUMMARIZE(
ModuleRegistration
,ModuleRegistration[Tutor_ID]
,ModuleRegistration[Student_ID]
)
,[RowCount] >= 2
)
,ModuleRegistration[Student_ID]
)
)
WTF happened to our measure?
Let's examine:
Starting with the innermost SUMMARIZE(). SUMMARIZE() navigates relationships outward from the table in (1) and groups by the columns listed in (2)-(N) (these don't have to be from the table in (1), but must be reachable by navigating relationships).
This is equivalent to the following in SQL:
SELECT
mr.Tutor_ID
,mr.Student_ID
FROM ModuleRegistration mr
We use FILTER() on this table like earlier. [RowCount] is evaluated in the combination of filter context from the pivot table and the row in the table, defined by our SUMMARIZE() above.
Now our row context is instead of just a student, a student-tutor pair. This pair will have a [RowCount] >= 2 when the student has taken more than one module from a tutor.
Our FILTER() returns the pairs which have a [RowCount] >= 2. This output table has two fields, [Tutor_ID] and [Student_ID], but we want to count distinct [Student_ID]s out of this.
Thus, we use the table from FILTER() as our (1) in the outer SUMMARIZE(). We group only by the values of [Student_ID]. We then count the rows of this table.
When only one [Faculty_Name] is in context, e.g. on a pivot table row, then our inner SUMMARIZE() is grouping by a single value of [Tutor_ID] and whatever [Student_ID]s are associated with it. This is identical to our earlier measure.
When we have many [Tutor_ID]s in context, like in the grand total, then we'll see the appropriate behavior of only counting each [Student_ID] once.

Power pivot named MDX field

I have a PowerPivot Data Model in Excel 2013. There are several measures that I have grouped into a named set using MDX - something like this:
{[Measures].[Sum of Value1],
[Measures].[Sum of Value2],
[Measures].[Sum of Value3]}
By using this named Set, I can place multiple measures on the rows or columns of an Excel PivotTable in a single action. My question is, is there any way using MDX (or DAX in the PowerPivot screen when working with the individual measures) to filter out or hide the entire set based on a single measure value (whether that measure is included in the set or not)? Preferably, I'm looking for a way to do this without including another member in the set (I.e. Not a measure).
Ror example, if the Sum of Value3 in the above example was zero, I'd want the entire set to be hidden from the pivot table.
I know I could edit the DAX in the Data Model to return BLANK() for each measure included in the set based on the value of another measure, but there may be times I want to show those measures in all cases. This would require writing at least 2 measures for every one I have now which I don't like the thought of doing.
UPDATE:
Sourav's answer looks great, but unfortunately won't work in my particular scenario, I believe, because I'm using the "Create Set using MDX" function (under the Manage Sets option in the Fields, Items, & Sets ribbon menu) within Excel. It will only let me write the MDX as:
IIF([Measures].[Sum of Value3]=0,
{},
{[Measures].[Sum of Value1],[Measures].[Sum of Value2],[Measures].[Sum of Value3]})
And once I add that new set to the PivotTable, it will still display all 3 measures for any members where [Sum of Value3] is 0.
I think I'm going to have to find an approach using DAX and the Excel Data Model measures.
UPDATE 2:
Below is a screenshot to help illustrate. Keep in mind the data source in my example is not an external cube, it's simply an Excel file linked in the Data Model against which MDX queries (with limitations?) can be run. In this example, I would like the set to return only Rows A and C because Sum of Value3 is not zero. However, as you can see, all rows are being returned. Thanks!
You can't choose to hide/unhide members/sets on the fly. Instead, you can use IIF to conditionally return an empty set
WITH SET MyNamedSet AS
IIF([Measures].[Sum of Value3] = 0,
{},
{[Measures].[Sum of Value1],[Measures].[Sum of Value2], [Measures].[Sum of Value3]}
Working example in AdventureWorks for #whytheq(DISCLAIMER - Cube was created by me for testing purposes)
with set abc as
iif([Measures].[Fact Internet Sales Count]>34229,
{
[Measures].[Fact Internet Sales Count],
[Measures].[Extended Amount - Fact Internet Sales]
},
{}
)
SELECT
abc
on 0
from [AdventureWorksDW]
where [Due Date].[Year].&[2004]
As you can see, the scope IS changing the results.
An alternative would be to create a dummy measure that returns null or 1 depending on your [Measures].[Sum of Value3]. Then multiply all other target measures by this dummy measure.
Here is an example of you scenario in AdvWrks:
SELECT
[Product].[Product Categories].[Category].[Components] ON 0
,{
[Measures].[Internet Sales Amount]
,[Measures].[Sales Amount]
,[Measures].[Standard Product Cost]
,[Measures].[Total Product Cost]
} ON 1
FROM [Adventure Works];
Returns this:
Adding the dummy measure and amending the other measures:
WITH
MEMBER [Measures].[isItZero] AS
IIF
(
[Measures].[Internet Sales Amount] = 0
,null
,1
)
MEMBER [Measures].[Sales Amount NEW] AS
[Measures].[Sales Amount] * [Measures].[isItZero]
MEMBER [Measures].[Standard Product Cost NEW] AS
[Measures].[Standard Product Cost] * [Measures].[isItZero]
MEMBER [Measures].[Total Product Cost NEW] AS
[Measures].[Total Product Cost] * [Measures].[isItZero]
SELECT
NON EMPTY //<<<<this is required
{
[Measures].[Internet Sales Amount]
,[Measures].[Sales Amount NEW]
,[Measures].[Standard Product Cost NEW]
,[Measures].[Total Product Cost NEW]
} ON 0
,{} ON 1
FROM [Adventure Works]
WHERE
[Product].[Product Categories].[Category].[Components];
Now this returns:
EDIT
According to your latest edit please just try this (I'm assuming you're using Excel 2013):
Create two new measures to replace two of the existing ones:
Name: "Sum of Value1 NEW"
Definition:
IIF
(
[Measures].[Sum of Value3] = 0
,null
,[Measures].[Sum of Value1]
)
Name: "Sum of Value2 NEW"
Definition:
IIF
(
[Measures].[Sum of Value3] = 0
,null
,[Measures].[Sum of Value2]
)
Now use only these three measures in your pivot and just use the ID dimension in a normal way on rows i.e. do not use the custom set you have already tried.
[Measures].[Sum of Value1 NEW]
[Measures].[Sum of Value2 NEW]
[Measures].[Sum of Value3]
Has ID B should now disappear?

Excel pivot table calculated field total returns unexpected value

I have an Excel spreadsheet which has a pivot table on it. The data itself is quite simple, Number of Units and a Discount (percentage from 0 to 100), pivoted on date across the top and customer down the left hand side. Those numbers are straight from a SQL view, so the pivot table source is just:
SELECT * FROM UnitDiscountView
All was looking fine until I attempted to add a calculated field of TotalCost (Each unit will costs £200) to the pivot table:
= (200 *NrUnits ) * ((100-Discount)/100)
The total at the bottom was negative, and vastly more than I was expecting as a number. If I select all the cells, then the sum which appear in the status bar at the bottom is what I would expect, but the Total field at the bottom is over a hundred times bigger, and negative to boot.
I am stumped. I have searched since Friday without finding anything which will help me to solve this. Any pointers on where to start looking for the solution would be greatly appreciated. I should mention that SQL is my forte, not Excel. I haven't used Excel's Pivot tables before last week, so I am probably missing something really obvious.
Calculated fields will work with the totals:
200 * (Sum of NrUnits) * ((100 - [Sum of Discount]) / 100 )
So for your total row, if Sum of Discount is greater than 100 (adding up all the Sums of Discount on the pivot table), the part of your formula (100-Sum of Discount) will be returning a negative number, hence the negative value.
What I normally do is to add another column to the table to the right of the values returned from the query. I will add my formulas there, then do the pivot table on the resized table.
If you have formatted the returned SQL query as a table (or list in Excel 2003), the pivot table source range should even resize by itself.
I found the answer.
Excel was effectively doing this for the total:
= (200 * sum(NrUnits)) * ((100-sum(Discount))/100)
Which isn't even close to what I wanted:
= sum((200-NrUnits) * ((100-Discount) * 100)))
I got round it by changing the SQL from the view to be:
SELECT *, NrUnits*((100-Discount)*100) AS EffectiveUnits
FROM UnitDiscountView
And the Calculated field to:
= EffectiveUnits * 200

Resources