WRAPROWS & WRAPCOLS in Excel: Reshape One-Dimensional Arrays into Grids

WRAPROWS and WRAPCOLS functions in Excel 365 — showing a flat list of nine values reshaped into a 3×3 grid two ways: WRAPROWS filling left-to-right row by row in green, and WRAPCOLS filling top-to-bottom column by column in teal, with key formulas for a dynamic calendar, filtered display grid, and WRAPCOLS product catalogue layout.
A flat list of 12 months becomes a 3×4 calendar grid. A 50-item product column reshapes into a 5×10 display table. WRAPROWS and WRAPCOLS perform this transformation in one formula. WRAPROWS fills left-to-right and wraps to the next row. WRAPCOLS fills top-to-bottom and wraps to the next column. This guide covers eight examples: basic grid reshaping with scan direction comparison, controlling the pad_with argument for partial rows, a dynamic self-updating calendar using SEQUENCE, a product catalogue display grid, filtered display grids via WRAPROWS+FILTER, pairing two columns with TOCOL+HSTACK, reshaping survey data into a month-by-question grid, and a dynamic wrap count that auto-resizes to a target number of columns.

A flat list of 12 months becomes a 3×4 calendar grid. A single column of 50 products reshapes into a 5×10 display table. WRAPROWS and WRAPCOLS perform this transformation in one formula. They take a one-dimensional array and wrap it into a two-dimensional grid by specifying how many items appear in each row or column. Both are Excel 365 functions that replaced a cumbersome INDEX+MOD+INT construction that previously required array entry and careful row/column arithmetic.

This guide covers both functions fully with eight practical examples. You will learn how to reshape a product list into a display grid, build a dynamic calendar, handle remainders with custom padding, create a comparison table from alternating columns, and combine WRAPROWS with SORT and FILTER for formatted dynamic outputs. Each example also explains the pad argument — the key that controls what appears in the incomplete final row or column.

Availability: WRAPROWS and WRAPCOLS are available in Excel 365 only (August 2022 or later). They are not in Excel 2021, 2019, or Google Sheets. Both spill automatically and do not require array entry.

What Are WRAPROWS and WRAPCOLS?

WRAPROWS takes a one-dimensional array and wraps it into rows of a specified width. After each wrap_count items, it starts a new row. WRAPCOLS does the same but fills columns instead — after wrap_count items it starts a new column. Together they cover the two directions in which you might want to tile a flat list into a grid.

The key distinction is fill direction. WRAPROWS fills horizontally: it places items left-to-right across a row, then drops to the next row. WRAPCOLS fills vertically: it places items top-to-bottom in a column, then moves to the next column. If the total number of items does not divide evenly by the wrap count, the last row or column has fewer items. The pad argument fills those empty positions with a value of your choice — typically a blank string, zero, or NA().

What Is the WRAPROWS and WRAPCOLS Syntax?

=WRAPROWS(vector, wrap_count, [pad_with]) =WRAPCOLS(vector, wrap_count, [pad_with])
ArgumentRequired?Description
vectorRequiredA one-dimensional array (single row or single column). Multi-dimensional arrays return an error. Use TOCOL or TOROW first to flatten a 2D range.
wrap_countRequiredThe number of items per row (WRAPROWS) or per column (WRAPCOLS). Must be a positive integer. This determines the grid width or height.
pad_withOptionalThe value to fill any empty positions in the final partial row/column. Default is #N/A. Use "" for blank, 0 for zero, or NA() to keep the default error-style padding.
WRAPROWS vs WRAPCOLS at a glance: WRAPROWS fills left-to-right then wraps to the next row — like text on a page. WRAPCOLS fills top-to-bottom then wraps to the next column — like a newspaper column. Use WRAPROWS when each row is a "group" of items. Use WRAPCOLS when each column is a "group."

Examples 1–8: WRAPROWS and WRAPCOLS in Practice

1
Basic reshape — flat list into a grid

The core use is converting a single column of values into a grid of specified width. WRAPROWS produces one row per group. WRAPCOLS produces one column per group. Both are one-formula replacements for the old INDEX+MOD+INT approach.

