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

Enhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends September 15. Request your voucher.

Reply
DSR
Resolver I
Resolver I

List.Generate to calculate column based on the previous row value of the Same Column

There is no solution yet as of Sunday February 16, 2025, 7:00pm USA Eastern Time.

 

Hello, Please  your help is appreciated. Kindly in each line of the List.Generate write its clarification in detail.

I have a table loaded in the power query copy below. Last Step: ChangedType=Source

let

    Source = Excel.CurrentWorkbook(){[Name="Tb_CalculatebasedonPrvRowValue"]}[Content],

    ChangedType = Table.TransformColumnTypes(Source, {{"Case.CC.EEName", type text}, {"PeriodNo", Int64.Type}, {"Yr", type text}, {"NoEE.inPrvPrd", Int64.Type}, {"Yr Move Out", Int64.Type}, {"Index.inGrp", Int64.Type}, {"NoEE", Int64.Type},{"Answershallbe",Int64.Type}}),

 

The table has the following Columns:

Case.CC.EEName

PeriodNo

Yr

NoEE.inPrvPrd

Yr Move Out

Index.inGrp

NoEE

Answershallbe

 

Column [Index.inGrp] is the Index  {0,1,2,3,…10}

 

Case.CC.EEName

PeriodNo

Yr

NoEE.inPrvPrd

Yr Move Out

Index.inGrp

NoEE

Answershallbe

A

0

Yr00

0

2

0

0

 

A

1

Yr01

0

2

1

1

1

A

2

Yr02

1

2

2

1

2

A

3

Yr03

1

2

3

1

1

A

4

Yr04

1

2

4

0

 

A

5

Yr05

0

2

5

1

1

A

6

Yr06

1

2

6

0

 

A

7

Yr07

0

2

7

0

 

A

8

Yr08

0

2

8

0

 

A

9

Yr09

0

2

9

0

 

A

10

Yr10

0

2

10

0

 

 

 

Please help me in Power query

Purpose to calculate the Tenure (the length of time an employee has been working/worked in the company) for EACH Employee in a company:

an Employee stays 2 periods (column [Yr Move out]) and leaves at the End of Year 2.  A NEW employee starts the next period (if there is work)

Some Employee is hired for only 1 Period as in Yr05, Index.inGrp =5

When [NoEE]=0 means position vacant= no Employee

When [NoEE] = 1, means there is Employee on the job.

 

Job A is filled by different employee over the period from Yr00… to Yr10

 

I want to calculate the Tenure (Calculated Column value) of EACH employee, that shall meet the following conditions:

 

if CurrentRow[Index.inGrp] = 0  or CurrentRow[Index.inGrp] =  null then null // If Index.inGrp = 0, set value to null

else if CurrentRow[NoEE] = 0 or CurrentRow[NoEE] = null then null // If NoEE = 0 or null, set value to null                        

else if PrevValue of [NoEE]  = 0  or PrevValue of [NoEE]  = null then CurrentRow[NoEE]  // If PrevValue of [NoEE]  = 0 or null,  set value to CurrentRow[NoEE]

else if PrevValue of Tenure  =  CurrentRow[Yr Move Out] then CurrentRow[NoEE] // If PrevValue of Tenure = CurrentRow[Yr Move Out], set value to CurrentRow[NoEE]

else PrevValue of Tenure + 1, // Otherwise, PrevValue of Tenure + 1

 

if you do not get the result as in Column [Answershallbe] mean that it means solution is not correct.

Please use List.Generate to calculate PreValue

 

Tenure is the current Employee= CurrentRow Tenure

PrevValue is the Tenure of the PREVIOUS PERIOD, which could be for different empluee than the current one.

Tenure = PrevValue + CurrentRow[NoEE]

PrevValue can be sometimes 0, 1 up to [Yr Move Out]

CurrentRow[NoEE]  can be 0 or 1

 

Please Note: the PrevValue recursive refereeing to its previous Calculation

To create PrevValue please use List.Generate function. This function allows you to generate a list based on a set of conditions, and it can be used to create a recursive calculation where each row depends on the previous row's value.

