I am trying to calculate the variance of projects, over different periods.
Periods are referenced as P1, P2,...
The user should be able to pick the periods that they want to compare and see the projects listed
new table
I have tried a dax formula, but I can't find one that has more than one filter.
My DAX:
Variance =
VAR DIFF =
WIP[WIP]
- CALCULATE (
SUM ( WIP[WIP] ),
FILTER ( 'WIP', WIP[Index1] = EARLIER ( WIP[Index] ) )
)
RETURN
IF ( DIFF = VALUE ( WIP[WIP] ), 0, DIFF )
Can you help?
2nd table
Variance =
VAR currentPeriod = SELECTEDVALUE('tbl'[Period])
VAR currentObj = SELECTEDVALUE(tbl[Object])
VAR firstPeriodInSelection=
CALCULATE(
MIN('tbl'[Period])
,'tbl'[Object]=currentObj
,ALLSELECTED('tbl'[Period])
,ALLEXCEPT(tbl,tbl[Period],tbl[Object])
)
VAR prevPeriod =
CALCULATE(
MAX('tbl'[Period])
,'tbl'[Period]<currentPeriod
,'tbl'[Object]=currentObj
,ALL()
)
VAR currentWIP =
CALCULATE(
AVERAGE(tbl[WIP])
,ALLEXCEPT(tbl,tbl[Object],tbl[Period])
)
VAR prevWIP =
CALCULATE(
AVERAGE(tbl[WIP])
,ALLEXCEPT(tbl,tbl[Object])
,'tbl'[Period]=IF(
prevPeriod < firstPeriodInSelection
,firstPeriodInSelection
,prevPeriod
)
)
RETURN
currentWIP-prevWIP
Please, pay attention that on my picture you can see 2 values for one period-object. For this case I used average. So, if it will be one value for period-object then you see the value, if it will be several then you will see calculated Variance for average.
Related
Please help to calculate/understand properly lastDate and rankDate measures for following simplified example (download):
Desired result:
Reality (incorrect subtypes):
Why relationship is broken?
How to avoid this cartesian product lines?
My Measure (I commented workaround, because it's kind of postfilter, not prefilter):
rnkDate =
VAR t =
CALCULATETABLE(
VALUES(tstTable[Date]),
REMOVEFILTERS(tstTable[Date])
)
RETURN
//IF( MAX(tstTable[Amount])<>BLANK(), // WORKAROUND To hide unwantedd rows
RANKX(
t,
LASTDATE(tstTable[Date])
)
//)
P.S. Mess happens only if I use fields from dimensional table dimType[Type] (within one table everything is Ok):
The problem is that the query generated by Power BI performs the cartesian product and filers the result by checking the result of the measure.
in our case is something similar to
SUMMARIZECOLUMNS(
'dimType'[Type],
'tstTable'[subType],
'tstTable'[Date],
"MinAmount", CALCULATE(MIN('tstTable'[Amount])),
"lastDate", 'tstTable'[lastDate],
"rnkDate", 'tstTable'[rnkDate]
)
SUMMARIZECOLUMNS doesn't use relationships when iterating on different tables, it applies them when evaluating the measures. There is an article explaining what is the equivalent DAX code executed by SUMMARIZECOLUMNS
Introducing SUMMARIZECOLUMNS
the problem is that RANKX evaluated on an empty table retuns 1. This can be seen executing this on dax.do
EVALUATE
VAR t =
FILTER ( ALL ( 'Date'[Date] ), FALSE )
RETURN
{ RANKX ( t, [Sales Amount] ), CALCULATE ( [Sales Amount], t ) }
so the solution is to first check that the table t is not empty, which is the reason because the workaround that you implemented solved the issue
lastDate =
IF( NOT ISEMPTY(tstTable), // checks fact table in particular context
CALCULATE(
LASTDATE(tstTable[Date]),
REMOVEFILTERS(tstTable[Date])
)
)
rnkDate =
VAR t =
CALCULATETABLE(
VALUES(tstTable[Date]),
REMOVEFILTERS(tstTable[Date])
)
RETURN
IF( NOT ISEMPTY(tstTable),
RANKX(
t,
LASTDATE(tstTable[Date])
)
)
I'm trying to calculate the Total Price per Order number. It specifically needs to be a column, because I'll be needing it for further calculations.
Can someone help me write code that calculates the total per Order Number, instead of line amount as it does now?
Since it's a calcualted column, just avoiding any context transition gives a straightforward solution
Total Price Per Order =
VAR CurrentOrder = SalesDetail[Order Number]
RETURN
SUMX (
FILTER (
SalesDetail,
SalesDetail[Order Number] = CurrentOrder
),
SalesDetail[Unit Price] * SalesDetail[Quantity]
)
Table 1 (Combined Hours) I have a list of [payweek], which is many repeated
Table 2 (All Scripts), I have a list of jobs and two dates, [Scripting Date] and [R4PreScriptDate]
I am trying to find the number of unique [payweek]s between the [Scripting Date] and the [R4PreScriptDate]
The DAX formula is below. My result is always 3. However, I am expecting variable answers (0,1, 2,3,4 or 5)
R4PreScriptWkCt = CALCULATE(DISTINCTCOUNTNOBLANK(CombinedHours[payWeek]),FILTER(CombinedHours,
CombinedHours[payWeek] <= MAX (AllScripts[Scripting Date] )
&& CombinedHours[payWeek] >= MAX (AllScripts[R4PreScriptDate] ) ))
Thank you,
I assumed that both tables are related by Job Number. I created the following measure:
R4PreScriptWkCt =
VAR __date2 = MAX ( AllScripts[R4PreScriptDate] )
VAR __date1 = MAX ( AllScripts[Scripting Date] )
VAR __job = MAX ( AllScripts[Job Number] )
VAR __subTable =
FILTER (
CombinedHours,
CombinedHours[Job Number] = __job
&& CombinedHours[Week] >= __date1
&& CombinedHours[Week] <= __date2
)
RETURN
CALCULATE ( DISTINCTCOUNTNOBLANK ( CombinedHours[Week] ), __subTable )
Hope it helps you.
I've got about 20 different metrics across 10 locations and want to make a matrix with metrics as rows and the locations as the different columns. The issue I'm running into is that the metrics are different data types, some are whole numbers, some are %s and some are $s.
Is there any way to custom format each row as a different data type like there is in excel?
Edit: Sorry I wasn't clear. I don't want the same value showing up multiple times.
See below screenshots.
Test Data Screenshot:
What I want, but I want it in Power BI, not Excel:
What I don't want when I use measures that are formatted as different data types:
The formatting is not controlled by the rows or columns but rather each measure can be assigned its own data type using the Modeling tab.
Edit: I see a few options here.
Option 1: Write a text measure that switches formats like this:
FormatMetric =
VAR Val = SUM ( TestData[Value] )
RETURN
SWITCH (
SELECTEDVALUE ( TestData[Metric] ),
"# quantity", FORMAT ( Val, "0" ),
"$ Sales", FORMAT ( Val, "$0.00" ),
"% to plan", FORMAT ( Val, "0%" )
)
You'll get a table that looks like this:
Be aware that this measure returns text values and won't work in a chart.
Option 2: Create three separate measures and format each separately:
# quantity = CALCULATE ( SUM ( TestData[Value] ), TestData[Metric] = "# quantity" )
$ Sales = CALCULATE ( SUM ( TestData[Value] ), TestData[Metric] = "$ Sales" )
% to plan = CALCULATE ( SUM ( TestData[Value] ), TestData[Metric] = "% to plan" )
If you make sure you have Format > Values > Show on rows turned on and put these three measures in the Values box:
These measures can be used in charts.
Option 3: Pivot your data table on the Metric column in the query editor so you don't have mixed data types in a single column. Your data table should look like this now:
From here, you can write three simple measures format as in the previous option:
# quantity = SUM ( Pivot[# quantity] )
$ Sales = SUM ( Pivot[$ Sales] )
% to plan = SUM ( Pivot[% to plan] )
I have the following which seems to function ok but looks like I might have done my usual trick of not keeping as simple as possible - what is the elegant version of this measure?
Num Users for Current Month =
VAR
MaxMonth = MONTH(LASTDATE(ALL('Date'[Day Marker])))
VAR
MaxYear = YEAR(LASTDATE(ALL('Date'[Day Marker])))
RETURN
CALCULATE(
[Num Users]
,FILTER(
'Date',
MONTH('Date'[Day Marker]) = MaxMonth
&&
YEAR('Date'[Day Marker]) = MaxYear
) )
With this code you are not selecting the current month. You are selecting the last available month in your selection of dates.
I would rather expand my date table with an extra field: IsCurrentMonth:
IsCurrentMonth =
IF (
YEAR ( Date[Date] ) = YEAR ( TODAY () )
&& MONTH ( Date[Date] ) = MONTH ( TODAY () ),
"Yes",
"No"
)
Then you measure can be rewritten towards:
CALCULATE([Num Users], Date[IsCurrentMonth]="yes")