Source (A2:A10)
WRAPROWS(A,3) result
WRAPCOLS(A,3) result
1,2,3,4,5,6,7,8,9
1 2 3
Row 1
1 4 7
Col tops
4 5 6
Row 2
2 5 8
Col mids
7 8 9
Row 3
3 6 9
Col bottoms
A2:A10 = {1,2,3,4,5,6,7,8,9} (9 values, single column). WRAPROWS — wrap into rows of 3 (produces a 3×3 grid): =WRAPROWS(A2:A10, 3) → {{1,2,3},{4,5,6},{7,8,9}} — fills left-to-right then new row WRAPCOLS — wrap into columns of 3 (produces a 3×3 grid): =WRAPCOLS(A2:A10, 3) → {{1,4,7},{2,5,8},{3,6,9}} — fills top-to-bottom then new column Old equivalent (INDEX + MOD + INT — required array entry): D1 = start row, D2 = wrap width. {=INDEX(A$2:A$10, (ROW(A1)-1)*D2+COLUMN(A1))} → WRAPROWS replaces this with a single clean formula
2
Handling remainders — the pad_with argument

When the item count does not divide evenly by wrap_count, the last row or column is shorter than the others. The pad_with argument fills those empty positions. Without it, the default padding is #N/A. For most display purposes, use an empty string "" for blank padding. For formulas that need to calculate on the grid, use 0 or a specific sentinel value.

