🚀 New batches open: Advanced Excel • Power BI • SQL • AI for Analytics — Book a free demo
Home / VBA Tutorial / Day 8

Day 8 — Numbers, rounding and dates

Two things break reports more than anything else: a rounding rule nobody checked, and a date that is really text.

Chopping the decimals off

FunctionDoesOn 7.8On -7.8
IntDown, always7-8
FixTowards zero7-7
RoundTo nearest8-8
Sub Chopping()
    Debug.Print Int(7.8), Fix(7.8), Round(7.8)
    Debug.Print Int(-7.8), Fix(-7.8), Round(-7.8)
    Debug.Print Abs(-42), Sgn(-42), Sqr(144)
End Sub

The rounding trap

VBA rounds an exact half to the nearest even number. This is deliberate - it is called banker’s rounding, and over thousands of rows it stops a persistent upward drift.

Sub RoundingTrap()
    Debug.Print "VBA Round"
    Debug.Print Round(0.5), Round(1.5), Round(2.5), Round(3.5)
    Debug.Print "Excel ROUND"
    Debug.Print WorksheetFunction.Round(0.5, 0), WorksheetFunction.Round(1.5, 0), _
                WorksheetFunction.Round(2.5, 0), WorksheetFunction.Round(3.5, 0)
End Sub
Read that output twice VBA gives 0, 2, 2, 4. Excel gives 1, 2, 3, 4. They disagree on every exact half. If your macro-produced total differs from the sheet total by a few rupees, this is very often the reason.
When you need the sheet’s behaviour, ask for it by name: WorksheetFunction.Round(x, 2).

Dates are numbers

Excel stores a date as a number of days counted from 30 December 1899. That is why you can subtract two dates and get days out.

Sub DateParts()
    Dim d As Date
    d = Cells(2, 2).Value

    Debug.Print d
    Debug.Print Year(d), Month(d), Day(d)
    Debug.Print MonthName(Month(d))
    Debug.Print Weekday(d)
End Sub

Date arithmetic

Sub DateMaths()
    Dim first As Date
    Dim last As Date

    first = Cells(2, 2).Value
    last = Cells(17, 2).Value

    Debug.Print "Days between:", DateDiff("d", first, last)
    Debug.Print "Months between:", DateDiff("m", first, last)
    Debug.Print "Thirty days on:", DateAdd("d", 30, first)
    Debug.Print "Same day next year:", DateAdd("yyyy", 1, first)
    Debug.Print "Built by hand:", DateSerial(2025, 12, 31)
End Sub
DateDiff, not subtraction last - first gives you days, which is often enough. DateDiff also does months, quarters and years, and it reads better: DateDiff("m", a, b) says what it means.

Format - turning values into text that looks right

Sub Formatting()
    Dim d As Date
    d = Cells(2, 2).Value

    Debug.Print Format(d, "yyyy-mm-dd")
    Debug.Print Format(d, "dd/mm/yyyy")
    Debug.Print Format(d, "mmm")
    Debug.Print Format(d, "mmmm")
    Debug.Print Format(d, "dddd")
    Debug.Print Format(0.256, "0.0%")
    Debug.Print Format(1234.5678, "0.00")
End Sub
Format gives you text, not a number Format(1234.5, "0.00") returns the string "1234.50". You cannot add it up any more. Use Format for labels and headings; to make a cell look right while staying a number, set .NumberFormat instead - that is tomorrow-but-one, on Day 11.
Number grouping follows your Windows region setting, so an India-English machine groups as 12,34,567 where a US one gives 1,234,567.

A monthly summary

Everything so far, doing a real job: group the orders by month.

Sub MonthlySummary()
    Dim i As Long
    Dim lastRow As Long
    Dim m As Long
    Dim janTotal As Double
    Dim febTotal As Double

    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    For i = 2 To lastRow
        m = Month(Cells(i, 2).Value)
        If m = 1 Then
            janTotal = janTotal + Cells(i, 6).Value * Cells(i, 7).Value
        ElseIf m = 2 Then
            febTotal = febTotal + Cells(i, 6).Value * Cells(i, 7).Value
        End If
        Cells(i, 9).Value = Format(Cells(i, 2).Value, "mmm")
    Next i

    Range("I1").Value = "Month"
    Debug.Print "January:", janTotal
    Debug.Print "February:", febTotal
End Sub

Try these yourself

  1. Print Int, Fix and Round of -3.5 and explain each answer.
  2. Show the difference between Round(4.5) and WorksheetFunction.Round(4.5, 0).
  3. Print how many days passed between the row 2 and row 10 order dates.
  4. Write the year of each order into column J using a loop.
  5. Explain why Format returns text, and when that would break a total.