Wauvel

Excel like a finance pro.

← All VBA snippets

Turn a month-by-column grid into a list

Finance data arrives as a cross-tab. Everything downstream wants rows.

1What it does

Accounts down the side, months across the top: that's how finance data arrives and how humans read it. It's also the one shape a pivot table, a lookup and a chart all refuse to work with properly. Unpivoting turns one row of twelve months into twelve rows of account-month-amount, which is what every tool actually wants. The loop is short — walk the columns inside a walk of the rows, writing one output row per cell — and it replaces a reshaping job people do by hand every single month.

2The code

Sub UnpivotToList()
    Dim src As Worksheet, out As Worksheet
    Dim lastRow As Long, lastCol As Long
    Dim r As Long, c As Long, n As Long

    Set src = ThisWorkbook.Worksheets("Grid")

    ' Rebuild the output sheet from scratch each run.
    On Error Resume Next
    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets("List").Delete
    Application.DisplayAlerts = True
    On Error GoTo 0

    Set out = ThisWorkbook.Worksheets.Add
    out.Name = "List"
    out.Range("A1:C1").Value = Array("Account", "Month", "Amount")

    lastRow = src.Cells(src.Rows.Count, 1).End(xlUp).Row
    lastCol = src.Cells(1, src.Columns.Count).End(xlToLeft).Column

    n = 1
    For r = 2 To lastRow                    ' each account
        For c = 2 To lastCol                ' each month column
            If src.Cells(r, c).Value <> "" Then
                n = n + 1
                out.Cells(n, 1).Value = src.Cells(r, 1).Value   ' account
                out.Cells(n, 2).Value = src.Cells(1, c).Value   ' month header
                out.Cells(n, 3).Value = src.Cells(r, c).Value   ' amount
            End If
        Next c
    Next r

    out.Columns("A:C").AutoFit
    MsgBox "Wrote " & n - 1 & " rows.", vbInformation
End Sub

Paste into the Visual Basic Editor (Alt + F11 → Insert → Module), then run and save as macro-enabled (.xlsm).

New to macros? Set up in 5 minutes
  1. 1

    Don't see the Developer tab in the ribbon?

    You don't strictly need it — Alt + F11 opens the editor directly — but it makes running macros easier.
    • Windows: File → Options → Customize Ribbon → tick Developer in the right-hand list → OK.
    • Mac: Excel → Preferences → Ribbon & Toolbar → tick Developer → Save.
  2. 2

    Paste in the code

    Press Alt + F11 to open the Visual Basic editor, then Insert → Module and paste the snippet's code into the blank window. Close it with Alt + Q.
  3. 3

    Run it

    Press Alt + F8, pick the macro's name, and click Run — that's it. (Pasted a custom function instead? Just type it into a cell like any built-in: =GrossMargin(B2, B3).)
  4. 4

    Keep the macro — save as .xlsm

    File → Save As → Excel Macro-Enabled Workbook (.xlsm). A plain .xlsx silently drops the code when you save.
  5. 5

    Macros blocked?

    Click Enable Content on the yellow bar. If you downloaded the file, you may first need to right-click it → Properties → tick Unblock → OK, then reopen.

Heads up: macros can't be undone with Ctrl + Z — save a copy before running one that changes your workbook.

3When you use it

  • Make a monthly grid usable by a pivot table.
  • Turn a budget laid out by column into something a lookup can read.
  • Prepare data for a chart that wants one series per row.

4See it in action

A simulation — press Run to perform what the macro does to a sample workbook.

Grid — how finance data arrives

AccountJulAugSep
Revenue$41,000$38,500$44,100
COGS$23,400$22,100$25,800
Travel$3,100$2,400

Humans read the grid. Pivots, lookups and charts all want the list. This is the reshaping people redo by hand every month.

5Pitfalls

Blank cells become rows of zero, inflating the count and every average downstream.

Fix: Skip them — the `If src.Cells(r, c).Value <> ""` test above.

Month headers come out as text when they were dates, so a later sort goes alphabetical.

Fix: Write the header's `.Value` (which keeps the date) rather than `.Text`, and format the output column as a date.

Cell-by-cell writing is slow on a large grid — a 40 × 12 grid is 480 separate writes.

Fix: For anything big, read into an array and write the result in one go. See the array read/write snippet.

Re-running appends to the old output, so the list doubles.

Fix: Delete and rebuild the sheet each run, with DisplayAlerts off so the deletion doesn't prompt.

6No-code alternatives

  • Power Query — Unpivot Columns Genuinely better if you'll do this repeatedly: select the month columns, right-click, Unpivot. No code, and it refreshes.
  • A pivot table's own source Doesn't help — a pivot needs the list shape to begin with, which is the whole problem.

Rather not write macros? Wauvel's free tools generate branded, formula-driven Excel for you — no VBA required.

Learn the moves here — or let Wauvel run them on your numbers.

Meet your AI CFO →

One CFO-grade Excel tip a week

A short, practical email for finance operators — functions, shortcuts, and the moves that save an afternoon. Free, unsubscribe anytime.