Distinct Count of weeks where sum is greater than 0 PowerPivot - excel

I have a table with the following criteria.There are multiple week endings for multiple projects. The hour/cost column can be positive or negative and are correlated (positive hours/positive costs). I'm able to get a distinct count of week ending for the project if there are any costs to it(+or-), but I want to get a distinct count only if the sum of hours or costs are positive.
Since charges can be + or -, and potentially cancel out for a week ending, this would alter my average formula if it were to count a week with sum of 0.
I'm trying to build a calculated field that I could add to my Pivot table that lists the actual charged weeks when I filter by Project. In the sample, there are 4 unique dates with sum greater than 0, but my current formula gives me 7 unique dates, disregarding positive sum.
WeekEndDate| Project | Hours | Cost
Sample Data
+---------------+---------+--------+-------------+
| WeekEndDate | Project | Hours | Cost |
+---------------+---------+--------+-------------+
| 10/7/16 | C7119A | 2.00 | $122.00 |
| 10/7/16 | C7119A | 32.00 | $1,952.00 |
| 10/7/16 | C7119A | 1.50 | $91.50 |
| 10/7/16 | C7119A | -32.00 | ($1,952.00) |
| 10/14/16 | C7119A | 10.00 | $610.00 |
| 10/14/16 | C7119A | -10.00 | ($610.00) |
| 10/21/16 | C7119A | 19.50 | $1,189.50 |
| 10/21/16 | C7119A | -19.50 | ($1,189.50) |
| 10/28/16 | C7119A | 2.00 | $122.00 |
| 10/28/16 | C7119A | 3.00 | $183.00 |
| 10/28/16 | C7119A | -3.00 | ($183.00) |
| 10/28/16 | C7119A | -2.00 | ($122.00) |
| 11/4/16 | C7119A | 1.00 | $61.00 |
| 11/11/16 | C7119A | 3.50 | $213.50 |
| 1/13/17 | C7119A | 3.00 | $183.00 |
+---------------+---------+--------+-------------+

You can do this using SUMMARIZE().
First create a calculated column to get a distinct ID on the project/week combo:
ProjectWeek =CONCATENATE([Project],[Week End Date])
Then create a calculated measure to count the weeks with positive sum of hours:
Positive Project Weeks:= COUNTROWS(Filter(ADDCOLUMNS(
SUMMARIZE('Project Costs','Project Costs'[Week End Date]),
"WeekSum", MAXX(Values('Project Costs'[ProjectWeek]),
CALCULATE(Sum([Hours]),ALL('Project Costs'[Hours])))),
[WeekSum] >0))
SUMMARIZE creates a table that contains the distinct WeekEndDate values.
ADDCOLUMNS creates a column in that table that shows the sum of hours for that WeekEndDate.
Filter removes the rows in our virtual table that have a sum of hours less than or equal to 0.
Countrows then counts the rows left in the table, which is equal to the distinct count of end dates.
If you don't create the calculated column for ProjectWeek and instead use WeekEndDate in the MAXX(VALUES()) functions, you will get a total of 7 instead of 4.

Related

DAX - Cumulative total without date-formatted source data

I am trying to implement a YtD measure for my report in Excel with Power Pivot. My source looks roughly like this:
Table 1
| Month | Store | Branch | Article | Value |
|----------|-------|--------|---------|-------|
| January | 1 | A | Sales | 200 |
| January | 1 | A | Costs | 100 |
| January | 1 | A | Rent | 10 |
| February | 1 | A | Costs | 20 |
| February | 1 | A | Sales | 80 |
| March | 1 | A | Costs | 30 |
| March | 1 | A | Sales | 80 |
| February | 2 | B | Sales | 100 |
| February | 2 | B | Costs | 40 |
| February | 2 | B | Rent | 20 |
Linked to it, are a table Table 2 of months (name - number from 1 to 12), a table Table 3 of unique articles and a table Table 4 of unique stores with their branches.
I want to be able to display YtD for every article depending on the chosen month.
I have measures:
Val. := sum(table1[Value])
YtD1:= calculate(Val., all('Table 2'[Name]))
The former sums across all the values, which are filtered by article in my pivot report. The latter calculates a YtD across all months. It works, but I have to rewrite it so that it responds to filtering the last month and sums from the first month to the selected month.
I have tried to format month numbers to process them as dates (e.g. first day of the month), but couldn't appropriately handle the FORMAT function.
I have also tried to do a sum of months, i.e.:
YtD2= calculate(Val., filter(Table2;Table2[Number]<=2))
which, I hoped, would count months from January to February. It doesn't seem to do any good, resulting in numbers I cannot explain.
My desired output should look like this:
| Store | Sales | | Costs | |
|-------|-------|-----|-------|-----|
| | Val. | YtD | Val. | YtD |
| 1 | 80 | 280 | 20 | 120 |
| 2 | 100 | 100 | 40 | 40 |
if data is filtered by February.
Or
| Store | Sales | | Costs | |
|-------|-------|-----|-------|-----|
| | Val. | YtD | Val. | YtD |
| 1 | 160 | 360 | 50 | 150 |
| 2 | 100 | 100 | 40 | 40 |
if February and March are selected (Val. is displayed for February and March, but YtD from January to March).
Is there a way to implement this in DAX? Can this be done without conversion from month names (or numbers) to some date&
If not, can I get it to work for a month filter instead of a month slicer? That is, if only one month can be selected.
I cannot use variables and similar Power BI features.
Try:
YTD :=
VAR MaxSelectedMonth =
MAX( Table2[Number] )
RETURN
CALCULATE(
[Val.],
FILTER(
ALL( Table2 ),
Table2[Number] <= MaxSelectedMonth
)
)

