I’m trying to compute the difference between (budget) allocations and expenditures.
At first glance, this seems easy to do with a simple measure:
Balance = SUM(Register[AllocationAmount]) – SUM(Register[TransactionAmount])
However, there’s an extra rule to factor in: Transaction amounts dated prior to the first allocation should be ignored. Measure Balance gets more complex to accommodate this:
Balance = CALCULATE(
SUM(Register[AllocationAmount]) - SUM(Register[TransactionAmount]),
FILTER(Dates,
Dates[Date] >= FIRSTDATE(Category[InitialAllocationDate])
&& NOT ISBLANK(FIRSTDATE(Category[InitialAllocationDate]))
)
)
Unfortunately, Balance doesn't add up correctly when used to compute totals up a hierarchy in the Category table. This makes sense. When Balance is evaluated up the hierarchy, FIRSTDATE(Category[InitialAllocationDate]) in the date filter pulls the first date out of all dates associated with all Category rows in context at that higher level and then uses this date to apply the filter once for the entire grouping.
This is incorrect. In order to produce an accurate total, the filter needs to be applied on a per-Category basis so that filtering factors in each category's InitialAllocationDate. To achieve this, I changed Balance so that it computes only when a single Category[Name] filter is applied (i.e. no hierarchy grouping is taking place). Then, I created a separate measure that uses SUMX to evaluate Balance on a per-Category row basis.
Balance = IF (HASONEFILTER(Category[Name])),
CALCULATE(
SUM(Register[AllocationAmount]) - SUM(Register[TransactionAmount]),
FILTER(Dates,
Dates[Date] >= FIRSTDATE(Category[InitialAllocationDate])
&& NOT ISBLANK(FIRSTDATE(Category[InitialAllocationDate]))
)
)
)
CumulativeBalance = SUMX(Grouping, Register[Balance])
This produces correct totals up Category's hierarchy (yay!); however, it requires two measures.
Question
Is there a way I can eliminate the second measure (CumulativeBalance) and instead somehow adjust Balance so that it computes correctly up the hierarchy?
Related
Looked around a long time now, and cannot find a way to conditionally format the values in a table, treemap, bar chart etc. if they are within the say, top 80% of all the values.
So let's say I have a table with sales and profit. Then I have a treemap showing the profit by city. I manage to get the percentage of total with:
% of total profit = SUM(Orders[Profit])/CALCULATE(SUM(Orders[Profit]),ALL(Orders))
..so that is no issue. But how would I go about formatting the cities that are within the top 80% of all profit? Any suggestion on approach?
Example:
Say I have the treemap below. The first four categories would fall within the top 80% of the total. Cumulatively it would be: 35%, 55%, 70% and 85%. So my need is to color only these in a specific way (and preferably any that falls outside of that range, in another color).
I take it that finding the logic to do this, likely though a measure somehow to base the formatting on, will then also be something that would be applicable to bar charts etc. (more traditional pareto).
OK, here is the solution. I will provide a traditional pareto and an adapted one according to your requirements. My data looks like this.
Create 3 measure as follows:
1
Profit Measure = SUM('Table'[Profit])
2
Pareto =
VAR amount = [Profit Measure]
VAR total = CALCULATE( [Profit Measure], REMOVEFILTERS('Table'))
VAR result = CALCULATE([Profit Measure], FILTER(ALL('Table'),[Profit Measure]>= amount))/total
RETURN result
3
Threshold =
VAR pareto = [Pareto]
VAR previousPareto = MAXX( FILTER( SUMMARIZE(ALL('Table'),'Table'[Order],'Table'[Profit],"p", [Pareto]), [p] < pareto), [Pareto])
RETURN IF( ISBLANK( previousPareto), pareto, previousPareto)
Create a table visual so you can see what is happening. In the table below, the Pareto measure is creating a cumulative percentage based on profit. If you were to use this, you can see that only A and B are cumulatively the only values actually < 80% and so they would be the only ones coloured. What you are asking for is slightly different which is what the threshold measure is showing. This outputs the previous pareto (or current if there is no previous).
In the tree map, I have created the conditional formatting as follows for standard pareto.
And as follows for the adapted pareto.
Click the fx icon under colors.
Select Rules for Format style, your measure as the field and then set up a rule (in your case, >= 0.2 for top 80%).
I’m wondering if there is a way, in a table, to calculate the percentage over a grand total.
I think this is a fairly simple issue, but I really can't wrap my head around it.
I have a table with a count, divided into different Categories:
I also have several slicers:
What I would like the table to show is the percentage of the current selection over the grand total, while keeping at least other two filters set (the Year(Anno) and another one set on the entire page).
If I select in the slicer “Range Scostamento %” a value, the table will obviously update the numbers:
The value I’m looking for is the “weight” in percentage of the filtered values over the total value.
So for example, for the first row I will have 317/14.793 = 0,0214 = 2,14% and so on.
I think my question has something to do with the SELECTEDVALUE/ALLSELECTED, maybe KEEPFILTERS, but I really don’t know how to make it work.
Thanks in advance!
Alessia
If I understand your requirement correct, you need these below measures for your purpose-
contratti = count(table_name[column_name])
grand_total =
CALCULATE(
count(table_name[column_name]),
ALL(table_name)
//-- ALL will return count of entire table
//-- you can use ALLSELECTED if you wants the
//-- grand_total for filtered data based on slicer
)
percentage = [contratti] / [grand_total]
Basically, I’d like to get one entity totals, but calculated for another (but still related/associated!) entity. Relation type between these entities is many-to-many.
Just to be less abstract, let’s take Trips and Shipments as mentioned entities and Shipments’ weight as a total to be calculated.
Calculating weight totals just per each trip is pretty easy task. Here is a table of Shipments weights:
We place them into some amounts of trucks/trips and get following weight totals per trip:
But when I try to show SUM of Trip weight totals (figures from 2nd table) per each related Shipment (Column from 1st table), it becomes much harder than I expect.
It should look like:
And I can’t get such table within Power BI.
Data model for your reference:
Seems like SUMMARIZE function is almost fit, but it doesn’t allow me to use a column from another table than initialized in the function:
Additional restrictions:
Selections made by user (clicks on cells etc.) should not affect calculation anyhow.
The figures should be able to be used in further calculations, using them as a basis.
Can anyone advise a solution? Or at least proper DAX references to consider? I thought I could find a quick answer in DAX reference guide on my own. However I failed to find a quick answer.
Version 1
Try the following DAX function as a calculated column inside of your shipments table:
TripWeight =
VAR tripID =
RELATED ( Trips[TripID] )
RETURN
CALCULATE (
SUM ( Shipments[ShipmentTaxWeightKG] );
FILTER ( Shipments; RELATED ( InkTable[TripID] ) = tripID )
)
The first expression var tripID is storing the TripID of the current row and the CALCULATE function gets the SUM of all of the weight for all the shipments that belong to the current trip.
Version 2
You can also create a calculated table using the following DAX and create a relationship between the newly created table and your Trips table and simply display the weight in this table:
TripWeight =
GROUPBY (
Shipments;
Trips[TripID];
"Total Weight KG"; SUMX ( CURRENTGROUP (); Shipments[ShipmentTaxWeightKG] )
)
Version 3
Version 1 and 2 are only working if the relationship between lnkTrip and Shipment is a One-to-One relationship. If it is a many-to-one relationship, the following calculated column can be created inside of the Trips table:
ShipmentTaxWeightKG by Trip = SUMX(RELATEDTABLE(Shipments); Shipments[ShipmentTaxWeightKG])
hope this helps.
I have a table called Conditions which links to a table called Agreement, relationship on AgreementID.
In Conditions, I have two measures already pre-calculated in the model called Margin Pct-EOP and Minimum Pct-EOP which return a value based on the filter context.
I have created measure in Power BI called InterestRateFloorBoolean which returns true if those measures don't match.
InterestRateFloorBoolean = if('Conditions'[Margin Pct-EOP] <> 'Conditions'[Minimum Pct-EOP],true,false)
If that measure returns true, then a subsequent measure called InterestRateFloorAmount runs the below calculation (a simple floored subtraction).
if([InterestRateFloorBoolean] = true,floor([Minimum Pct-EOP] - [Margin Pct-EOP],0.01),BLANK())
At a row level, the desired output is returned, blank() showing where the Margin/Minimum measures match. However, the Total runs an average of 2 AgreementID entries as ID 3236 does have Margin and Minimum values. ID 3336 is excluded as it does not have any entries.
I get that blank() is not the same as null and is essentially being treated like a 0 for the purposes of the Total (average). How can I construct my InterestRateFloorAmount measure so that when the total is averaged it does not include any blank() values?
Current output by way of illustration, the Total for InterestRateFloorAmount should be 4.00% (the percentage is a format):
This is due to calculation context and how the two measures [Margin Pct-EOP] and [Minimum Pct-EOP] are calculated.
Because in the context of the the total line the calculation it ignores the context of the previous lines. Hence InterestRateFloorAmount compares the two measures in the IF-statement:
InterestFloorAmount =
IF(
[InterestRateFloorBoolean] = true,
floor([Minimum Pct-EOP] - [Margin Pct-EOP], 0.01),
BLANK()
)
however in the context of Total the two measures evaluate to 4.20% and 2.20% (these, I assume, are calculated like (2.25+6.15)/2 and (2.25+2.15)/2 respectively). Thus
InterestFloorBoolean evaluates to TRUE and therefore InterestRateFloorAmount calculates 4.20%-2.20% and you end up with 2.00%.
I have the following tables & relationships in our pbix report:
For some obvious reasons, I need to have a relationship (non-active) between Dates[date] and Table2[T2Date]. However, doing so causes data fluctuation to measure 'Total Amount' in Table1.
Here are some screenshots:
Before Relationship (Dates[date] - Table2[T2Date]):
After Relationship (Dates[date] - Table2[T2Date]):
I need to understand why this difference is coming up and how the relationship is causing it since the measure uses a different relationship.
For reference, I am attaching the pbix report.
https://drive.google.com/open?id=1XknisXvElS6uQN224bEcZ_biX7m-4el4
Any help would be appreciated :)
The link that #MikeHoney gives has really useful information on the subtleties of relationships and does relate to this problem (do watch it!), but this issue is not ultimately related to bidirectional filtering in particular. In fact, I can reproduce it with this simplified relationship structure:
The key thing to note here is that when you attach Table2 to Dates, since Table2 contains T2Date values that don't match to any Date[date], this creates an extra row in Dates with a blank date which you can notice in your filter on 6. Year when that relationship exists (active or inactive). Filtering out that that blank in the 6. Year filter would work, except that in your measure, you use ALL(Dates) to strip all filtering done on that table.
There are multiple ways to resolve this discrepancy, the easiest being replacing ALL with ALLNOBLANKROW. If you used ALLSELECTED that would also work in conjunction with filtering out blanks on your report-level filter on 6. Year.
Cleaning up some items not relevant in this context and changing ALL to ALLNOBLANKROW, your total measure can be more simply written as:
ALLNOBLANKROW =
VAR EndServiceDate =
MAX ( Dates[Date] )
RETURN
CALCULATE (
SUM ( Table1[Net Amount] ),
FILTER (
ALLNOBLANKROW ( Dates ),
Dates[Date] <= EndServiceDate
),
Table1[Flag2] = 1,
Table1[Flag] = TRUE ()
)
Results with no 6. Year filter and with two measures, one using ALL and one using ALLNOBLANKROW:
Notice that every row in the ALL column has been reduced by -7,872.01. This is the sum of all the Net Amount values that don't match to any dates in the Dates table. If you remove the relationship from Dates[date] to Table2[T2Date] then the blank row no longer exists and both of these will match the ALLNOBLANKROW version.
Setting the Cross Filter Direction to Both on any relationship is a bit risky - you essentially hand over control of the runtime query designs to the Power BI robots. There's then a risk that they will come up with a "creative" query design that is unexpected.
There's some insight into how this happens in a recent talk by Alberto Ferrari:
https://www.sqlbi.com/tv/understanding-relationships-in-power-bi/
I'm sure you'll agree it's quite terrifying.
Looking at your info, I expect you can avoid those traps by changing the Cross Filter Direction to Single, for the relationship from MonthYear to Dates.