Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Next up in the FabCon + SQLCon recap series: The roadmap for Microsoft SQL and Maximizing Developer experiences in Fabric. All sessions are available on-demand after the live show. Register now

Reply
Anonymous
Not applicable

Rolling sum, stop by another field according to group - Power Query

Hi, 

In the example data can be identified 3 groups by [Type], A, B and C, and 5 groups by [Type] and [Name], A-John, A-Mia, B-Mia, B-Bob and C-John. [Type] A has [Stock] = 3, [Type] B has [Stock] = 1 and [Type] C has [Stock] = 2. Also, [Type] A, [Name] John has [WIP] = 2, [Type] A, [Name] Mia has [WIP] = 1, etc. 

ID

Date

Quantity

Type

Name

Stock

WIP

1

2019/12/20

1

A

John

3

2

2

2019/12/21

1

A

John

3

2

3

2019/12/22

2

A

John

3

2

4

2019/12/22

1

A

Mia

3

1

5

2019/12/18

1

B

Mia

1

3

6

2019/12/20

3

B

Mia

1

3

7

2019/12/21

2

B

Bob

1

1

8

2019/12/20

1

C

John

2

1

9

2019/12/22

1

C

John

2

1

10

2019/12/22

1

C

John

2

1

 

Each line of the data is a purchase order of some [Quantity] from a client.

 

I´d like to, first, identify which lines can be satisfied with [Stock], for each [Type], ordered by [Date] (i.e., first satisfy the oldest line).

 

Then, I´d like to identify which of the lines that could not be satisfied with [Stock] can be satisfied with [WIP], for each [Type]+[Name], again ordered by date.

 

Any solution that identifies those lines is ok, but I imagine that it could be done like this:

4.png

 

[HasStock] calculates the rolling sum of [Quantity] by [Type], ordered by [Date], with the condition that the result is less than or equal to [Stock]. In other case it should be 0.

 

[HasWIP] calculates the rolling sum of [Quantity] by [Type] and [Name], ordered by [Date], only for the rows where [Stock] can´t meet the demand, i.e. [HasStock] = 0, with the condition that the result is less than or equal to [WIP]. In other case it should be 0.

 

Best regards.

1 ACCEPTED SOLUTION
Anonymous
Not applicable

Hi @Anonymous ,

 

Please check following formulas.

HasStock = 
VAR t =
 FILTER ( 'Table', [Type] = EARLIER ( 'Table'[Type] ) )
VAR Stock =
 MAXX ( t, [Stock] )
VAR beforeDayLeft =
 Stock
 - CALCULATE (
 SUM ( 'Table'[Quantity] ),
 FILTER ( t, [Date] < EARLIER ( 'Table'[Date] ) )
 )
VAR thisdayQuantity =
 CALCULATE (
 SUM ( 'Table'[Quantity] ),
 FILTER ( t, [Date] = EARLIER ( 'Table'[Date] ) )
 )
VAR i = [ID]
VAR d = [Date]
VAR q = [Quantity]
RETURN
 IF (
 thisdayQuantity < beforeDayLeft,
 RANKX ( FILTER ( t, [Date] <= EARLIER ( 'Table'[Date] ) ), [ID], i, ASC, DENSE ),
 VAR thisDayt =
 FILTER ( t, 'Table'[Date] = d )
 VAR thisDaytRank =
 ADDCOLUMNS (
 thisDayt,
 "Index", RANKX ( thisDayt, [Quantity],, ASC, DENSE )
 + RANKX ( thisDayt, [ID],, ASC, DENSE ) / 10
 )
 VAR r =
 RANKX ( thisDayt, [Quantity], q, ASC, DENSE )
 + RANKX ( thisDayt, [ID], i, ASC, DENSE ) / 10
 RETURN
 IF (
 CALCULATE ( SUM ( 'Table'[Quantity] ), FILTER ( thisDaytRank, [Index] <= r ) ) > beforeDayLeft,
 0,
 CALCULATE ( DISTINCTCOUNT ( 'Table'[ID] ), FILTER ( t, 'Table'[Date] < d ) )
 + RANKX ( thisDayt, [Quantity], q, ASC, DENSE )
 )
 )
HasWIP = 
VAR t =
 FILTER (
 'Table',
 [Type] = EARLIER ( 'Table'[Type] )
 && [Name] = EARLIER ( 'Table'[Name] )
 )
