Bridges to other tools (Power Query, Python via xlwings, etc.).
Disadvantages of VBA
Old language (from 1993); lacks modern features (e.g., no classes, limited error handling).
Not easy to debug or test.
Grammar is not the most friendly.
Macro security mindset
A Macro is the common name for some VBA code embedded in an Office document.
Macros can run code; treat files like executables.
Only enable content from trusted sources.
Use signed macros in corporate environments.
A signed macro is one that has been digitally signed with a certificate to verify its authenticity.
Windows (Trust Center): File → Options → Trust Center → Trust Center Settings → Macro Settings
Recommended for learning: “Disable all macros with notification” + add a Trusted Location for your course folder.
Consider enabling Protected View for files from the internet; unblock via file Properties → Unblock.
Mac (Trust Center): Excel → Preferences → Security & Privacy
Similar options: enable with notification; manage access to Visual Basic project if prompted.
Enable Developer tab (Windows)
File → Options → Customize Ribbon
Under Main Tabs, check Developer and click OK
Enable Developer tab (Mac)
Excel → Preferences → Ribbon & Toolbar
Select Main Tabs and check Developer
Click Save; the Developer tab appears
Excel UI tour (Win/Mac)
Windows screenshot: Excel workbook with the Ribbon showing the Developer tab
Mac screenshot: Excel for Mac with Developer tab visible
Callouts: Record Macro button, Visual Basic button, Macros list
Recording a macro (Win/Mac)
Windows
Developer → Record Macro
Name, choose storage (This Workbook/Personal)
Do actions → Stop → inspect in VBE
Use “Use Relative References” for relative actions
Naming: start with a letter; verbs like FormatHeader
Quick edit: Developer → Macros → Edit
Mac
Developer → Record Macro (similar flow)
Some shortcuts/dialogs differ slightly
Relative References also available
Prefer shape/button over keyboard shortcut (conflicts)
Storage mirrors Windows; Personal Macro Workbook exists
Relative References
Relative References toggle (Windows/Mac) controls whether recorded actions use absolute cell references (e.g., Range("A1")) or relative to the active cell (e.g., ActiveCell.Offset(0, 0)).
Use the Use Relative References button on the Developer tab before starting to record.
The Visual Basic Editor (VBE)
Open with Alt+F11 (Windows) or Option+F11 (Mac)
Project Explorer, Properties Window, Code Pane
Modules vs ThisWorkbook vs Sheet objects
Insert a Module: VBE → Insert → Module (stores your Sub procedures)
Run code: press F5 in VBE, or assign to a shape/button on the sheet
Opening the VBE (step‑by‑step)
Windows: Use Alt+F11, or Ribbon → Developer → Visual Basic
Mac: Use Option+F11, or Ribbon → Developer → Visual Basic
Verify the Project Explorer (left) and Properties (bottom‑left); if hidden: View → Project Explorer, View → Properties Window
Use View menu to show/hide panes if your layout differs.
Hello, world (VBA)
Macros start with a Sub procedure, and end with End Sub.
VBA has reserved words (e.g., Sub, Dim, If, Then, End); case-insensitive but prefer standard casing.
Sub HelloWorld() MsgBox "Hello from VBA!"End Sub
How to run it: place cursor inside HelloWorld and press F5 (or click Run ▶)
Assign to a button: Insert → Shapes → pick a shape → right‑click → Assign Macro → choose HelloWorld
Procedures, variables, and types
Sub procedures and variables
Sub MyTask()' your steps hereEnd SubSub Boxes()Dim total AsLong' variable declaration total = 42 MsgBox totalEnd Sub
Sub = a routine you can run; lives in a Module
Dim name As Type declares storage
Types and Option Explicit
Common types: Integer, Long, Double, String, Boolean, Date
Variant can hold anything (flexible but slower)
Prefer explicit types for clarity and speed
Not all types are available on Mac.
The Option Explicit statement forces variable declaration, reducing typos and bugs.
Worksheets("Sheet1").SelectRange("A1").SelectSelection.Value = "Indirect write"Range("B1").SelectActiveCell.Value = "Indirect with ActiveCell"
Conditionals
If…Then
If Range("A1").Value > 0 Then MsgBox "Positive"Else MsgBox "Non‑positive"End If
Great for simple conditions and ranges
Select Case
Select Case Range("B1").Value Case "A", "B": MsgBox "Group 1" Case "C": MsgBox "Group 2" Case Else: MsgBox "Other"End Select
Cleaner than nested Ifs for discrete categories
Loops: Do it repeatedly
You need to define the variable that controls the loop.
Dim i AsLongFor i = 1 To 10 Cells(i, 1).Value = iNext iDim c As RangeFor Each c In Range("A1:A10") c.Value = c.Value & "!"' The & concatenates stringsNext cDim k AsLongk = 1Do While k <= 10 Cells(k, 2).Value = k * 2 k = k + 1LoopDim tries AsLongtries = 0Do tries = tries + 1Loop Until tries >= 10
For ... Next: use a counter variable for numeric ranges
For Each ... Next: iterate items in a collection (Worksheets, Shapes, or cells in a Range)
Do While/Do Until: loop while/until a condition is satisfied (see next slide)
Debugging essentials
Breakpoints (click left margin), the code execution will pause there.
Step Into F8, Step Over Shift+F8, Step Out Ctrl+Shift+F8
Immediate window Ctrl+G: evaluate (? Range("A1").Value) or call procedures
Debug.Print for tracing; Stop statement to break programmatically
How to inspect variables live
Use the Locals window (View → Locals Window) to see all local variables and their current values when paused at a breakpoint.
Not all variables may have their values shown in the Locals window, especially if they are complex objects or if the code is not currently within the scope where the variable is defined.
Sub Trace()Dim c AsLongFor c = 1 To 10 c = c + 1Next cEnd Sub
Tip: Reproduce fast; isolate into small test Subs; comment out non-essential code while debugging
Do While / Do Until
Dim r AsLongr = 1Do While Cells(r, 1).Value <> "" Cells(r, 2).Value = Len(Cells(r, 1).Value) r = r + 1Loop
Do While condition ... Loop: runs while condition is True
Do Until condition ... Loop: runs until condition becomes True
Dim tries AsLongtries = 0Do tries = tries + 1If tries > 1000 Then Exit Do ' safety' ... work ...Loop Until Application.CountA(Range("A1:A10")) = 10
Tip: Choose For when you know counts, For Each for collections, Do While/Until for condition-driven loops
InputBox and MsgBox
Dim name AsStringname = InputBox("Your name?")MsgBox "Hi " & name
Simple UI for quick interactions
Advanced: prompt for a Range safely
Sub PickRange()Dim rng As RangeOnErrorResumeNextSet rng = Application.InputBox("Select a range", Type:=8)OnErrorGoTo 0If rng Is NothingThen MsgBox "No selection"Else MsgBox "You picked " & rng.AddressEnd IfEnd Sub
Arrays (static vs dynamic)
An array is a collection of values indexed by number.
Static arrays have fixed size; Dynamic arrays can be resized with ReDim.
' Static array (fixed size)Dim a(1 To 5) AsLonga(1) = 10' Dynamic array (resize later)Dim b() AsDoubleReDim b(1 To 3)b(3) = 1.23ReDim Preserve b(1 To 5) ' keep existing valuesReDim b(1 To 2) ' loses existing values
Static arrays: fastest, but fixed bounds
Dynamic arrays: ReDim to set size; ReDim Preserve to keep values.
Bounds defaults: if unspecified, VBA uses zero-based indexing; prefer explicit 1 To N for clarity
Many programming languages use zero-based indexing; VBA defaults to zero-based if no bounds are specified, but using 1 To N is clearer for Excel users.
Collections and Dictionary
Two main collection types: Collection (built-in) and Scripting.Dictionary (Windows).
Collections have no fixed size; Dictionaries map keys to values.
' Collection (built-in)Dim coll AsNew Collectioncoll.Add "Alice"coll.Add "Bob"Dim item As VariantFor Each item In coll Debug.Print itemNext' Scripting.Dictionary (Windows)Dim dict AsObjectSet dict = CreateObject("Scripting.Dictionary")dict("FR") = "France"dict("ES") = "Spain"If dict.Exists("FR") Then Debug.Print dict("FR")
Collection: ordered, allows duplicates, 1-based indexing via Item
Dictionary: key→value map, fast lookup; on Mac, available via AppleScript support but often easiest to simulate with Collection or use array lookups
Tip: For portability, prefer Collection or arrays unless you really need keyed lookup
Dim vs Set', Dim declares a variable;Set` assigns an object reference.
An object reference points to an instance of an object (like a Collection or Dictionary).
Object references
If you modify an object through one reference, the changes are reflected when accessing it through another reference.
Example
Dim coll1 AsNew CollectionDim coll2 As CollectionSet coll2 = coll1 ' coll2 now references the same Collection as coll1coll1.Add "Item1"Debug.Print coll2.Count ' Outputs 1, as coll2 references the same Collection
Subs vs Functions (User Defined Functions - UDFs)
' Sub performs actionsSub ClearData() Worksheets("Sheet1").Range("A2:D1000").ClearContentsEnd Sub' Function returns a value (UDF) name the variable that captures the return value as the function namePublicFunction AddTax(amount AsDouble, rate AsDouble) AsDouble AddTax = amount * (1 + rate)End Function
Sub: run from VBE, buttons, or macros dialog; can modify workbook state
Function: returns a value; can be used in worksheet cells as a UDF
UDF caveats: should be pure (function of inputs only); avoid side effects (changing sheets)
For security UDFs are not allowed to modify the Excel environment (e.g., changing cell values, formatting, or interacting with other applications). They should only compute and return values based on their input parameters.
The Workbook, Worksheet and WorksheetFunction objects
Each workbook and worksheet has its own code module (ThisWorkbook, Sheet1, etc.)
They allow access to events (open, close, change, etc.)
They also allow access to standard excel formulas.
Use ThisWorkbook to refer to the workbook containing the code.
Some common events:
Workbook_Open: runs when the workbook opens
Workbook_BeforeClose: runs before the workbook closes
Worksheet_Change: runs when a cell value changes in that sheet
This is the main reason why Office applications ask to enable macros when opening files with VBA code.
PrivateSub Workbook_Open() MsgBox "Welcome!"End Sub
Access to standard Excel formulas
Sub UseExcelFunction()Dim result AsDouble result = Application.WorksheetFunction.Sum(Range("A1:A10")) MsgBox "Sum is " & resultEnd Sub---## Win vs Mac differences (overview)- Shortcuts (Alt vs Option), some dialogs differ- File system paths differ- Many object model calls are the sameDetails that matter:- Paths: Windows uses `C:\Users\...\file.xlsx`; Mac uses `/Users/you/file.xlsx`; combine with `Application.PathSeparator`- File dialogs: `Application.FileDialog(msoFileDialogFilePicker)` works on both, but filters anddefault folders behave slightly differently- API calls: Windows allows `Declare PtrSafe Function` tocall Win32 APIs; Mac lacks Win32 — avoid OS API calls for portability- Add‑ins: `.xlam` works both; COM add‑ins are Windows‑only---## Error handling basics```vbSub DoWork()OnErrorGoTo CleanUp ' jump to CleanUp on error' ... risky code here ...Done:' What to do when doneExit SubCleanUp: MsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation, "DoWork"Resume DoneEnd Sub
Start simple; add structure as you grow
Variable Types
Integer: -32,768 to 32,767 (2 bytes)
Long: -2,147,483,648 to 2,147,483,647 (4 bytes)
Single: Single-precision floating point (4 bytes)
Double: Double-precision floating point (8 bytes)
String: Text (up to ~2 billion characters)
Boolean: True/False (2 bytes)
Date: Dates and times (8 bytes)
Variant: Can hold any type; default if no type specified (16 bytes + data)
Prefer explicit types for clarity and performance; Variant is flexible but slower and uses more memory
Not all types are available on Mac.
Your first serious program (exercise in class)
For your first exercise you are going to estimate the value of \(\pi\) using a Monte Carlo method.
Imagin e a square of side 2 (from -1 to 1 in both x and y) that contains a circle of radius 1.
The area of the square is 4, and the area of the circle is \(\pi\).
You are going to randomly generate points in the square, and count how many fall inside the circle as a fraction of the total points.
This fraction multiplied by 4 will give you an estimate of \(\pi\).
Your task - Create a UDF EstimatePi(n As Long) As Double that takes the number of random points to generate as input, and returns the estimate of \(\pi\). - Use x = Rnd to generate random numbers between 0 and 1; scale it to -1 to 1. - Return the estimate. - Your function should be available in the worksheet as e.g. =EstimatePi(10000).
Function EstimatePi(n AsLong) AsDoubleDim inside AsLongDim i AsLongDim x AsDouble, y AsDouble inside = 0'Randomize 'Optional Initialize random number generatorFor i = 1 To n x = Rnd * 2 - 1 ' Random x in [-1, 1] y = Rnd * 2 - 1 ' Random y in [-1, 1]If x * x + y * y <= 1 Then inside = inside + 1End IfNext i EstimatePi = (inside / n) * 4 ' Estimate of piEnd Function