16 REPLIES 16
DSR
Resolver I
Resolver I

 Akash_Varuna's result

was the nearest but not aligned

Thank you ffor your effort.

Yours are the nearest but they are not aligned.

I asked copilot (5-8), deepsaeek(10+) and openai (15+) times all failed. however, i took thast copilot and changed 2 line of codes to become:

CurrentRow = BufferTable{[RowIndex]+1},
PreviousRow = BufferTable{[RowIndex]},

Copilot as most looked back, i follower rickmaurinus  logic in Calculating running total.  looking  next instead of looking back

and correctly solve it: here is the correct codes:

let
    Source = Excel.CurrentWorkbook(){[Name="Tb_CalculatebasedonPrvRowValue"]}[Content],
    ChangedType = Table.TransformColumnTypes(Source, 
    {
        {"Case.CC.EEName", type text}, 
        {"PeriodNo", Int64.Type}, 
        {"Yr", type text}, 
        {"NoEE.inPrvPrd", Int64.Type}, 
        {"Yr Move Out", Int64.Type}, 
        {"Index.inGrp", Int64.Type}, 
        {"NoEE", Int64.Type},
        {"Answershallbe", Int64.Type}
    }),
BufferTable = Table.Buffer(ChangedType),
 
    ListTenure = List.Generate(
        () => [RowIndex = 0, Tenure = if BufferTable[NoEE]{0} = 0 then "" else BufferTable[NoEE]{0}], 
        each [RowIndex] < Table.RowCount(BufferTable),
        each [
            RowIndex = [RowIndex] + 1,
            CurrentRow = BufferTable{[RowIndex]+1},
            PreviousRow = BufferTable{[RowIndex]},
            PrevTenure = [Tenure],
            Tenure = 
                if CurrentRow[Index.inGrp] = 0 or CurrentRow[Index.inGrp] = null then ""
                else if CurrentRow[NoEE] = 0 or CurrentRow[NoEE] = null then ""
                else if PreviousRow[NoEE] = 0 or PreviousRow[NoEE] = null then CurrentRow[NoEE]
                else if PrevTenure = PreviousRow[Yr Move Out] then CurrentRow[NoEE]
                else PrevTenure + 1
        ],
        each [Tenure]
    ),
 
    #"CombineStartTb + TenureCol" = Table.FromColumns(
        Table.ToColumns(BufferTable) & {Value.ReplaceType(ListTenure, type {Int64.Type} )},
        Table.ColumnNames(BufferTable) & {"Calculated Tenure"}
    ),
    #"Added Custom" = Table.AddColumn(#"CombineStartTb + TenureCol", "EE.Refill", each if [Calculated Tenure] = "" then "" else if [Calculated Tenure] = 1 then List.Count(List.Select(List.FirstN(#"CombineStartTb + TenureCol"[Calculated Tenure],[Index.inGrp]+1), each _=1)) else if [Calculated Tenure]>1 then null else "", Int64.Type),
    #"Filled Down" = Table.FillDown(#"Added Custom",{"EE.Refill"})
 
in
    #"Filled Down"
v-ssriganesh
Community Support
Community Support

Hello @DSR,

Could you please confirm if your query have been resolved? If they have, kindly mark the helpful response and accept it as the solution. This will assist other community members in resolving similar issues more efficiently.

Thank you.

Hello v-ssriganesh,

Thank you for your recommendation. but yours did not solve it. the nearest one is from Akash_Varuna but was not aligned. 

I asked copilot (5-8), deepsaeek(10+) and openai (15+) times all failed. however, i took thast copilot and changed 2 line of codes to become:

CurrentRow = BufferTable{[RowIndex]+1},
PreviousRow = BufferTable{[RowIndex]},

Copilot as most looked back, i follower rickmaurinus  logic looking next instead of lookinh back

and correctly solve it: here is the correct codes:

