Stop Writing VBA Macros Blindly — Try This Instead

The first thing most people do when they decide to create scripts in Excel is open the VBA editor (Alt+F11), type Sub MyFirstScript(), and start pasting code from Stack Overflow. That’s like wiring a light switch after watching one YouTube video — it *might* work, but you’ll probably trip the breaker or fry something important.

The Setup

You’re managing quarterly sales data for a small SaaS reseller. Eight reps report deals closed each month, but entries come in messy: inconsistent date formats, duplicate entries flagged as 'REPEAT', missing territories, and revenue entered as text (e.g., "42,500" instead of 42500). You need to clean, standardize, and flag anomalies — not just once, but every time new data drops into Sheet1!A1:E12.
Rep NameDeal DateCompanyRevenueTerritory
Sarah Chen03/15/2024Acme Corp42,500West
Javier Mora2024-03-17Nexus Labs$68,900South
Priya DesaiMar 12 2024Veridian Systems39,200East
Sarah Chen03/15/2024Acme Corp42,500REPEAT
Marcus Lee2024/03/20Tecton Dynamics$55,100North
Aisha Khan03-18-2024Lumina Health28,750West
Javier Mora2024-03-17Nexus Labs68900South
Priya DesaiMar 12 2024Veridian Systems$39,200East
Marcus Lee2024/03/20Tecton Dynamics55100North
Aisha Khan03-18-2024Lumina Health28,750West

The Challenge

You need to create scripts in Excel that handle three things reliably: convert mixed date formats into true Excel dates (so you can sort and filter), strip dollar signs and commas from Revenue and convert to numbers, and replace 'REPEAT' in Territory with blank — but only if the full row matches an earlier entry exactly. The tricky part? You can’t assume users will paste cleanly. And if your script runs twice on the same data, it might double-convert numbers or wipe valid territory names. That’s why how to write scripts for Excel isn’t about typing faster — it’s about designing guards. Every script needs validation at the top: Is this range actually selected? Are cells non-empty? Has this already been processed? We’ll bake those in.

Walking Through It

Let’s build a script step-by-step — not all at once, but as discrete, testable actions. Open the VBA editor with Alt+F11. In the Project Explorer, right-click ThisWorkbook → Insert → Module. Paste this first version:
Sub CleanSalesData()
    Dim rng As Range
    Set rng = Range("A1:E12")
    
    ' Step 1: Convert dates
    With rng.Columns(2)
        .NumberFormat = "yyyy-mm-dd"
        .Value = .Value ' forces re-evaluation
    End With
End Sub
Run it (F5). Nothing changes visibly — but now check cell B2. Its underlying value is now a serial number (45370), not text. That’s critical. Excel won’t sort '03/15/2024' and '2024-03-17' correctly unless both are true dates. Here’s the before/after for column B:
Before (B1:B12)After (B1:B12)
03/15/20242024-03-15
2024-03-172024-03-17
Mar 12 20242024-03-12
03/15/20242024-03-15
2024/03/202024-03-20
Now add Step 2 — cleaning Revenue (column D):
    ' Step 2: Clean revenue
    With rng.Columns(4)
        .Value = Evaluate("IF(ROW(" & .Address & "),SUBSTITUTE(SUBSTITUTE(" & .Address & ",""$"",""),"",""),"")")
        .Value = .Value ' force numeric conversion
    End With
Yes — we used Evaluate. It’s faster than looping through 12 rows, and safer than Replace() when you don’t know where commas sit. (Trust me, I learned this the hard way trying to clean $1,234,567.00.) Before/after for column D:
Before (D1:D12)After (D1:D12)
42,50042500
$68,90068900
39,20039200
42,50042500
$55,10055100
Finally, Step 3 — deduplicate by row and clear 'REPEAT':
    ' Step 3: Flag and clear repeats
    Dim i As Long
    For i = rng.Rows.Count To 2 Step -1
        If Application.WorksheetFunction.CountIfs( _
            rng.Columns(1), rng.Cells(i, 1).Value, _
            rng.Columns(2), rng.Cells(i, 2).Value, _
            rng.Columns(3), rng.Cells(i, 3).Value, _
            rng.Columns(4), rng.Cells(i, 4).Value) > 1 Then
            If rng.Cells(i, 5).Value = "REPEAT" Then rng.Cells(i, 5).ClearContents
        End If
    Next i
Notice we loop backwards (To 2 Step -1). That avoids skipping rows when deleting — a classic gotcha.

The Result

After running the full script, here’s what lives in A1:E12 — clean, sortable, formula-ready, and safe to pivot or chart:
Rep NameDeal DateCompanyRevenueTerritory
Sarah Chen2024-03-15Acme Corp42500West
Javier Mora2024-03-17Nexus Labs68900South
Priya Desai2024-03-12Veridian Systems39200East
Sarah Chen2024-03-15Acme Corp42500
Marcus Lee2024-03-20Tecton Dynamics55100North
Aisha Khan2024-03-18Lumina Health28750West
Javier Mora2024-03-17Nexus Labs68900
Priya Desai2024-03-12Veridian Systems39200
Marcus Lee2024-03-20Tecton Dynamics55100North
Aisha Khan2024-03-18Lumina Health28750West

What Could Go Wrong

Even with careful design, these three mistakes happen constantly — and they’re rarely caught until the report goes out.
SymptomCauseFix
Dates become ###### after runningColumn width too narrow *after* formatting changeAdd rng.Columns(2).AutoFit after date conversion
Revenue shows #VALUE! in some rowsCells contain non-numeric text like "N/A" or "Pending"Wrap Evaluate with IFERROR: Evaluate("IFERROR(...,0)")
Script deletes *all* Territory values, not just REPEATMissing quotes around "REPEAT" in the If statementUse If rng.Cells(i, 5).Value = "REPEAT" Then — not = REPEAT
One more thing: Never save a workbook with scripts as .xlsx. Always use .xlsm. Excel disables macros silently in .xlsx — and there’s no warning until your button stops working. Here’s your quick-reference cheat sheet for how to create scripts in Excel safely:
  • Alt+F11 — Open VBA editor
  • Ctrl+R — Toggle Project Explorer (find your module fast)
  • F5 — Run current macro
  • Alt+Q — Close VBA editor and return to Excel
  • Always wrap core logic in On Error Resume Next + error logging — even for simple scripts
  • Test with MsgBox "Step 1 complete" after each major block
  • Name modules meaningfully: modSalesClean, not Module1
Michael Lee

Michael Lee

Michael covers the latest in office software updates