Tutorials/Power Apps/Add Sequential Row Numbers to Any Power Apps Collection
Power Appsintermediate

Add Sequential Row Numbers to Any Power Apps Collection

Tag each record in an in-memory collection with a unique row number using Sequence, Patch, and ForAll — with no data source changes.

NA
Narmer Abader
@narmer · Published June 3, 2026

Need a numbered list of records inside a gallery, but your data source doesn't include a row index? Adding a sequential row number to a local collection is a common pattern, especially when you work with temporary data, reorder records, or paginate manually. This walkthrough shows a compact formula that uses ForAll, Sequence, and Patch to generate a RowNumber column in any collection.

Example Scenario: Employee List

Imagine you have a small collection of employees stored as a local variable in your app.

NameDepartment
AliceSales
BobMarketing
CarolSales
DavidEngineering
EveMarketing

Your goal is to display these names in a gallery with a leading number — 1, 2, 3, … — so the user can quickly refer to a record.

Step-by-Step Implementation

1. Create the Source Collection

In a button’s OnSelect, define the input set:

powerfxCreate the employee collection
ClearCollect(colEmployees,
  {Name:"Alice",  Dept:"Sales"},
  {Name:"Bob",    Dept:"Marketing"},
  {Name:"Carol",  Dept:"Sales"},
  {Name:"David",  Dept:"Engineering"},
  {Name:"Eve",    Dept:"Marketing"}
);

2. Add Row Numbers to the Collection

Run the following formula right after you create the collection (or whenever a fresh numbering is needed):

powerfxGenerate row numbers
ClearCollect(colNumberedEmployees,
  ForAll(
      Sequence(CountRows(colEmployees)),

      // For each number N, take the Nth record and add RowNumber
      Patch(
          Last(FirstN(colEmployees, Value)),
          {RowNumber: Value}
      )
  )
);

The result is a new collection, colNumberedEmployees with an added numeric column.

RowNumberNameDepartment
1AliceSales
2BobMarketing
3CarolSales
4DavidEngineering
5EveMarketing

You can now bind a gallery to colNumberedEmployees and show RowNumber as the label.

3. How the Formula Works

  • CountRows(colEmployees) returns 5.
  • Sequence(5) generates a table of numbers: [1, 2, 3, 4, 5].
  • ForAll iterates over each number, calling Patch on the Nth record.
  • FirstN(colEmployees, Value) returns the first N records (e.g., for Value=3, the first three rows).
  • Last(…) extracts the Nth record (the third row in this example).
  • Patch appends a column called RowNumber with the current Value.
  • The outer ClearCollect stores the resulting table into a separate collection so you don’t accidentally lose the original data.
Side effect on source collection

Note that Patch modifies the source collection colEmployees in-place. In the example above we still have the original untouched because we used a separate target colNumberedEmployees. If you want to keep the original collection unchanged, consider using the alternative pattern described later.

Performance & Delegation

  • Sequence and ForAll run client‑side on the device. The formula is acceptable for collections with up to a few hundred records.
  • Because CountRows on a collection is not delegated, you cannot use this approach for a large data source directly. Filter first to a reasonable size.
  • For galleries of thousands of records, consider adding the row number in the data source itself (e.g., a SQL identity column) or use paginated counting.

Alternative Pattern That Avoids Mutating the Original

If you need to leave the original collection unchanged, you can combine With and Collect to build the numbered collection without side effects:

powerfxNon‑destructive row numbering
ClearCollect(colNumberedEmployees,
  ForAll(
      Sequence(CountRows(colEmployees)),
      With(
          {record: Last(FirstN(colEmployees, Value))},
          {RowNumber: Value, Name: record.Name, Dept: record.Dept}
      )
  )
);

This explicitly copies each field, so the original colEmployees stays unmodified.

Common Mistakes & Troubleshooting

  • Empty source collection: If the collection is empty, CountRows returns 0 and Sequence produces an empty table. Add a guard condition (If(CountRows(colEmployees) > 0, …)).
  • One‑based index: Sequence starts at 1 by default. If you need a different start, use Sequence(Count, Start).
  • Forgot to store the result: The formula without ClearCollect only returns the result table but doesn’t save it. Always wrap in ClearCollect or assign to a variable.
  • Column name collision: If the source already has a column named RowNumber, Patch will overwrite its values. Rename the output column to something unique like SeqID.

Recommendation

Use the ForAll/Sequence/Patch pattern when you need a quick row‑number column for display in a gallery or list. It’s concise, easy to copy into any app, and works entirely client‑side. For collections that remain read‑only in the app, prefer the non‑destructive alternative to avoid accidental mutation.

References