VAR TotalWIP =
 MAXX ( t, [WIP] )
VAR d = [Date]
RETURN
 IF (
 [HasStock] <> 0,
 BLANK (),
 IF (
 'Table'[Quantity] > TotalWIP,
 0,
 VAR d = [Date]
 VAR q = [Quantity]
 VAR i = [ID]
 VAR PreviousT =
 FILTER ( t, [HasStock] = 0 && [Date] <= d )
 VAR PreviousTRank =
 ADDCOLUMNS (
 PreviousT,
 "Index", RANKX ( PreviousT, [Date],, ASC, DENSE )
 + RANKX ( PreviousT, [Quantity],, ASC, DENSE ) / 100
 + RANKX ( PreviousT, [ID],, ASC, DENSE ) / 10000
 )
 VAR r =
 RANKX ( PreviousT, [Date], d, ASC, DENSE )
 + RANKX ( PreviousT, [Quantity], q, ASC, DENSE ) / 100
 + RANKX ( PreviousT, [ID], i, ASC, DENSE ) / 10000
 RETURN
 IF (
 CALCULATE ( SUM ( 'Table'[Quantity] ), FILTER ( PreviousTRank, [Index] <= r ) ) <= TotalWIP,
 [Quantity],
 0
 )
 )
 )

Result would be shown as below.

1.PNG

BTW, Pbix as attached, hopefully works for you.

 

Best Regards,

Jay

Community Support Team _ Jay Wang

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

View solution in original post

5 REPLIES 5
Anonymous
Not applicable

Hi @Anonymous ,

 

If i understand you correctly, ALLEXCEPT() function and EARLIER() function might be helpful for you.

But one thing I'm confused about is what you mean "ordered by [Date] (i.e., first satisfy the oldest line)". As i can see from your sample data the Date of ID 3 and 4 is same, their Quantity is less than stock. Why HasStock of ID 3 and 10 is 0, how do you judge the "oldest line"?

 

Best Regards,

Jay

Community Support Team _ Jay Wang

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Greg_Deckler
Community Champion
Community Champion

So you already have the solution or is that how you imagine the solution being done?



Follow on LinkedIn
@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
DAX For Humans

DAX is easy, CALCULATE makes DAX hard...
Anonymous
Not applicable

@Greg_Deckler This is how I imagine it being done. I just want to identify which lines can be satisfied with stock and then with WIP, by date, with the logic I wrote.

 

@Anonymous ID 3 and ID 4 quantity is less than stock, but when you do the cummulative sum ID 3 can´t satisfy stock.

 

For [Type] A there are 4 purchase orders:

  • ID 1, of Quantity 1 and date 12/20
  • ID 2, of Quantity 1 and date 12/21
  • ID 3, of Quantity 2 and date 12/22
  • ID 4, of Quantity 1 and date 12/22

Also, A has a [Stock] of 3 and a [WIP] of 2.

 

So, by [Date], you would take the first purchase order, ID 1, and try if [Stock] can satisfy it. Because 1 <= 3 it can be done. Now we have only 2 left in [Stock].

Then you take the second purchase order by [Date], ID 2, and try if [Stock] can satisfy it. Because 1 <= 2 it can be done. Now we have only 1 left in [Stock].

Then you take the next purchase order by [Date]. It does not matter if you take first ID 3 or ID 4 because they have the same [Date], but I wanted to take that case in consideration. If you try ID 3, its [Quantity], 2, is not less than or equal to 1 left in [Stock], so [Stock] can´t satisfy ID 3 and the column I imagined [HasStock] should be a 0. Then you try ID 4 and check that 1<=1 in [Stock] so ID 4 can be satisfied. Now we have 0 left in [Stock].

 

ID 1, ID 2 and ID 4 can be satisfied with [Stock]. ID 3 can be satisfied with [WIP] (but the grouping must be [Type]-[Name] as I described).

 

Doing it by [Date] I mean, If the case were this:

  • ID 1, of Quantity 1 and date 12/20
  • ID 2, of Quantity 1 and date 12/21
  • ID 3, of Quantity 2 and date 12/22
  • ID 4, of Quantity 1 and date 12/22
  • ID 5, of Quantity 1 and date 12/23
  • ID 6, of Quantity 2 and date 12/24

ID 1, ID 2 and ID 4 can be satisfied with [Stock]. ID 3 can be satisfied with [WIP]. ID 5 and ID 6 can´t be satisfied (you need to start with ID 1).