Dax measure for monthly running total on weekly granularity

I have to visualize an accumulated monthly budget on a daily level.
Means a running total for the individual month on a daily basis.
The budget targets are provided in a table like this:
+------+------------+--------+
| Area | Year-Week | Budget |
+------+------------+--------+
| A | 2020-01 | 50 |
| A | 2020-02 | 25 |
| A | 2020-03 | 50 |
| A | 2020-04 | 25 |
| B | 2020-01 | 50 |
| B | 2020-02 | 50 |
| B | 2020-03 | 50 |
| B | 2020-04 | 75 |
+------+------------+--------+
As you can see, the monthly budget for January is the sum of 2020-01 - 2020-04
The structure is provided in the calendar table. So I have the information on which week belongs to which month.
What I need to do is to create a dax measure that divides the weekly budget by the working days.
THe calendar has also the information of calendar days. For this purpose I have add this measure:
Working Days =
VAR vSelectedMonth =
SELECTEDVALUE ( 'Calendar'[Fiscal Month Number])
RETURN
CALCULATE (
COUNTROWS ( 'Calendar' ),
FILTER (
'Calendar',
'Calendar'[Fiscal Month Number] = vSelectedMonth
&& 'Calendar'[IsWorkingDay] = 1
)
)
Now, how can I divide the weekly budget by the working days for the corresponding week and than to accumulate this information for the whole month?
Based on the provided information the result should be something like that:
+------+------------+----------------+
| Area | Date | Running Budget |
+------+------------+----------------+
| A | 01.01.2020 | 10 |
| A | 02.01.2020 | 20 |
| A | 03.01.2020 | 30 |
| A | 04.01.2020 | 40 |
| A | 05.01.2020 | 50 |
| A | 06.01.2020 | 50 |
| A | 07.01.2020 | 50 |
| A | 08.01.2020 | 55 |
+------+------------+----------------+
Of course, if the corresponding date is not a working day, that value from the day before should be shown.
I am grateful for every help!
Please let me know if you need further information.
Best Regards

Cumulative sum of unique users per day

I'm having trouble creating the query to plot a running sum of unique users per day.
I have a table of usages. Lets consider this table:
+--------+---------------------+
| UserId | Timestamp |
+--------+---------------------+
| 1 | 2020-6-9T08:00:00Z |
+--------+---------------------+
| 2 | 2020-6-9T09:23:00Z |
+--------+---------------------+
| 3 | 2020-6-9T14:12:00Z |
+--------+---------------------+
| 3 | 2020-6-10T15:12:00Z |
+--------+---------------------+
| 3 | 2020-6-10T18:01:00Z |
+--------+---------------------+
| 4 | 2020-6-10T02:02:00Z |
+--------+---------------------+
The resulting table I would like to produce is a cumulative sum, per day, such that the sum increases only if that user did not report usage previously.
The graph above would produce the following result. The key here is that on day 2020-6-10, User 3 is not included in the sum, since User 3 reported Usage on 2020-6-9. Also, notice User 3 was only report once on 2020-6-10 (each day is unique usage).
+-----------+-------+
| Day | Users |
+-----------+-------+
| 2020-6-9 | 3 |
+-----------+-------+
| 2020-6-10 | 1 |
+-----------+-------+
Please take a look at activity_counts_metrics plugin:
let start = datetime(2020-06-09);
let end = datetime(2020-06-11);
datatable (UserId:int, Timestamp:datetime)
[
1, datetime(2020-6-9T08:00:00Z),
2, datetime(2020-6-9T09:23:00Z),
3, datetime(2020-6-9T14:12:00Z),
3, datetime(2020-6-10T15:12:00Z),
3, datetime(2020-6-10T18:01:00Z),
4, datetime(2020-6-10T02:02:00Z),
]
| evaluate activity_counts_metrics(UserId, Timestamp, start, end, 1d)
| project Timestamp, new_dcount

Lookup between two tables on a unique ID AND where the date is between two other dates