let
    Source = Excel.CurrentWorkbook(){[Name="Tb_CalculatebasedonPrvRowValue"]}[Content],
    ChangedType = Table.TransformColumnTypes(Source, 
    {
        {"Case.CC.EEName", type text}, 
        {"PeriodNo", Int64.Type}, 
        {"Yr", type text}, 
        {"NoEE.inPrvPrd", Int64.Type}, 
        {"Yr Move Out", Int64.Type}, 
        {"Index.inGrp", Int64.Type}, 
        {"NoEE", Int64.Type},
        {"Answershallbe", Int64.Type}
    }),
BufferTable = Table.Buffer(ChangedType),
 
    ListTenure = List.Generate(
        () => [RowIndex = 0, Tenure = if BufferTable[NoEE]{0} = 0 then "" else BufferTable[NoEE]{0}], 
        each [RowIndex] < Table.RowCount(BufferTable),
        each [
            RowIndex = [RowIndex] + 1,
            CurrentRow = BufferTable{[RowIndex]+1},
            PreviousRow = BufferTable{[RowIndex]},
            PrevTenure = [Tenure],
            Tenure = 
                if CurrentRow[Index.inGrp] = 0 or CurrentRow[Index.inGrp] = null then ""
                else if CurrentRow[NoEE] = 0 or CurrentRow[NoEE] = null then ""
                else if PreviousRow[NoEE] = 0 or PreviousRow[NoEE] = null then CurrentRow[NoEE]
                else if PrevTenure = PreviousRow[Yr Move Out] then CurrentRow[NoEE]
                else PrevTenure + 1
        ],
        each [Tenure]
    ),
 
    #"CombineStartTb + TenureCol" = Table.FromColumns(
        Table.ToColumns(BufferTable) & {Value.ReplaceType(ListTenure, type {Int64.Type} )},
        Table.ColumnNames(BufferTable) & {"Calculated Tenure"}
    ),
    #"Added Custom" = Table.AddColumn(#"CombineStartTb + TenureCol", "EE.Refill", each if [Calculated Tenure] = "" then "" else if [Calculated Tenure] = 1 then List.Count(List.Select(List.FirstN(#"CombineStartTb + TenureCol"[Calculated Tenure],[Index.inGrp]+1), each _=1)) else if [Calculated Tenure]>1 then null else "", Int64.Type),
    #"Filled Down" = Table.FillDown(#"Added Custom",{"EE.Refill"})
 
in
    #"Filled Down"

Hi @DSR,
We appreciate your efforts and are pleased to hear that your issue was resolved. Please mark the helpful response and accept it as the solution. This will assist other community members in resolving similar issues more efficiently.
Thank you.

v-ssriganesh
Community Support
Community Support

Hi @DSR,

Thank you @dufoq3 for addressing the issue.

We would like to follow up to see if the solution provided by the super user resolved your issue. Please let us know if you need any further assistance.


If the super user's response resolved your issue, please Accept it as a solution and consider leaving a "Kudos" so other members can find it more easily.

Thank you.

v-ssriganesh
Community Support
Community Support

Hi @DSR,

May I ask if you have resolved this issue? If so, please mark the helpful reply and accept it as the solution. This will be helpful for other community members who have similar problems to solve it faster.

Thank you.

dufoq3
Super User
Super User

At the beginning you have to check List.Generate


Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

dufoq3
Super User
Super User

Hi @DSR, check this:

 

Output

dufoq3_0-1739443018952.png