Anonymous
Not applicable

Hi @Anonymous ,

 

Please check following formulas.

HasStock = 
VAR t =
 FILTER ( 'Table', [Type] = EARLIER ( 'Table'[Type] ) )
VAR Stock =
 MAXX ( t, [Stock] )
VAR beforeDayLeft =
 Stock
 - CALCULATE (
 SUM ( 'Table'[Quantity] ),
 FILTER ( t, [Date] < EARLIER ( 'Table'[Date] ) )
 )
VAR thisdayQuantity =
 CALCULATE (
 SUM ( 'Table'[Quantity] ),
 FILTER ( t, [Date] = EARLIER ( 'Table'[Date] ) )
 )
VAR i = [ID]
VAR d = [Date]
VAR q = [Quantity]
RETURN
 IF (
 thisdayQuantity < beforeDayLeft,
 RANKX ( FILTER ( t, [Date] <= EARLIER ( 'Table'[Date] ) ), [ID], i, ASC, DENSE ),
 VAR thisDayt =
 FILTER ( t, 'Table'[Date] = d )
 VAR thisDaytRank =
 ADDCOLUMNS (
 thisDayt,
 "Index", RANKX ( thisDayt, [Quantity],, ASC, DENSE )
 + RANKX ( thisDayt, [ID],, ASC, DENSE ) / 10
 )
 VAR r =
 RANKX ( thisDayt, [Quantity], q, ASC, DENSE )
 + RANKX ( thisDayt, [ID], i, ASC, DENSE ) / 10
 RETURN
 IF (
 CALCULATE ( SUM ( 'Table'[Quantity] ), FILTER ( thisDaytRank, [Index] <= r ) ) > beforeDayLeft,
 0,
 CALCULATE ( DISTINCTCOUNT ( 'Table'[ID] ), FILTER ( t, 'Table'[Date] < d ) )
 + RANKX ( thisDayt, [Quantity], q, ASC, DENSE )
 )
 )
HasWIP = 
VAR t =
 FILTER (
 'Table',
 [Type] = EARLIER ( 'Table'[Type] )
 && [Name] = EARLIER ( 'Table'[Name] )
 )
VAR TotalWIP =
 MAXX ( t, [WIP] )
VAR d = [Date]
RETURN
 IF (
 [HasStock] <> 0,
 BLANK (),
 IF (
 'Table'[Quantity] > TotalWIP,
 0,
 VAR d = [Date]
 VAR q = [Quantity]
 VAR i = [ID]
 VAR PreviousT =
 FILTER ( t, [HasStock] = 0 && [Date] <= d )
 VAR PreviousTRank =
 ADDCOLUMNS (
 PreviousT,
 "Index", RANKX ( PreviousT, [Date],, ASC, DENSE )
 + RANKX ( PreviousT, [Quantity],, ASC, DENSE ) / 100
 + RANKX ( PreviousT, [ID],, ASC, DENSE ) / 10000
 )
 VAR r =
 RANKX ( PreviousT, [Date], d, ASC, DENSE )
 + RANKX ( PreviousT, [Quantity], q, ASC, DENSE ) / 100
 + RANKX ( PreviousT, [ID], i, ASC, DENSE ) / 10000
 RETURN
 IF (
 CALCULATE ( SUM ( 'Table'[Quantity] ), FILTER ( PreviousTRank, [Index] <= r ) ) <= TotalWIP,
 [Quantity],
 0
 )
 )
 )

Result would be shown as below.

1.PNG

BTW, Pbix as attached, hopefully works for you.

 

Best Regards,

Jay

Community Support Team _ Jay Wang

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Anonymous
Not applicable

o_O Impresive! Thank you!!

Helpful resources

Announcements
New to Fabric survey Carousel

New to Fabric Survey

If you have recently started exploring Fabric, we'd love to hear how it's going. Your feedback can help with product improvements.

Power BI DataViz World Championships carousel

Power BI DataViz World Championships - June 2026

A new Power BI DataViz World Championship is coming this June! Don't miss out on submitting your entry.

Join our Fabric User Panel

Join our Fabric User Panel

Share feedback directly with Fabric product managers, participate in targeted research studies and influence the Fabric roadmap.

March Power BI Update Carousel

Power BI Community Update - March 2026

Check out the March 2026 Power BI update to learn about new features.