I have two tables in Excel. One has Key and Date - this can be table A. The other has Key, Begin Date, End Date, and Value - let's call this table B.
I am trying to pull into Table A the Value from Table B for the Key , where the Date from Table A is between the Begin Date and End Date from Table B. The value should be 0.4 using the example tables below.
NOTE: There will never be overlapping dates and shouldn't have multiple rows for the same date range.
Table A -
| Key | Date |
|-----|------------|
| 2 | 10/29/2018 |
Table B -
| Key | Begin Date | End Date | Value |
|-----|------------|------------|-------|
| 1 | 07/01/2018 | 12/31/2999 | 0.1 |
| 1 | 01/01/1995 | 06/30/2018 | 1 |
| 1 | 01/01/1900 | 12/31/1994 | 0.5 |
| 2 | 10/31/2018 | 12/31/2999 | 3.6 |
| 2 | 01/01/1995 | 10/30/2018 | 0.4 |
| 2 | 01/01/1900 | 12/31/1994 | 10 |
| 3 | 01/01/1900 | 12/31/2999 | 100 |
Thanks!
Assuming there'll only be one match, use SUMIFS.
=SUMIFS($I$1:$I$8,$F$1:$F$8,A2,$G$1:$G$8,"<="&B2,$H$1:$H$8,">="&B2)
Note - changed two instances of 12/31/1995 in Table B to 12/31/1994, assuming that it's a typo and date ranges shouldn't overlap between rows.
EDIT:
You can use INDEX and AGGREGATE if you need to return text.
=INDEX(I2:I8,AGGREGATE(15,6,ROW($A$1:$A$7)/(($F$2:$F$8=A2)*($G$2:$G$8<=B2)*($H$2:$H$8>=B2)),1))

DAX Cumulative Total With Date Filters

I am trying to calculate a running total where orders are only valid during a certain date range. Each order has a value, a start date and an end date. I want to calculate the cumulative sum of the order's values only during the dates between an order's start date and end date.
I've read over this article on cumulative totals and have an equation for the running total but I can't figure out how to filter the equation so that it filter's out an order once the date table is past the order's End Date. The current measure I have is Cumulative Value:=CALCULATE(SUM(Orders[Vaue]), FILTER(ALL('Date'), [Date] <= MAX([Date]))) and I want to add a filter that filters out any orders with an end date past the current date row, similar to this Filter('Order', 'Orders'[Order_End_Date] < 'Date'[Date]). When I try to add this filter though I get an error since 'Date'[Date] is not used in any aggregation.
Below is the data model that I am using and a link to the Excel File with the data model.
The sample Data:
+-----------+
| Date |
+-----------+
| 1/1/2015 |
| 1/2/2015 |
| 1/3/2015 |
| 1/4/2015 |
| 1/5/2015 |
| 1/6/2015 |
| 1/7/2015 |
| 1/8/2015 |
| 1/9/2015 |
| 1/10/2015 |
+-----------+
+----------+------+------------------+----------------+
| Order_Id | Vaue | Order_Start_Date | Order_End_Date |
+----------+------+------------------+----------------+
| 1 | 1 | 1/1/2015 | 1/3/2015 |
| 2 | 3 | 1/2/2015 | |
| 3 | 6 | 1/3/2015 | 1/7/2015 |
| 4 | 7 | 1/5/2015 | |
+----------+------+------------------+----------------+
And the output of the current measure I have and what the correct measure's output should be.
+-----------+-----------------+--------------------------+
| Date | Current Measure | Desired Measure's Output |
+-----------+-----------------+--------------------------+
| 1/1/2015 | 1 | 1 |
| 1/2/2015 | 4 | 4 |
| 1/3/2015 | 10 | 9 |
| 1/4/2015 | 10 | 9 |
| 1/5/2015 | 17 | 16 |
| 1/6/2015 | 17 | 16 |
| 1/7/2015 | 17 | 10 |
| 1/8/2015 | 17 | 10 |
| 1/9/2015 | 17 | 10 |
| 1/10/2015 | 17 | 10 |
+-----------+-----------------+--------------------------+
Cumulative Value2:=CALCULATE(
SUM(Orders[Vaue])
,FILTER(
VALUES(Orders[Order_Start_Date])
,Orders[Order_Start_Date] <= MAX('Date'[Date])
)
,FILTER(
VALUES(Orders[Order_End_Date])
,ISBLANK(Orders[Order_End_Date])
|| Orders[Order_End_Date] >= MAX('Date'[Date])
)
)
Model Diagram (note I took out your date relation - for the limited use case you've provided, it only makes things more complicated):
Note: I will refer to function arguments positionally, with the first argument represented by (1).
So, what we're doing is similar to what you were trying. We've got two FILTER()s, each as an argument to our CALCULATE(). CALCULATE() combines its arguments (2)-(n) in a logical and.
The first FILTER() does essentially what you were already doing, except we are filtering the distinct values of the [Order_Start_Date], comparing them against the current filter context of the pivot table.
The second FILTER() loops over the distinct values of [Order_End_Date], checking two conditions combined in a logical or. We must handle the case of a BLANK [Order_End_Date]. This BLANK is normally implicitly converted to 0 == 1899-12-30, which is less than any date we're considering. In the case of a BLANK, we get a true value from ISBLANK() and the row is returned as a part of FILTER()'s resultset. The other test is simply checking that [Order_End_Date] is greater than the current filter context date in the pivot.
What you are looking for is often called the "event in progress" problem. Here are some posts that will help you to solve your problem.
a solid summary of the problem
a special case
guess this will help on first sight
if you can't get enough - read the complete white paper
I hope this helps.
-Tom

Resources