Table.AlternateRows
TableKeeps an initial number of rows, then alternates between skipping and keeping groups of rows.
Syntax
Table.AlternateRows(table as table, offset as number, skip as number, take as number) as tableParameters
| Name | Type | Required | Description |
|---|---|---|---|
table | table | Yes | The table to process. |
offset | number | Yes | The number of rows at the start of the table to keep before the skip/take pattern begins. |
skip | number | Yes | The number of consecutive rows to remove in each cycle. |
take | number | Yes | The number of consecutive rows to keep after each skipped group. |
Return Value
table — A table containing the first offset rows plus the rows kept by the skip/take pattern.
Remarks
Table.AlternateRows first keeps the first offset rows unconditionally. After that it repeats a skip-then-take cycle until the end of the table: it removes the next skip rows, then keeps the next take rows. Note the order: each cycle skips first, so Table.AlternateRows(t, 0, 1, 1) keeps the 2nd, 4th, 6th… rows, while Table.AlternateRows(t, 1, 1, 1) keeps the 1st, 3rd, 5th… rows.
This function is primarily useful when consuming data that has a fixed repeating structure — for example, raw exports where every second row is a separator, or flat files where every Nth row contains a record header that should be discarded after parsing. For purely row-count-based skipping or selection, Table.Skip and Table.FirstN are simpler alternatives.
Be aware that Table.AlternateRows does not typically fold to the data source, so it will be evaluated locally. For large datasets, consider pre-filtering at the source before applying this function.
Examples
Example 1: Sample every other row (keep 1, drop 1)
let
Source = #table(
{"OrderID", "CustomerName", "Product"},
{
{1, "Alice", "Widget A"},
{2, "Bob", "Gadget B"},
{3, "Charlie", "Widget C"},
{4, "Alice", "Gadget D"},
{5, "Diana", "Widget A"},
{6, "Bob", "Thingamajig E"},
{7, "Charlie", "Gadget B"},
{8, "Diana", "Widget C"}
}
)
in
Table.AlternateRows(Source, 1, 1, 1)The final output — Table.AlternateRows keeps the first row (offset 1), then repeatedly skips 1 row and keeps 1 row, so orders 1, 3, 5, and 7 remain.
OrderID | CustomerName | Product | |
|---|---|---|---|
| 1 | 1 | Alice | Widget A |
| 2 | 3 | Charlie | Widget C |
| 3 | 5 | Diana | Widget A |
| 4 | 7 | Charlie | Gadget B |
Example 2: Drop every third row (a repeating divider)
Table.AlternateRows(
#table({"Row"}, {{"A"}, {"B"}, {"SEP"}, {"C"}, {"D"}, {"SEP"}, {"E"}, {"F"}}),
2, 1, 2
)Row | |
|---|---|
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
| 6 | F |
Example 3: Use offset to preserve a header before the pattern starts
Table.AlternateRows(
#table({"Row"}, {{"Header"}, {"SEP"}, {"Data1"}, {"SEP"}, {"Data2"}}),
1, 1, 1
)Row | |
|---|---|
| 1 | Header |
| 2 | Data1 |
| 3 | Data2 |