A2:A11 = 10 items. wrap_count = 3. 3 rows of 3 = 9 items used. 1 item left over in the 4th row. The 4th row has 1 real value and 2 padded positions. Default padding (#N/A) — causes errors in formulas that use the result: =WRAPROWS(A2:A11, 3) → Row 4: {10, #N/A, #N/A} (last 2 positions padded with error) Blank padding — empty string fills the unused positions: =WRAPROWS(A2:A11, 3, "") → Row 4: {10, "", ""} (visually clean, no errors) Zero padding — useful when the grid feeds into SUM or AVERAGE: =WRAPROWS(A2:A11, 3, 0) → Row 4: {10, 0, 0} (SUM of each row still counts correctly) NA() padding — same as default but explicitly specified: =WRAPROWS(A2:A11, 3, NA()) → Row 4: {10, #N/A, #N/A} (same as omitting pad_with)
3
Dynamic calendar grid — reshape month dates into a 7-column week layout

A calendar is a flat sequence of dates wrapped into rows of seven. WRAPROWS handles this in one formula. The starting point is a SEQUENCE of date values. Wrapping that sequence into rows of 7 produces the seven-column weekly layout. Additionally, padding with blank strings fills the last partial week without showing errors.

D1 = first day of the target month (e.g. DATE(2025,1,1)). SEQUENCE generates all the dates in the month. Calculate number of days in the month: DAY(EOMONTH(D1, 0)) → 31 for January, 28 or 29 for February, etc. Generate all dates for the month: =SEQUENCE(DAY(EOMONTH(D1, 0)), 1, D1) → Vertical array of all dates in the month Wrap dates into a 7-column (weekly) grid with blank padding: =WRAPROWS( SEQUENCE(DAY(EOMONTH(D1, 0)), 1, D1), 7, "" ) → Spills a grid of dates, 7 per row (one row per week) Last row padded with blanks for the partial final week Format each date cell as "d" (day number only) for a clean calendar display. Column headers: {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}
4
Product display grid — reshape a sorted product list into catalogue columns

A single-column product list is easy to sort and filter but hard to display in a compact catalogue format. WRAPCOLS reshapes it into multiple columns, filling top-to-bottom so each column reads vertically like a traditional catalogue. This is specifically useful for price lists, inventory tables, and option menus where vertical scanning is more natural than horizontal.

A2:A50 = sorted product names (49 items). Goal: display in 5 columns (10 items per column, 10×5 grid). WRAPCOLS wraps into columns of 10: Each column holds 10 products, reading top-to-bottom. =WRAPCOLS(SORT(A2:A50), 10, "") → 10-row × 5-column product grid, sorted alphabetically, blank-padded Dynamic column count — D1 = number of columns wanted: Items per column = CEILING(total / columns, 1). =WRAPCOLS( SORT(A2:A50), CEILING(ROWS(A2:A50) / $D$1, 1), "" ) → Adjusts rows-per-column automatically when D1 changes Include prices alongside products — pass a 2-col array: TOCOL flattens the 2-column range first, then WRAPCOLS reshapes. Not ideal for multi-column sources — see Example 8 for a cleaner approach.

Examples 5–8: Advanced WRAPROWS and WRAPCOLS

5
WRAPROWS with FILTER — display filtered results as a grid

Combining FILTER with WRAPROWS produces a filtered grid that updates automatically as data changes. This is particularly useful for dashboards where filtered results need to be shown in a compact tiled layout rather than a long vertical list. The wrap count controls how many items appear per row.

A2:A200 = product names. B2:B200 = categories. C2:C200 = prices. Goal: show all products in "Electronics" as a 4-across grid. Filter Electronics products, then wrap into rows of 4: =WRAPROWS( FILTER(A2:A200, B2:B200="Electronics", "None"), 4, "" ) → Filtered product names, 4 per row, blank-padded Sorted and filtered grid (sort by price ascending before wrapping): =WRAPROWS( CHOOSECOLS( SORT(FILTER(A2:C200, B2:B200="Electronics"), 3), 1 ), 4, "" ) → Electronics products sorted cheapest-first, 4 across Dynamic wrap count from a cell (D1): Change D1 to see more or fewer items per row without editing the formula. =WRAPROWS( FILTER(A2:A200, B2:B200="Electronics", "None"), $D$1, "" )
6
Interleave two lists — pair rows from two columns side by side

WRAPROWS with wrap_count = 2 on an interleaved sequence creates a side-by-side pairing of two lists. This is useful for creating before/after tables, comparing two score sets, or pairing names with values. The interleaving requires combining both arrays into a single flat vector first, then wrapping into pairs.

A2:A10 = names {Alice,Bob,...}. B2:B10 = scores {87,72,...}. Goal: display as two-column pairs: Name | Score. Step 1: Interleave the two columns into a flat sequence using VSTACK+TRANSPOSE: TOCOL(HSTACK(A2:A10, B2:B10)) reads row by row: Alice,87,Bob,72,... =TOCOL(HSTACK(A2:A10, B2:B10)) → {Alice,87,Bob,72,Carol,65,...} Step 2: Wrap into rows of 2 (each pair = Name + Score): =WRAPROWS( TOCOL(HSTACK(A2:A10, B2:B10)), 2 ) → {{Alice,87},{Bob,72},{Carol,65},...} A two-column Name | Score table from two separate input columns Three-column grouping (Name, Score, Date): Same pattern with HSTACK of 3 columns and wrap_count = 3. =WRAPROWS( TOCOL(HSTACK(A2:A10, B2:B10, C2:C10)), 3 )
7
Comparison grid — reshape survey responses into a month×question grid

Survey data often arrives as a long flat list of responses: question 1 January, question 2 January, question 3 January, question 1 February, and so on. WRAPROWS reshapes this into a readable month-by-question grid. The wrap count equals the number of questions per month.

A2:A36 = 36 survey responses. Layout: 3 questions × 12 months = 36 values, ordered Q1M1, Q2M1, Q3M1, Q1M2... Goal: reshape into a 12-row × 3-column grid (one row per month). Wrap into rows of 3 (3 questions per row = one month per row): =WRAPROWS(A2:A36, 3, "") → 12×3 grid: each row is one month, each column is one question Row labels — add month names alongside the grid using HSTACK: D2 = month name array (Jan,Feb,...,Dec). =HSTACK( D2:D13, =WRAPROWS(A2:A36, 3, "") ) → Month name + 3 question columns (4-column output) Average per question (column-wise summary): BYROW or SUBTOTAL on the WRAPROWS result. Or use MMULT to calculate the column means in one step. =MMULT( TRANSPOSE(=WRAPROWS(A2:A36, 3)), SEQUENCE(ROWS(=WRAPROWS(A2:A36,3)), 1, 1, 0) ) / 12 → Average response per question across all 12 months
8
Dynamic wrap count — auto-size the grid to fit a target number of rows or columns

Hard-coding the wrap count requires manual updates when the data size changes. A dynamic wrap count calculated from the data length and a target column count adjusts automatically. This is the right approach for any report where the number of items grows over time.

A2:A200 = data (variable number of items, may grow month to month). D1 = target number of columns in the output grid. Dynamic wrap count — items per row = CEILING(n / target_cols, 1): COUNTA counts the actual number of non-blank items. =CEILING(COUNTA(A2:A200) / $D$1, 1) → e.g. CEILING(49/5, 1) = 10 (rows per column for 5 columns) Full dynamic WRAPCOLS formula: Wrap count adjusts when data grows or D1 changes. =WRAPCOLS( FILTER(A2:A200, A2:A200<>""), CEILING(COUNTA(A2:A200) / $D$1, 1), "" ) → Automatically resizes to D1 columns as items are added Reverse: fix the number of ROWS instead of columns. D2 = target number of rows. wrap_count = CEILING(n / D2, 1) produces that many items per row. =WRAPROWS( FILTER(A2:A200, A2:A200<>""), CEILING(COUNTA(A2:A200) / $D$2, 1), "" ) → Produces a grid with exactly D2 rows (adjusts columns automatically)

Common Issues and How to Fix Them

WRAPROWS returns #VALUE! with a 2D range

WRAPROWS and WRAPCOLS require a one-dimensional vector. Passing a multi-column range directly returns #VALUE!. First flatten the range using TOCOL (column-major order) or TOROW (row-major order), then pass the result to WRAPROWS or WRAPCOLS. For example, =WRAPROWS(TOCOL(A2:C10), 3) flattens the 3-column range into a single column before wrapping.

The last row has unwanted #N/A errors

The default pad_with value is #N/A, which fills incomplete rows with errors. This is intentional — it signals that a position has no data. However, it causes problems when the result feeds into formulas like SUM or AVERAGE. Always specify pad_with explicitly: use "" for blank cells or 0 for numeric zero. Using IFERROR on the result is a workaround but less clean than setting pad_with correctly from the start.

WRAPROWS and WRAPCOLS only work with 1D arrays: Pass a single-column or single-row range, or the output of a function that produces a 1D result. Multi-dimensional ranges must be flattened first with TOCOL or TOROW. Additionally, wrap_count must be a positive integer — fractions, zero, and negative numbers all return errors.

Frequently Asked Questions

  • What is the difference between WRAPROWS and WRAPCOLS?+
    WRAPROWS fills a grid left-to-right and wraps to the next row after each wrap_count items — like text on a page. WRAPCOLS fills top-to-bottom and wraps to the next column after each wrap_count items — like newspaper columns. The same flat list of items produces different grids depending on which function you use. Choose WRAPROWS when each row represents a logical group (e.g. one week of days). Choose WRAPCOLS when each column represents a logical group (e.g. one alphabetical section of a product catalogue).
  • How do I control what fills the empty positions in the last row?+
    Use the third argument (pad_with). The default is #N/A. For blank cells, use "". For zeros, use 0. For a custom label like "—", pass that text string. The pad_with value appears only in the positions that have no corresponding source value — it does not affect any complete rows or columns. If you are building a visual display grid, "" is the most common choice. If the grid feeds into calculations, use 0 to avoid errors in SUM and AVERAGE formulas.
  • Can I use WRAPROWS with a 2D range?+
    Not directly — WRAPROWS requires a one-dimensional vector. However, you can first flatten a 2D range using TOCOL (reads column by column) or TOROW (reads row by row), then pass the result to WRAPROWS. For example, =WRAPROWS(TOCOL(A2:C10), 3) flattens the 3×9 range into a 27-item column, then wraps it into 9 rows of 3. The order of flattening matters, so choose TOCOL or TOROW based on which reading order you want.
  • How do I build a dynamic calendar using WRAPROWS?+
    Generate all dates in the month using SEQUENCE(DAY(EOMONTH(D1,0)), 1, D1) where D1 is the first day of the month. Then wrap into rows of 7 with a blank pad: =WRAPROWS(SEQUENCE(DAY(EOMONTH(D1,0)),1,D1), 7, ""). Format the result cells as "d" (day number only) for a clean calendar display. Add column headers for Mon through Sun above the formula cell. Change D1 to a different month and the calendar updates automatically.