let
    Source = Table.FromRows( {
        {"A", 0, "Yr00", 0, 2, 0, 0},
        {"A", 1, "Yr01", 0, 2, 1, 1},
        {"A", 2, "Yr02", 1, 2, 2, 1},
        {"A", 3, "Yr03", 1, 2, 3, 1},
        {"A", 4, "Yr04", 1, 2, 4, 0},
        {"A", 5, "Yr05", 0, 2, 5, 1},
        {"A", 6, "Yr06", 1, 2, 6, 0},
        {"A", 7, "Yr07", 0, 2, 7, 0},
        {"A", 8, "Yr08", 0, 2, 8, 0},
        {"A", 9, "Yr09", 0, 2, 9, 0},
        {"A", 10, "Yr10", 0, 2, 10, 0} },
        {"Case.CC.EEName", "PeriodNo", "Yr", "NoEE.inPrvPrd", "Yr Move Out", "Index.inGrp", "NoEE"} ),
    L = List.Buffer(Table.ToRows(Table.SelectColumns(Source,{"NoEE", "Index.inGrp", "Yr Move Out"}))),
    Gen = List.Skip(List.Generate(
        ()=> [ x = -1],
        each [x] < List.Count(L),
        each [ x = [x]+1, y = L{x},
               z = if (y{0}??0) = 0 then null
                   else if (y{1}??0) = 0 then null
                   else if ([z]??0) = 0 then 1
                   else if [z] = y{2} then y{0}
                   else [z] +1 ],
        each [z] )),
    Merged = Table.FromColumns(Table.ToColumns(Source) & {Gen}, Value.Type(Table.FirstN(Source, 0) & #table(type table[Answer=Int64.Type], {})))
in
    Merged

Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

I know List.Generate as function. You did not define any of the x, y, x ??. Thanks

 

Read whole article please:

 

dufoq3_0-1739482637470.png

I've defined all of x,y and z

dufoq3_1-1739482735053.png

 

Just to clarify if (y{0}??0) = 0 means: if fist value of list y = null or first value of list y = null


Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

Hello dufoq3, Thank you for your effort. Could you please explain for me along each line the ollowing lines?

Gen = List.Skip(List.Generate(
()=> [ x = -1],
each [x] < List.Count(L),
each [ x = [x]+1, y = L{x},
z = if (y{0}??0) = 0 then null
else if (y{1}??0) = 0 then null
else if ([z]??0) = 0 then 1
else if [z] = y{2} then y{0}
else [z] +1 ],
each [z] )),
Merged = Table.FromColumns(Table.ToColumns(Source) & {Gen}, Value.Type(Table.FirstN(Source, 0) & #table(type table[Answer=Int64.Type], {})))
in
Merged

 

Thank you

v-ssriganesh
Community Support
Community Support

Hello @DSR,

Thank you for posting your query in the Microsoft Fabric Community Forum regarding the calculation of a column based on the previous row's value using List.Generate in Power Query. I have successfully replicated your scenario in Power BI Desktop and would like to share the steps I followed, along with the expected output and a PBIX file for your reference.

Steps I Followed:

  • Created Sample Data: I manually entered the following data into Power BI Desktop:

Case.CC.EEName

PeriodNo

Yr

NoEE.inPrvPrd

Yr Move Out

NoEE

Index.inGrp

A

0

Yr00

0

2

0

0

A

1

Yr01

0

2

1

1

A

2

Yr02

1

2

2

2

A

3

Yr03

1

2

1

3

A

4

Yr04

1

2

0

4

A

5

Yr05

0

2

1

5

A

6

Yr06

1

2

0

6

A

7

Yr07

0

2

0

7

A

8

Yr08

0

2

0

8

A

9

Yr09

0

2

0

9

A

10

Yr10

0

2

0

10

  • Opened Power Query Editor: I imported the data into Power Query by selecting Transform Data.
  • Added Custom Calculated Column: I implemented the following M code to create the new calculated column, CalculatedNoEE:

Code:

let 

    index = [Index.inGrp], 

    noEE = [NoEE], 

    yrMoveOut = [Yr Move Out], 

    previousValues = List.Generate( 

        () => [Value = 0, Index = 0],

        each [Index] <= index,

        each [ 

            Value = if [Index] = 0 then 0

                     else if noEE = 0 or noEE = null then null

                     else if [Value] = yrMoveOut then noEE  

                     else [Value] + 1,

            Index = [Index] + 1   

        ], 

        each [Value]

    ), 

    result = List.Last(previousValues)

in 

    result 

  • Reviewed and Applied Changes: After adding the custom column, I verified the calculations.
  • I have attached a screenshot of the output table showing the newly calculated column:
    vssriganesh_0-1739379761825.png

     

  • Additionally, I have attached the PBIX file for your convenience.


If this helps, then please Accept it as a solution and dropping a "Kudos" so other members can find it more easily.
Hope this works for you!
Thank you.

Hello V-ssriganesh, Thank you for your work. rom your table result your codes do not get the correct result. the Answer shall be: 

Answershallbe
 
1
2
1
 
1
 
 
 
 
 

I have updated the request. please review if the conditions

Akash_Varuna
Super User
Super User

Hi @DSR  , Could you try this 

let
// Example table
Source = Table.FromRows(
{
{"A", 0, "Yr00", 0, 2, 0, 0},
{"A", 1, "Yr01", 0, 2, 1, 1},
{"A", 2, "Yr02", 1, 2, 2, 1},
{"A", 3, "Yr03", 1, 2, 3, 1},
{"A", 4, "Yr04", 1, 2, 4, 0},
{"A", 5, "Yr05", 0, 2, 5, 1},
{"A", 6, "Yr06", 1, 2, 6, 0},
{"A", 7, "Yr07", 0, 2, 7, 0},
{"A", 8, "Yr08", 0, 2, 8, 0},
{"A", 9, "Yr09", 0, 2, 9, 0},
{"A", 10, "Yr10", 0, 2, 10, 0}
},
{"Case.CC.EEName", "PeriodNo", "Yr", "NoEE.inPrvPrd", "Yr Move Out", "Index.inGrp", "NoEE"}
),

// Generate calculated column
AddedColumn = Table.AddColumn(Source, "CalculatedColumn", each null),
ListValues = List.Generate(
() => [Index = 0, PreviousValue = 0], // Start condition
each [Index] < Table.RowCount(Source), // Continue while there are rows
each [
Index = [Index] + 1,
PreviousValue = if Table.Column(Source, "Index.inGrp"){[Index]} = 0 then
0
else if Table.Column(Source, "NoEE"){[Index]} = 0 or Table.Column(Source, "NoEE"){[Index]} = null then
null
else if [PreviousValue] = Table.Column(Source, "Yr Move Out"){[Index]} then
Table.Column(Source, "NoEE"){[Index]}
else
[PreviousValue] + 1
],
each [PreviousValue]
),

// Add ListValues back to the table
Result = Table.FromColumns(Table.ToColumns(Source) & {ListValues}, Table.ColumnNames(Source) & {"CalculatedColumn"})
in
Result
In the above 

  • Recursive Calculation: List.Generate tracks the previous row's value and uses it for the next row.
  • Conditions: Checks are implemented for Index.inGrp , NoEE , and Yr Move Out values as specified.
  • Merge Back: The calculated list is combined back into the table.
    If this post helped please do give a kudos and accept this as a solution 
    Thanks In Advance

 

 

Hello Akash, Thank you for your work. I have applied your codes. Coply below. CalculatedColumn  did not answer correctly when [Index.inGrp] = 1,2,3,4,5

Case.CC.EENamePeriodNoYrNoEE.inPrvPrdYr Move OutIndex.inGrpNoEECalculatedColumn

A0Yr0002000
A1Yr0102110
A2Yr0212211
A3Yr0312312
A4Yr0412401
A5Yr050251null
A6Yr061260null
A7Yr070270null
A8Yr080280null
A9Yr090290null
A10Yr1002100null

Hello Akash,

If I modify the conditions to become:

if Table.Column(ChangedType, "Index.inGrp"){[Index]} = 0 then null
else if Table.Column(ChangedType, "NoEE"){[Index]} = 0 or Table.Column(ChangedType, "NoEE"){[Index]} = null then null
else if [PreviousValue] = 0 or [PreviousValue] = null then 1
else if [PreviousValue] = Table.Column(ChangedType, "Yr Move Out"){[Index]} then Table.Column(ChangedType, "NoEE"){[Index]}
else [PreviousValue] + 1 ],

=======

It resulted in correct numbers but, not aligned,  shifted one row down.

Yr Move OutIndex.inGrpNoEEAnswershallbeCalculatedColumn

200null0
2111null
22121
23112
240null1
2511null
260null1
270nullnull
280nullnull
290nullnull
2100nullnull

Helpful resources

Announcements
August Power BI Update Carousel

Power BI Monthly Update - August 2025

Check out the August 2025 Power BI update to learn about new features.

August 2025 community update carousel

Fabric Community Update - August 2025

Find out what's new and trending in the Fabric community.

Top Solution Authors