Calculations and Dates
Module 5 of 9
REMINDER: To fully understand Calculations and Dates, you should have already watched the Calculations and Dates Video in Canvas and followed along with the Macro Demo file. This practice will build upon that foundation.
Calculations and Dates in VBA
VBA can perform calculations three ways: store the result in a variable, place a formula in a cell so Excel calculates it, or place the result of the calculation directly in a cell. Each approach has its place. Variables are used when you need the value mid-macro. Formulas in cells let Excel recalculate automatically. Results in cells are faster and don't depend on Excel's calculation engine.
For this course, the most common pattern is calculating into a variable and then displaying or storing the result. Functions like Count, Sum, and Average are available through Application.WorksheetFunction and work exactly like their Excel equivalents.
If a function works in Excel, it almost certainly works in VBA through Application.WorksheetFunction. When in doubt, try it — if it doesn't work without the prefix, add it.
Basic Math and WorksheetFunction
Basic arithmetic in VBA uses the same operators as Excel: +, -, *, /. You can calculate directly into a variable or into a cell. To use Excel functions like Count, Sum, or Average in VBA, prefix them with Application.WorksheetFunction. Some functions work without the prefix — but when in doubt, include it.
Syntax
' Basic math into a variable
AverageGPR = TotalGPR / StudentCount
' WorksheetFunction into a variable
NoRecords = Application.WorksheetFunction.Count(Range("A:A"))
TotalSales = Application.WorksheetFunction.Sum(Range("H:H"))
' Place formula in a cell (Excel calculates)
Range("K2") = "=Count(A:A)"
' Place result in a cell (VBA calculates)
Range("K3") = Application.WorksheetFunction.Count(Range("A:A"))
This example from the Macro Handout shows all three approaches for Count:
Dim NoRecords As Integer
' Places the actual count formula in the cell
Range("K2") = "=Count(A:A)"
' Places the result into a cell
Range("K3") = Application.WorksheetFunction.Count(Range("A:A"))
' Places the result into a variable
NoRecords = Application.WorksheetFunction.Count(Range("A:A"))
Accumulating a Total in a Loop
When you need a running total across multiple records, you accumulate it inside a loop using a variable. Start the variable at 0 before the loop, add to it on each pass, then use or display it after the loop ends. This is the same pattern whether you're summing sales, counting records, or calculating an average.
Syntax
Dim CumulativeTotal As Double
CumulativeTotal = 0 ' reset before loop
Do Until ActiveCell = ""
CumulativeTotal = CumulativeTotal + ActiveCell.Offset(0, 5)
ActiveCell.Offset(1, 0).Select
Loop
MsgBox "Total: " & CumulativeTotal
This is the CumulativeTotal example from the Macro Handout:
Dim CumulativeTotal As Double
Range("A2").Select
CumulativeTotal = 0
Do Until ActiveCell = ""
CumulativeTotal = CumulativeTotal + ActiveCell.Offset(0, 5)
ActiveCell.Offset(1, 0).Select
Loop
MsgBox "The cumulative total is " & _
Application.WorksheetFunction.Dollar(CumulativeTotal, 0)
Formatting Numbers and Dates
Formatting affects what is displayed in a cell — it does not change what is stored in a variable. A Double variable holding 3.756 stays 3.756 regardless of how the cell displays it. The Dollar function formats a number as currency for display in a MsgBox. For worksheet cells, use the NumberFormat property.
Syntax
' Format a cell as currency
Range("H2").NumberFormat = "$#,##0.00"
' Format a cell as percentage with 2 decimal places
Range("B2").NumberFormat = "0.00%"
' Dollar function for MsgBox display only
MsgBox Application.WorksheetFunction.Dollar(AverageVariable, 2)
Date Functions
VBA has built-in date functions for adding time intervals and finding end-of-month dates. DateAdd takes an interval code, a number, and a starting date and returns a new date. EoMonth returns the last day of a month and requires Application.WorksheetFunction. Year, Month, and Day extract parts of a date and work directly without any prefix.
Syntax
' Add 1 month to a date
DateAdd("m", 1, StartDate)
' Add 1 day
DateAdd("d", 1, StartDate)
' Add 1 year
DateAdd("yyyy", 1, StartDate)
' Last day of the month
Application.WorksheetFunction.EoMonth(StartDate, 0)
' Extract year, month, day
Year(StartDate)
Month(StartDate)
Day(StartDate)
These are the date examples from the Macro Handout:
Dim StartDate As Date
StartDate = Range("B2")
' Add 1 month
Range("B4") = DateAdd("m", 1, StartDate)
' End of month
Range("B7") = Application.WorksheetFunction.EoMonth(StartDate, 0)
' Compare year to current year
If Year(Range("B7")) = Year(Now()) Then
MsgBox "You are in the current year"
End If
Quick Check
1. You want to count the number of records in column A using VBA and store the result in a variable. Which line is correct?
WorksheetFunction functions that store into a variable require the Application.WorksheetFunction prefix. Option D places a formula string in a variable, not the result. Option B counts all cells including empty ones — not what you want.
2. You format a cell as currency using NumberFormat. Your variable GPR still holds 3.756. What does the variable contain after the formatting?
Formatting affects display only — it never changes what is stored in a variable. GPR remains 3.756 as a Double regardless of how the cell is formatted.
3. What does DateAdd("m", 3, StartDate) return?
"m" is the interval code for months. "d" is days, "yyyy" is years.
4. You need to accumulate a total inside a loop. Before the loop starts, you should:
While VBA does initialize numeric variables to 0, explicitly setting it to 0 before the loop is best practice — it makes your intent clear and prevents bugs if the macro runs more than once in the same session.
5. Which function requires Application.WorksheetFunction in VBA?
DateAdd, Year, Month, and Day are native VBA functions and work without any prefix. EoMonth is an Excel worksheet function and requires Application.WorksheetFunction.
Question 5 comes up on the exam in the form of code that doesn't work — you'll be asked to fix it. EoMonth without the prefix is a classic error.
Easy Wins
Write a macro that counts the records in a column and calculates the sum of a numeric column, then displays both in a MsgBox.
Open the VBA Editor (Alt+F11). Insert a module (Insert → Module). Type this shell to start — Steps 2 and 3 will fill in the lines between the Dim statements and End Sub:
Option Explicit
Sub CalculateTotals()
Dim RecordCount As Integer
Dim TotalGPR As Double
End Sub
Add these lines inside your Sub, after the Dim statements. WorksheetFunction calculates both values directly — no loop needed:
Sheets("Sheet1").Select
Range("A1").Select
RecordCount = Application.WorksheetFunction.Count(Range("A:A"))
TotalGPR = Application.WorksheetFunction.Sum(Range("D:D"))
Count(Range("A:A")) counts non-empty cells in column A.
Sum(Range("D:D")) adds all values in column D.
Add the MsgBox line after your calculations, before End Sub. The Dollar function formats the total as currency with 3 decimal places:
MsgBox "Records: " & RecordCount & " | Total GPR: " & _
Application.WorksheetFunction.Dollar(TotalGPR, 3)
Press F5 to run. With the 30-record Aggie Advisors dataset in column A and GPR values in column D, you should see both totals in the MsgBox.
Option Explicit
Sub CalculateTotals()
Dim RecordCount As Integer
Dim TotalGPR As Double
Sheets("Sheet1").Select
RecordCount = Application.WorksheetFunction.Count(Range("A:A"))
TotalGPR = Application.WorksheetFunction.Sum(Range("D:D"))
MsgBox "Records: " & RecordCount & " | Total GPR: " & _
Application.WorksheetFunction.Dollar(TotalGPR, 3)
End Sub
Expected result: Records: 30 | Total GPR: $111.435
Type any date into cell B2 of a worksheet. Then run this macro and observe what each line puts into the cells:
Option Explicit
Sub DateDemo()
Dim StartDate As Date
StartDate = Range("B2")
Range("C2") = DateAdd("m", 1, StartDate)
Range("C3") = DateAdd("d", 1, StartDate)
Range("C4") = DateAdd("yyyy", 1, StartDate)
Range("C5") = Application.WorksheetFunction.EoMonth(StartDate, 0)
Range("C6") = Year(StartDate)
End Sub
C5 may display as a number instead of a date. Why?
EoMonth returns a date serial number. The cell needs to be formatted as a
date to display correctly. This is the difference between what VBA stores
(a number) and what Excel displays (a date).
Fix: Range("C5").NumberFormat = "mm/dd/yyyy"
Practice Problem
Copy this data and paste it into cell A1 of a new Excel worksheet. Press Ctrl+V — Excel will split the columns automatically.
| StudentID | LastName | FirstName | TAMU_GPR | Grade229 | Grade230 | Grade327 | FinalDecision |
|---|---|---|---|---|---|---|---|
| 724816395 | Anderson | Emma | 3.842 | A | B+ | A- | Accept |
| 831924750 | Martinez | Carlos | 3.156 | B | B | B- | Deny |
| 619283740 | Thompson | Sarah | 3.971 | A | A- | A | Accept |
| 748291036 | Nguyen | Michael | 3.624 | B+ | A- | B+ | Accept |
| 825163947 | Williams | Ashley | 2.987 | C+ | B | C | Deny |
| 736481920 | Brown | James | 3.745 | A- | B+ | A- | Accept |
| 814729360 | Davis | Lauren | 3.512 | B+ | B+ | B | Accept |
| 729183640 | Wilson | Tyler | 2.843 | C | C+ | B- | Deny |
| 836492710 | Johnson | Megan | 3.889 | A | A | A- | Accept |
| 715824930 | Garcia | Daniel | 3.234 | B | B- | B | Deny |
| 842163950 | Miller | Rachel | 3.763 | A- | A- | B+ | Accept |
| 726849130 | Moore | Kevin | 3.091 | B- | C+ | B | Deny |
| 819374620 | Taylor | Jessica | 3.956 | A | A- | A | Accept |
| 734826190 | Jackson | Ryan | 3.478 | B+ | B | B+ | Accept |
| 821649370 | White | Brittany | 2.765 | C | B- | C+ | Deny |
| 716293840 | Harris | Brandon | 3.834 | A- | A- | A- | Accept |
| 843716290 | Martin | Stephanie | 3.612 | B+ | B+ | A- | Accept |
| 728493610 | Thompson | Nathan | 3.147 | B | B- | B | Deny |
| 815264930 | Lewis | Amanda | 3.891 | A | A | A | Accept |
| 731846920 | Robinson | Justin | 3.423 | B+ | B | B | Accept |
| 824619730 | Clark | Samantha | 2.914 | C+ | B- | C | Deny |
| 719283460 | Rodriguez | Matthew | 3.756 | A- | B+ | A- | Accept |
| 836142790 | Lee | Kayla | 3.534 | B+ | A- | B+ | Accept |
| 724891360 | Walker | Andrew | 3.068 | B- | C+ | B- | Deny |
| 811364920 | Hall | Courtney | 3.847 | A | A- | A | Accept |
| 738261490 | Allen | Christopher | 3.389 | B | B+ | B | Accept |
| 826419730 | Young | Melissa | 2.831 | C | C+ | B- | Deny |
| 713849260 | Hernandez | Joshua | 3.912 | A | A | A- | Accept |
| 841263970 | King | Tiffany | 3.645 | B+ | A- | B+ | Accept |
| 727491360 | Wright | Patrick | 3.178 | B | B- | B | Deny |
Calculate Average GPR of Accepted Students
Using the Aggie Advisors data, write a macro that loops through all 30 records, accumulates the total GPR of accepted students, counts them, calculates the average, and displays it formatted to 3 decimal places.
What your macro needs to do:
- Declare variables: AcceptCount (Integer), TotalGPR (Double), AverageGPR (Double)
- Loop through all records using Do Until blank cell
- Check if FinalDecision = "Accept" (column H,
Offset(0, 7)) - If Accept: add GPR (column D,
Offset(0, 3)) to TotalGPR and add 1 to AcceptCount - After loop: calculate AverageGPR = TotalGPR / AcceptCount
- Display: "Accepted: [X] | Avg GPR: [X.XXX]"
Expected result: Accepted: 20 | Avg GPR: 3.718
Hint: Calculate the average AFTER the loop ends, not inside it.
Use Format(AverageGPR, "0.000") to display exactly 3 decimal places.
Challenge
These exercises are perfect preparation for the Sample Exam, which prepares you for the Macro Project Exam itself. Exam format may vary by semester.
Calculations and Dates Summary
No hints. No steps. This is exam level.
Using the Aggie Advisors dataset, write a macro that produces a complete summary in a MsgBox showing:
- Total applicants (all 30)
- Number accepted and their average GPR
- Number denied and their average GPR
- The month and year of today's date formatted as "Month: [X] Year: [X]"
All values must come from variables — no hardcoded numbers.
Use Format(value, "0.000") for GPR averages.
Month and year from Month(Now()) and Year(Now()).
Expected output format:
"Total: 30 | Accepted: 20 (Avg GPR: 3.718) | Denied: 10 (Avg GPR: 3.001) | Month: [current month] Year: [current year]"
The month and year values will match the date when you run the macro —
use Month(Now()) and Year(Now()) in your code, not hardcoded numbers.