I have a simple powerpivot model with a datetable and a milestone table.
shown in the figure. The milestone table has columns of milestone forecast and actual dates, eventually for six major milestones but two are shown. I am able to summarize (calculated field) the COUNT of forecasted or actual milestone events by week and year. But I cannot see how to also generate a cumulative total (YTD) of these counts - probably missing something that should be obvious.
The two calculated fields that work are:
MS1 YTD Forecast:=CALCULATE(COUNT([Forecast MS1 Date]))
MS1 YTD Actual:=CALCULATE(COUNT([Actual MS1 Date]), USERELATIONSHIP(milestones[Actual MS1 Date],datetbl[Date]))
The pivotchart of this shows
Eventually I would like to create a report showing the progress for each milestone (actual vs forecast) for this project.
I have a partial answer. Added 'helper columns' with a 1 or 0 based on existence of a date. THEN used Javier Guillen's "Running Totals" post (https://javierguillen.wordpress.com/2012/11/28/running-total-techniques-in-dax/) to create the lines.
But I get a syntax error when I attempt to apply the DAX Cumulative pattern to FILTER for valid dates. My measure is:
Cumulative MS1 Actual :=
IF (
MIN ( 'datetbl'[Date] )
<= CALCULATE ( MAX (milestones[Actual MS1 Date] ), ALL (milestones) ),
CALCULATE (
SUM (milestones[MS1 Actual exists] ),
USERELATIONSHIP(milestones[Actual MS1 Date],datetbl[Date]),
FILTER (
ALL ( 'datetbl'[Date] ),
'milestones'[MS1 Actual Date] <= MAX ( 'milestones'[MS1 Actual Date] )
)
)
)
I am getting a semantic error 'column 'MS1 Actual Date' in table milestones cannot be found or may not be used in this expression.
unfortunately I cannot seem to post the updated chart or datamodel
Related
I have Cartons table, which contains two datatime columns - entering warehouse date and exiting warehouse date. For my report i need to calculate table which shows how many cartons are in the warehouse at the end of the each day. My idea was get number of cartons for each date which have entering date lower than current date and exiting date higher than current date. So i need to translate following sql into dax:
SELECT d.date, COUNT(c.Id) AS 'Count of cartons' FROM #dim d
INNER JOIN Inventory.Cartons c on d.date between c.EnteringWarehouseTime and c.ExitingWarehouseTime
GROUP BY d.date
ORDER By d.date
Where dim is table with all dates.
But all joins in dax can be performed only using relations. I can only make cross join of these tables and filter result, but this operation would take to much time. Do i have another options for this?
Actually you can simulate a relationship with dax. However, if I understand correctly your questions and the datamodell, you want to query all cartons that are still in the warehouse at a given time, right? For each day in the Date table you can calculate that how many rows in the Carton table are by filtering it by the currently iterated Day. So this formula calculates:
For each day in the date table - VALUES('Date') -, will calculate how many rows in the Cartons table present used some filtering - COUNTROWS('Cartons') -. And the filtering works like this: On the current value of the Day - think as a foreach in C# - it will check that how many rows are in the Cartons table present where it's Exiting date is higher or equal than the current Date's value in the iteration, and Enter date is lower the the current date, or it is BLANK() - so still in the warehouse.
CALCULATETABLE(
ADDCOLUMNS(
VALUES('Date'),
"Cartons",
CALCULATE(
COUNTROWS('Cartons'),
FILTER(
'Cartons',
'Cartons'[EnteringWarehouseTime] <= 'Date'[Date]
),
FILTER(
'Cartons',
OR('Cartons'[ExitingWarehouseTime] >= 'Date'[Date],ISBLANK('Cartons'[ExitingWarehouseTime])
)
)
)
)
This is very similar to the "Open orders" pattern. Check out daxpatterns.com
If you want to simulate a relationship you can always use the COUNTROWS() > 0 pattern as a filter.
Like if you want to do a SUM(Value) on your main table, but only for those rows that are present in the Referenced table - without relationship:
CALCULATE(
SUM('MainTable'[Value]),
FILTER(
'MainTable',
CALCULATE(
COUNTROWS('ReferencedTable'),
'ReferencedTable'[PK] = 'MainTable'[FK]
) > 0
)
)
I am trying to create dynamic Time Intelligence in SSAS Tabular similar to traditional OLAP Time Intel.
Additionally, I need Time Intelligence that can handle two sets of date hierarchies. For example, a Transmission Date and an Activity Date.
For example, I am trying to create a simple year-to-date sum of gross sales given that the user has selected two filters in an Excel pivot table. We are talking about all dates of transmission but only from the point of view of a single activity date. That is, I want to view 2016 total sales as if it were today, but also as if it were last month (i.e. as of a month ago, what did sales look like?).
An additional caveat is that I need two special calendars: a radio broadcast calendar for the transmission period and a traditional gregorian for the activity period.
I have started here:
YTD :=
IF (HASONEVALUE ( Dates[Years-Bcast] ),
CALCULATE (
SUM ( Sales[Sales Amount] ),
FILTER (
ALL( Dates ),Dates[Years-Bcast] = VALUES ( Dates[Years-Bcast] )
&& Dates[DatesKey] <= MAX ( Dates[DatesKey] )
)
),
BLANK ()
)
The problem I assume is my filter; I really want the last FILTER clause to be:
&& Dates[ActivityDateKey] <= MAX ( Dates[DatesKey] )
The activity date would be a user-defined report filter. It seems I need 2 filters. The first filter is filtering out only the applicable transmission dates I need, so then my activity date filter is pointless.
Any help would be greatly appreciated.
this might be what you're looking for..
KEEPFILTERS - https://msdn.microsoft.com/en-us/library/hh758426.aspx
I am trying to apply a measure value calculated at the Month level to a dimension contained within that month i.e.
Should look like this:
I've attempted to use a scoping statement so far but with no luck.
SCOPE (
{[Sale].[Sale Year].&[2]:[Sale].[Sale Year].&[7]}
,[Date].[Calendar Month].&[201603]
,[Measures].[Costs Per Sale] );
THIS = ([Date].[Calendar Month].&[201603],[Measures].[Costs Per Sale]);
END SCOPE;
The Aggregated Sales measure is calculated using the Sale Year which unfortunately has not and cannot be linked to the Cost dimension.
Does anyone know how I can apply the Cost Per Sale monthly value to the [Sale].[Sale Year] dimension?
Thanks
Try this -
SCOPE ({[Sale].[Sale Year].&[2]:[Sale].[Sale Year].&[7]} ,[Measures].[Costs Per Sale]);
THIS = ([Sale].[Sale Year].[All],[Measures].[Costs Per Sale]);
END SCOPE;
Let's assume i have easy table with sales data like:
id shop
id product
date
amount
Can you help me to write MDX query for calculated member to get current period sales ratio to same period of previous year?
For example, if month or quarter selected as one of dimensions.
Let's assume you've a [Time] dimension with [Year], [Month] and [Day] levels.
If
SELECT
[Time].[Jan 2015]:[Time].[Dec 2015] on 0,
[Measures].[Sales] on 1
FROM
[Cube]
Returns the sales for all months of 2015. We can add a calculated measure to get ratio :
WITH
MEMBER [Sales Ratio] AS DivN(
[Sales],
( ParallelPeriod( [Time].[Year], 1, [Time].current ), [Sales] )
SELECT
[Time].[Jan 2015]:[Time].[Dec 2015] on 0,
{[Sales],[Sales Ratio]} on 1
FROM
[Cube]
DivN is icCube specific and allows for dividing being 'empty' safe.
ParallelPeriod is a standard MDX function, that returns previous years month. You could also use Lag(-12), that is 'travelling' backwards in a level 12 times.
current (aka Currentmember) is also standard MDX and allows for retrieving the current value of a hierarchy/ dimension.
In icCube I'd add a function to navigate to the previous year so you can reuse it (and fix one if needed). Like :
WITH
FUNCTION timePrevYear(t_) AS ParallelPeriod( [Time].[Year], 1, t_ )
MEMBER [Sales Ratio] AS DivN(
[Sales],
( timePrevYear( [Time].current ), [Sales] )
SELECT
[Time].[Jan 2015]:[Time].[Dec 2015] on 0,
{[Sales],[Sales Ratio]} on 1
FROM
[Cube]
It's going to be a bit too much but eventually you could add this kind of calculations in what we call in MDX Utility or Stats dimension, so you can even let the end-user select this in a dropdown from a reporting tools. More on this here.
In the models I create for my clients, I sometimes take another route as ic3 has suggested:
Especially when there will be lots of additional calculations on top of these (e.g. year-to-date, inception-to-date, month-to-date etc).
This is:
load the same facts data again, but set as the "load date" the "date" - 1 year (e.g. mySQL: DATE_ADD(,INTERVAL -1 YEAR).
Advantages:
drill through on history is possible
lots of formulas can be added "on top" of these, you always know that the basics are ok
My situation is as following:
This is a Powerpivot solution developed in Excel 2013 (32-bit).
I got a transaction table containing transactions with an amount, a category and a posting date. What I would like to to is to present a number of different calculations depending on the time frame.
Sum of amount of current day of import (all the transations with the latest posting date available).
Sum of amount Month-to-date (the current month of the latest transaction)
Sum of amount same period last month (Month-to-date minus one month)
Sum of amount last month (the totals for whole last month)
So, idea is to create a "Current day" measure as a stand point for all the other measures.
[Current day] = LASTDATE('TransactionTable'[Posting Date])
Before summarizing things I wanted to create measures that would represent the start and end date for each period (to display in the report and to make easier measures), this is where I run into trouble.
[First day of current month] = STARTOFMONTH([Current Day])
Gives me the error: "A function 'CALCULATE' has been used in a True/False expression that is used as a table filter expression. This is not allowed."
And with this I would like to end up with something like this for current month:
[Sum of amount current month] = CALCULATE(SUM('Transactiontable'[Amount]);DATESBETWEEN('DateTable'[Date]; [First day of current month];[Current day]))
And this for previous month total:
[First day of previous month] = DATEADD([First day of current month];-1;MONTH)
[Last day of previous month] = EOMONTH([Current day];-1)
CALCULATE(SUM('Transactiontable'[Amount]);DATESBETWEEN('DateTable'[Date]; [First day of previous month]; [Last day of previous month]))
It feels like I am not using the measures the "right" way... Basically I want to create dynamic measures that will change the timeframe depending on what the latest posting date is in the transaction table. Is this the way to go at all?
Thanks guys,
First you need to use ALL()
You were pretty close - the trick to getting [CurrentDate] right is use of the ALL() function. This handy function overrides any filter conditions you have.
So let's look at your [CurrentDate] measure that uses LASTDATE('TransactionTable'[Posting Date]). If your pivot table has months as row labels, this will happen:
The row context alters the output of [CurrentDate]. Not what we want. So you need to override the filter condition, like this.
[CurrentDate] = CALCULATE(LASTDATE(TransactionTable[Posting Date])
,ALL(TransactionTable)
)
Then you need FILTER()
Then to sum the amount for [CurrentDay] we do this:
[SumAmountCurrentDay] = CALCULATE([SumAmount]
,FILTER(TransactionTable
,TransactionTable[Posting Date]=[CurrentDay]
)
)
We need to use FILTER() because it's a more complicated criteria than CALCULATE can handle by default. FILTER() explicitly tells CALCULATE() which table it needs to filter on - although it might be obvious to us, it isn't to PowerPivot.
Here are the rest of the formulas you need, of varying complexity but mostly reusing functions you've listed above, plus ALL() and FILTER().
[FirstDayOfCurrentMonth]
=CALCULATE(STARTOFMONTH(TransactionTable[Posting Date])
,ALL(TransactionTable)
,FILTER(TransactionTable
,TransactionTable[Posting Date]=[CurrentDay]
)
)
[SumAmountCurrentMonth]
=CALCULATE([SumAmount]
,DATESBETWEEN(DateTable[Date]
,[FirstDayOfCurrentMonth]
,[CurrentDay]
)
)
[FirstDayOfPrevMonth]
=CALCULATE(STARTOFMONTH(TransactionTable[Posting Date])
,ALL(TransactionTable)
,FILTER(TransactionTable
,TransactionTable[Posting Date]=
CALCULATE(dateadd(LASTDATE(TransactionTable[Posting Date])
,-1
,month
)
,ALL(TransactionTable)
)
)
)
[LastDayOfPrevMonth]
=CALCULATE(ENDOFMONTH(TransactionTable[Posting Date])
,ALL(TransactionTable)
,FILTER(TransactionTable
,TransactionTable[Posting Date]=
CALCULATE(dateadd(LASTDATE(TransactionTable[Posting Date])
,-1
,month
)
,ALL(TransactionTable)
)
)
)
SumAmountPrevMonth
=CALCULATE([SumAmount]
,DATESBETWEEN(DateTable[Date]
,[FirstDayOfPrevMonth]
,[LastDayOfPrevMonth]
)
)