Excel CHOOSEROWS Function: Select Exact Rows by Position with One Spill
The CHOOSEROWS function extracts specific rows from an array by their position numbers. Instead of extracting the first or last N rows, CHOOSEROWS lets you cherry-pick exact rows – get row 3, row 7, row 15, and row 2 in any order you want. This precision targeting makes CHOOSEROWS essential for custom row selection, reordering data, and building filtered views without manual manipulation.
What Does the CHOOSEROWS Function Do?
CHOOSEROWS selects rows from an array by specifying their row positions explicitly. You can select individual rows, multiple rows in any order, and even repeat rows if needed. Unlike TAKE which extracts a contiguous block from the beginning or end, CHOOSEROWS gives you granular control over exactly which rows appear in your output.
This function excels at reordering data, extracting non-contiguous rows, highlighting specific records, and building custom selections from larger datasets. When combined with ROW, SEQUENCE, MATCH, and other functions, CHOOSEROWS enables sophisticated row-level data manipulation that would require complex helper columns or manual work in traditional Excel.
CHOOSEROWS Syntax and Arguments
=CHOOSEROWS(array, row_num1, [row_num2], ...)
- array (required): The source array or range from which to extract rows. This can be a cell range (like A1:D100) or an array returned by other dynamic functions.
- row_num1 (required): The position of the first row to extract (1 = first row, 2 = second row, etc.).
- row_num2 through row_num254 (optional): Additional row positions to extract. You can specify up to 254 row position arguments in a single formula.
Key Rules:
- Row positions must be positive integers (1 or greater).
- Row positions must be less than or equal to the total number of rows in the array.
- You can select the same row multiple times (row will appear multiple times in output).
- Row order in the output matches the order of your position arguments.
- You can specify up to 254 different row selections.
- CHOOSEROWS spills automatically across all selected rows.
Key Behaviors and Important Notes
- Exact positioning: CHOOSEROWS returns rows in the exact order you specify. CHOOSEROWS(A1:D10, 3, 1, 5) returns row 3, then row 1, then row 5.
- Spill behavior: CHOOSEROWS is a dynamic array function that automatically spills. Occupied cells cause
#SPILL!error. - Duplicate rows allowed: You can select the same row multiple times. CHOOSEROWS(A1:D10, 1, 1, 1) returns the first row three times.
- #NUM! for invalid positions: Requesting a row number greater than the array size returns
#NUM!error. - #VALUE! for invalid arguments: Non-integer row positions or missing required arguments trigger
#VALUE!. - All columns preserved: CHOOSEROWS always returns all columns from the source array; it only filters rows.
- Live updates: When source data changes, CHOOSEROWS adapts if the specified rows exist.
Basic Examples
Example 1: Extract specific individual rows
You have data in A1:D100 and want rows 5, 12, and 8 (in that order):
=CHOOSEROWS(A1:D100, 5, 12, 8)
Result: A 3×4 array containing rows 5, 12, and 8 from the source, in exactly that order.
Example 2: Reorder rows
Reverse row order by selecting in reverse sequence:
=CHOOSEROWS(A1:D10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
Result: All 10 rows in reverse order (bottom-to-top instead of top-to-bottom).
Example 3: Duplicate rows
Extract specific rows multiple times for comparison:
=CHOOSEROWS(A1:D100, 1, 1, 50, 100, 100)
Result: Row 1 appears twice, followed by rows 50 and 100 (100 appears twice). Useful for before-and-after comparisons.
Example 4: Skip rows using row numbers
Select only odd-numbered rows from the first 10:
=CHOOSEROWS(A1:D10, 1, 3, 5, 7, 9)
Result: A 5×4 array with only odd-numbered rows.
Example 5: Extract header and selected data rows
Include header row plus specific data rows:
=CHOOSEROWS(A1:D100, 1, 5, 10, 15, 20)
Result: Header row followed by data from rows 5, 10, 15, and 20.
Example 6: Alternating pattern selection
Select alternating rows for pattern analysis:
=CHOOSEROWS(A1:D20, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
Result: All even-numbered rows from the range.
Creating Custom Row Selections
Highlight specific employees
Extract rows for employees needing attention:
=VSTACK(
{"Employee Review List"},
CHOOSEROWS(HR!A:F, 1, 3, 7, 15, 22)
)
Creates a focused list with header plus five specific employees for performance review.
Sample-based quality check
Extract predetermined rows for QA inspection:
=CHOOSEROWS(
Production_Log,
1,
10,
25,
50,
75,
100
)
Selects header and specific rows spaced throughout the dataset for sampling.
Before-after comparison
Compare same row at different time periods:
=HSTACK(
VSTACK({"Before"}, CHOOSEROWS(January_Data, 5, 12, 20)),
VSTACK({"After"}, CHOOSEROWS(March_Data, 5, 12, 20))
)
Shows the same customer records from different months side-by-side for trend analysis.
Milestone tracking
Extract key milestone records:
=CHOOSEROWS(
Project_Timeline,
1,
1,
ROWS(Project_Timeline)
)
Shows header, first activity, and final activity in the project timeline.
Advanced Function Combinations
CHOOSEROWS + MATCH for lookup-based selection
=CHOOSEROWS(
Employee_Data,
1,
MATCH("Smith", Employee_Data[Name], 0),
MATCH("Johnson", Employee_Data[Name], 0),
MATCH("Williams", Employee_Data[Name], 0)
)
Selects specific employees by name using MATCH to find their row positions dynamically.
CHOOSEROWS + SEQUENCE for pattern extraction
=CHOOSEROWS(
A1:D100,
SEQUENCE(20) * 5
)
Extracts every 5th row (rows 5, 10, 15, 20… up to 100).
CHOOSEROWS + SORT for reordering
=CHOOSEROWS(
SORT(Sales_Data, 4, -1),
1,
2,
3,
4,
5
)
Sorts data by sales descending, then takes header plus top 5 sales records.
CHOOSEROWS with IF for conditional selection
=CHOOSEROWS(
Data,
1,
IF(Condition_A, 5, ""),
IF(Condition_B, 10, ""),
IF(Condition_C, 15, "")
)
Selects rows conditionally based on parameter values.
CHOOSEROWS + FILTER + MATCH for smart selection
=CHOOSEROWS(
Employee_Data,
1,
MATCH("Manager", FILTER(Employee_Data[Title], Employee_Data[Dept] = "Sales"), 0)
)
Finds and selects the manager in the Sales department among filtered results.
Multi-layer selection with nested CHOOSEROWS
=CHOOSEROWS(
CHOOSEROWS(All_Data, 1, 5, 10, 15, 20),
1,
3,
5
)
First extracts specific rows, then from those selections, extracts specific rows again.
Real-World Applications
Auditor sample selection
Pull predetermined rows for compliance auditing:
=VSTACK(
{"Audit Sample - Transactions to Review"},
CHOOSEROWS(
Transaction_Log,
1,
50,
100,
150,
200,
250,
300,
350,
400,
450
)
)
Selects 10 specific transactions spaced throughout the period for audit verification.
Executive steering committee agenda items
Build agenda from specific action items:
=VSTACK(
{"Executive Steering Committee - Key Items"},
CHOOSEROWS(
All_Action_Items,
1,
MATCH("Budget Approval", All_Action_Items[Item], 0),
MATCH("Staffing Plan", All_Action_Items[Item], 0),
MATCH("Q4 Strategy", All_Action_Items[Item], 0)
)
)
Automatically pulls specific agenda items by name, updating if content changes.
Clinical trial cohort selection
Extract specific patient records for study:
=CHOOSEROWS(
Patient_Registry,
1,
Patient_IDs_To_Include
)
Selects header plus specific patients identified for the study.
Portfolio performance comparison
Compare same funds at different review dates:
=HSTACK(
VSTACK({"Q1 Performance"}, CHOOSEROWS(Q1_Data, 1, 2, 5, 8)),
VSTACK({"Q4 Performance"}, CHOOSEROWS(Q4_Data, 1, 2, 5, 8))
)
Shows same fund selections from different quarters for performance tracking.
Quality control first/middle/last inspection
Sample first, middle, and last items from production batch:
=CHOOSEROWS(
Production_Batch,
1,
1,
ROUNDUP(ROWS(Production_Batch)/2, 0),
ROWS(Production_Batch)
)
Selects header, first item, middle item, and last item for quick QA assessment.
Dynamic Row Selection Patterns
Pattern 1: Top N with headers
=CHOOSEROWS(Sorted_Data, 1, 2, 3, 4, 5)
After sorting externally or within another formula, get header plus top 5.
Pattern 2: Specific employees by name
=VSTACK(
{"Selected Employees"},
CHOOSEROWS(
HR_Data,
1,
MATCH("Alice", HR_Data[Name], 0),
MATCH("Bob", HR_Data[Name], 0),
MATCH("Carol", HR_Data[Name], 0)
)
)
Pattern 3: Quarterly milestone rows
=CHOOSEROWS(
Monthly_Data,
1,
3,
6,
9,
12
)
Pattern 4: Reverse order for comparison
=CHOOSEROWS(
Current_Data,
ROWS(Current_Data),
ROWS(Current_Data) - 1,
ROWS(Current_Data) - 2
)
Pattern 5: Key reference rows plus recent additions
=CHOOSEROWS(
Dataset,
1,
2,
3,
ROWS(Dataset) - 2,
ROWS(Dataset) - 1,
ROWS(Dataset)
)
CHOOSEROWS vs. Related Functions
| Function | Use Case | Example |
|---|---|---|
| CHOOSEROWS | Select exact specific rows by position | =CHOOSEROWS(A1:D100, 5, 12, 8) |
| TAKE | Extract first or last N rows | =TAKE(A1:D100, 10) or =TAKE(A1:D100, -5) |
| DROP | Remove first or last N rows | =DROP(A1:D100, 5) or =DROP(A1:D100, -5) |
| FILTER | Select rows based on criteria | =FILTER(A1:D100, B1:B100 > 100) |
| SORT | Reorder rows by column values | =SORT(A1:D100, 3, -1) |
Common Mistakes and How to Avoid Them
Mistake 1: Using 0 for row position
Row numbering starts at 1, not 0.
Wrong: =CHOOSEROWS(A1:D100, 0, 5, 10) → #NUM! error
Correct: =CHOOSEROWS(A1:D100, 1, 5, 10)
Mistake 2: Exceeding array row count
Requesting a row number greater than the array size returns an error.
Wrong: =CHOOSEROWS(A1:A10, 15) → #NUM! error
Correct: Verify array has at least 15 rows before referencing row 15
Mistake 3: Forgetting headers in output
If you want headers but only select data rows, headers disappear.
Wrong: =CHOOSEROWS(A1:D100, 5, 10, 15) (no header)
Correct: =CHOOSEROWS(A1:D100, 1, 5, 10, 15) (includes header in row 1)
Mistake 4: Confusing row position with row values
CHOOSEROWS uses position numbers (1st, 2nd, 3rd row), not the values within rows.
Wrong thinking: “I want rows where ID = 5” → That’s FILTER, not CHOOSEROWS
Correct thinking: “I want the 5th row” → That’s CHOOSEROWS
Mistake 5: Not accounting for #SPILL! errors
Occupied cells below or to the right block spilling.
Solution: Place CHOOSEROWS formula in a location with adequate empty space
Mistake 6: Overcomplicated MATCH usage
While CHOOSEROWS + MATCH is powerful, ensure MATCH results are valid row numbers.
Wrong: =CHOOSEROWS(A1:D100, MATCH("xyz", A:A, 0)) if “xyz” doesn’t exist → #N/A
Correct: Use IFERROR or verify the lookup value exists
CHOOSEROWS vs. Alternative Methods
| Method | Pros | Cons |
|---|---|---|
| CHOOSEROWS Formula | Precise row selection, simple syntax, reordering capability, up to 254 rows | Requires Microsoft 365, manual row position entry |
| Manual Copy-Paste | Works in all Excel versions | Time-consuming, error-prone, no automatic updates |
| INDEX + ROW Formula | Works in older Excel, customizable logic | Complex syntax, difficult to maintain for multiple rows |
| Helper Columns + SMALL | Granular control available | Clutters spreadsheet, difficult to reorder, many formulas needed |
| FILTER + Conditional Logic | Good for criteria-based selection | Less precise for specific row position selection |
Availability and Compatibility
CHOOSEROWS is available in Microsoft 365 for Windows, Mac, and Excel for the web. It is not available in perpetual versions like Excel 2019, 2016, or earlier. For older Excel versions, use INDEX, SMALL, or manual selection as alternatives.
Tips for Mastering CHOOSEROWS
- Start with position 1: Include row 1 for headers, unless you specifically want data-only output.
- Use MATCH for names: Instead of hardcoding row numbers, use MATCH to find rows by content dynamically.
- Combine with SEQUENCE: For pattern-based selections (every Nth row), use SEQUENCE with multiplication.
- Leverage reordering: CHOOSEROWS is perfect for reversing or rearranging row order for display.
- Duplicate rows intentionally: Repeat row references to show the same data multiple times in context.
- Document your selections: Explain which rows you’re choosing and why in formula comments.
- Verify row counts: Before deploying, confirm source array has enough rows for all your position references.
- Place strategically: Ensure adequate empty space below and to the right for spilling output.
Troubleshooting Guide
| Error | Cause | Solution |
|---|---|---|
| #SPILL! | Cells to the right or below are occupied | Clear cells in the spill range or move formula to a location with empty space |
| #NUM! | Row position is 0, negative, or exceeds array row count | Use row positions 1 or greater, up to the total rows in the array |
| #VALUE! | Row position argument is not an integer or is missing | Ensure all row_num arguments are whole numbers; verify you have at least one row position |
| #N/A (from MATCH) | MATCH couldn’t find the lookup value | Verify the value exists in the array; use IFERROR if lookup might fail |
| #REF! | Array reference is invalid or deleted | Check that the source range exists and is correctly referenced |
| #NAME? | Function not recognized | Verify Microsoft 365 subscription; update Excel to latest version |
Performance Considerations
- Many row selections: Specifying 200+ row positions might impact performance, though 254 is supported. Test with realistic data.
- Large source arrays: Extracting from very large arrays (1M+ rows) is efficient. Row position lookup is fast regardless of array size.
- Nested functions: Combining CHOOSEROWS with MATCH, SORT, and other functions can reduce performance. Test before deployment.
- Spill range size: Large output ranges consume memory. Monitor spreadsheet responsiveness.
- Dependent formulas: Many formulas referencing CHOOSEROWS output can compound performance impact.
Advanced Scenarios
Dynamic employee promotion list from sorted performance data
=VSTACK(
{"Promotion Candidates - Top 5"},
CHOOSEROWS(
SORT(HR_Performance, 5, -1),
1,
2,
3,
4,
5,
6
)
)
Sorts by performance score descending, then selects header and top 5 performers.
Stratified sampling across cohorts
=VSTACK(
{"Sample Group A"},
CHOOSEROWS(Group_A_Data, 1, 10, 20, 30, 40, 50),
{"Sample Group B"},
CHOOSEROWS(Group_B_Data, 1, 15, 30, 45, 60, 75)
)
Selects stratified samples from two different population groups for analysis.
Quarterly milestone tracking with automatic lookups
=CHOOSEROWS(
Project_Timeline,
1,
MATCH("Phase 1 Complete", Project_Timeline[Status], 0),
MATCH("Phase 2 Complete", Project_Timeline[Status], 0),
MATCH("Final Delivery", Project_Timeline[Status], 0)
)
Finds and extracts key milestone rows automatically based on status descriptions.
Before-after clinical data comparison
=HSTACK(
VSTACK({"Before Treatment"}, CHOOSEROWS(Pre_Treatment, 1, 5, 10, 15, 20)),
VSTACK({"After Treatment"}, CHOOSEROWS(Post_Treatment, 1, 5, 10, 15, 20))
)
Compares the same patient measurements from before and after treatment periods.
Financial year comparison across multiple periods
=HSTACK(
VSTACK({"FY2022"}, CHOOSEROWS(FY2022_Data, 1, 6, 12)),
VSTACK({"FY2023"}, CHOOSEROWS(FY2023_Data, 1, 6, 12)),
VSTACK({"FY2024"}, CHOOSEROWS(FY2024_Data, 1, 6, 12))
)
Compares same quarter data across three fiscal years side-by-side.

