StudyComputer ScienceVBA

Excel VBA for Traders - Automating Spreadsheets That Actually Work

2026-04-01 22 min read Computer Science
Excel VBA for Traders - Automating Spreadsheets That Actually Work

Excel VBA for Traders: Automating Spreadsheets That Actually Work

There is a joke on Wall Street that goes like this: “What technology powers the global financial system?” The intern says “Bloomberg Terminal.” The developer says “Python.” The quant says “C++.” And the person who actually keeps the lights on says “a 47-tab Excel spreadsheet that nobody understands and everyone is terrified to touch.”

That joke is barely a joke. Excel runs finance. It runs risk reports, P&L calculations, trade blotters, curve interpolation, position monitoring, and approximately 97% of all things that banks promise are “fully automated.” And the engine under the hood of these mission-critical spreadsheets? VBA. Visual Basic for Applications. The language that every developer loves to hate and every trader quietly depends on.

VBA is not glamorous. It will never trend on Hacker News. Nobody is writing Medium articles about “Why VBA is the Future.” But if you want to be useful in a finance environment, knowing how to write VBA that does not break at 6 AM when the London desk opens is worth its weight in gold.

Python may be the future, but VBA is the present. And the present pays the bills.


Why VBA Still Matters in Finance

Before we write a single line of code, let us address the elephant in the room. “Why not just use Python?”

Fair question. Here is why VBA still dominates:

  1. Excel is already everywhere. Every desk, every bank, every fund has Excel. No installation required. No IT approval process. No virtual environment headaches. It is just there.

  2. Traders live in Excel. They do not want a terminal. They do not want a web app. They want their spreadsheet. The one they have been using for 7 years. The one with the macros their predecessor wrote. Traders want their data where they can see it, touch it, and argue with it.

  3. Speed of deployment. You can write a VBA macro, test it, and hand it to a trader in 20 minutes. Try deploying a Python application to a locked-down bank desktop in 20 minutes. Good luck.

  4. Integration with everything. Bloomberg, Reuters, internal databases, emails, PowerPoint reports, you name it. VBA can talk to all of them through COM objects and add-ins.

Key Insight: VBA is not a good language for building scalable software systems. But it is an excellent language for solving “I need this specific thing automated in the tool I already use” problems. And finance is full of those problems.

The best code is the code that actually gets used. A perfect Python script sitting in a repo nobody looks at is worth less than a janky VBA macro that a trader runs 40 times a day.


VBA Fundamentals: The 20-Minute Crash Course

If you have never opened the VBA editor, here is the express version.

Opening the VBA Editor

Press Alt + F11 in Excel. That is it. You are now in the Visual Basic Editor (VBE). If that shortcut does not work, go to File > Options > Customize Ribbon and check “Developer” tab, then click “Visual Basic” from that tab.

Your First Macro

In the VBE, go to Insert > Module. Type the following:

Sub HelloTrader()
    MsgBox "Good morning. Your P&L is still loading."
End Sub

Press F5 to run it. Congratulations, you have written your first VBA macro.

Variables and Data Types

VBA is statically typed (if you want it to be). Always declare your variables with Dim, and always use Option Explicit at the top of every module to force declaration.

Option Explicit

Sub VariableDemo()
    Dim stockPrice As Double
    Dim ticker As String
    Dim quantity As Long
    Dim isActive As Boolean

    stockPrice = 142.57
    ticker = "AAPL"
    quantity = 1000
    isActive = True

    MsgBox ticker & " | Qty: " & quantity & " | Price: $" & stockPrice
End Sub

Not using Option Explicit is like driving without a seatbelt. You will feel fine until the day you misspell stockPirce and spend 3 hours wondering why your P&L is zero.

Key Data Types

TypeDescriptionExample
IntegerWhole numbers (-32,768 to 32,767)Dim count As Integer
LongLarger whole numbers (+/- 2 billion)Dim rowNum As Long
DoubleFloating-point numbers (15 digits)Dim price As Double
StringTextDim name As String
BooleanTrue/FalseDim isValid As Boolean
DateDate and timeDim tradeDate As Date
VariantCan hold any type (avoid when possible)Dim anything As Variant

Key Insight: Always use Long instead of Integer for row counters and loop variables. Excel has over 1 million rows, and Integer maxes out at 32,767. This is one of the most common VBA bugs in finance, and it will only show up when you process a large dataset, which is exactly when you cannot afford bugs.

Reading and Writing Cells

This is the bread and butter. Everything in VBA finance boils down to reading numbers from cells, doing something with them, and writing results back.

Sub CellBasics()
    ' Reading a cell value
    Dim price As Double
    price = Range("B2").Value

    ' Writing to a cell
    Range("C2").Value = price * 1.1  ' 10% markup

    ' Using Cells(row, column) notation
    Dim i As Long
    For i = 2 To 10
        Cells(i, 4).Value = Cells(i, 2).Value * Cells(i, 3).Value
    Next i

    ' Referencing a specific sheet
    Worksheets("Trades").Range("A1").Value = "Trade ID"
End Sub

Loops and Conditionals

Sub LoopExample()
    Dim i As Long
    Dim lastRow As Long

    ' Find the last row with data in column A
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row

    For i = 2 To lastRow
        If Cells(i, 3).Value > 100 Then
            Cells(i, 4).Value = "Large Trade"
        ElseIf Cells(i, 3).Value > 10 Then
            Cells(i, 4).Value = "Medium Trade"
        Else
            Cells(i, 4).Value = "Small Trade"
        End If
    Next i
End Sub

Finding the last row with Cells(Rows.Count, 1).End(xlUp).Row is the VBA equivalent of a secret handshake. If you know this line by heart, people will trust you with their spreadsheets.


Project 1: Bond Price Calculator

Let us build something real. A bond pricer that calculates the present value of a fixed-rate bond given its coupon rate, face value, yield to maturity, and number of periods.

The Math

The price of a bond is the sum of the present values of all future cash flows:

Bond Price = sum(C / (1 + y)^t, t=1..n) + F / (1 + y)^n

Where:
- C = coupon payment per period
- y = yield to maturity per period
- F = face value (par value)
- n = number of periods

The Spreadsheet Layout

RowAB
1ParameterValue
2Face Value1000
3Coupon Rate (annual)5.00%
4Yield to Maturity (annual)4.00%
5Years to Maturity10
6Payments per Year2
7Bond Price(calculated)
8Accrued Interest(calculated)

The VBA Code

Option Explicit

Sub CalculateBondPrice()
    Dim faceValue As Double
    Dim couponRate As Double
    Dim ytm As Double
    Dim years As Long
    Dim frequency As Long
    Dim couponPayment As Double
    Dim periodicYield As Double
    Dim nPeriods As Long
    Dim bondPrice As Double
    Dim pvCoupons As Double
    Dim pvFace As Double
    Dim t As Long

    ' Read inputs from the spreadsheet
    faceValue = Range("B2").Value
    couponRate = Range("B3").Value
    ytm = Range("B4").Value
    years = Range("B5").Value
    frequency = Range("B6").Value

    ' Calculate derived values
    couponPayment = (couponRate * faceValue) / frequency
    periodicYield = ytm / frequency
    nPeriods = years * frequency

    ' Calculate present value of coupon payments
    pvCoupons = 0
    For t = 1 To nPeriods
        pvCoupons = pvCoupons + couponPayment / (1 + periodicYield) ^ t
    Next t

    ' Calculate present value of face value
    pvFace = faceValue / (1 + periodicYield) ^ nPeriods

    ' Total bond price
    bondPrice = pvCoupons + pvFace

    ' Write result
    Range("B7").Value = bondPrice
    Range("B7").NumberFormat = "$#,##0.00"

    ' Display summary
    MsgBox "Bond Price: $" & Format(bondPrice, "#,##0.00") & vbCrLf & _
           "Coupon per period: $" & Format(couponPayment, "#,##0.00") & vbCrLf & _
           "Number of periods: " & nPeriods & vbCrLf & _
           "Premium/Discount: $" & Format(bondPrice - faceValue, "#,##0.00")
End Sub

Running the Example

With the inputs above (5% coupon, 4% yield, 10 years, semi-annual):
- Coupon payment per period: $25.00
- Number of periods: 20
- PV of coupons: $410.24
- PV of face value: $672.97
- Bond price: $1,082.21

The bond trades at a premium ($1,082.21 > $1,000) because the coupon rate (5%) exceeds the yield (4%). Investors are willing to pay more for higher-than-market coupons.

YieldBond PricePremium/Discount
3.00%$1,170.30+$170.30 (Premium)
4.00%$1,082.21+$82.21 (Premium)
5.00%$1,000.00$0.00 (Par)
6.00%$925.61-$74.39 (Discount)
7.00%$858.10-$141.90 (Discount)

Key Insight: When the coupon rate equals the yield to maturity, the bond trades at exactly par ($1,000). This is not a coincidence, it is a mathematical identity. The bond is paying exactly what the market demands, so nobody needs to pay a premium or accept a discount.

If your bond pricer returns $1,000 when the coupon equals the yield, your code is correct. If it does not, go back and check your loop bounds.


Project 2: Automated P&L Report

Every morning, traders want to know one thing: “How much did I make or lose?” Let us automate that.

The Setup

Assume you have a “Trades” sheet with this structure:

ABCDE
Trade IDTickerQuantityEntry PriceCurrent Price
T001AAPL500142.50148.20
T002MSFT-200380.00375.50
T003GOOGL100140.25152.80
T004TSLA-150245.00258.30

Negative quantity means a short position.

The VBA Code

Option Explicit

Sub GeneratePnLReport()
    Dim wsTrades As Worksheet
    Dim wsReport As Worksheet
    Dim lastRow As Long
    Dim i As Long
    Dim reportRow As Long
    Dim quantity As Long
    Dim entryPrice As Double
    Dim currentPrice As Double
    Dim pnl As Double
    Dim totalPnL As Double
    Dim totalLongs As Double
    Dim totalShorts As Double

    Set wsTrades = Worksheets("Trades")

    ' Create or clear the Report sheet
    On Error Resume Next
    Set wsReport = Worksheets("P&L Report")
    On Error GoTo 0

    If wsReport Is Nothing Then
        Set wsReport = Worksheets.Add(After:=Worksheets(Worksheets.Count))
        wsReport.Name = "P&L Report"
    Else
        wsReport.Cells.Clear
    End If

    ' Write headers
    With wsReport
        .Range("A1").Value = "P&L Report - " & Format(Now, "dd-mmm-yyyy hh:mm")
        .Range("A1").Font.Bold = True
        .Range("A1").Font.Size = 14

        .Range("A3").Value = "Trade ID"
        .Range("B3").Value = "Ticker"
        .Range("C3").Value = "Position"
        .Range("D3").Value = "Quantity"
        .Range("E3").Value = "Entry Price"
        .Range("F3").Value = "Current Price"
        .Range("G3").Value = "P&L ($)"
        .Range("H3").Value = "P&L (%)"
        .Range("A3:H3").Font.Bold = True
        .Range("A3:H3").Interior.Color = RGB(51, 51, 51)
        .Range("A3:H3").Font.Color = RGB(255, 255, 255)
    End With

    lastRow = wsTrades.Cells(wsTrades.Rows.Count, 1).End(xlUp).Row
    reportRow = 4
    totalPnL = 0
    totalLongs = 0
    totalShorts = 0

    For i = 2 To lastRow
        quantity = wsTrades.Cells(i, 3).Value
        entryPrice = wsTrades.Cells(i, 4).Value
        currentPrice = wsTrades.Cells(i, 5).Value

        ' P&L calculation (works for both long and short positions)
        pnl = quantity * (currentPrice - entryPrice)
        totalPnL = totalPnL + pnl

        ' Track long/short exposure
        If quantity > 0 Then
            totalLongs = totalLongs + quantity * currentPrice
        Else
            totalShorts = totalShorts + Abs(quantity) * currentPrice
        End If

        ' Write to report
        With wsReport
            .Cells(reportRow, 1).Value = wsTrades.Cells(i, 1).Value
            .Cells(reportRow, 2).Value = wsTrades.Cells(i, 2).Value
            .Cells(reportRow, 3).Value = IIf(quantity > 0, "LONG", "SHORT")
            .Cells(reportRow, 4).Value = Abs(quantity)
            .Cells(reportRow, 5).Value = entryPrice
            .Cells(reportRow, 6).Value = currentPrice
            .Cells(reportRow, 7).Value = pnl
            .Cells(reportRow, 8).Value = pnl / (Abs(quantity) * entryPrice)

            ' Color P&L cells
            If pnl > 0 Then
                .Cells(reportRow, 7).Font.Color = RGB(0, 128, 0)
            ElseIf pnl < 0 Then
                .Cells(reportRow, 7).Font.Color = RGB(200, 0, 0)
            End If
        End With

        reportRow = reportRow + 1
    Next i

    ' Format number columns
    With wsReport
        .Range("E4:F" & reportRow - 1).NumberFormat = "$#,##0.00"
        .Range("G4:G" & reportRow - 1).NumberFormat = "$#,##0.00"
        .Range("H4:H" & reportRow - 1).NumberFormat = "0.00%"

        ' Summary section
        .Cells(reportRow + 1, 1).Value = "TOTAL P&L:"
        .Cells(reportRow + 1, 1).Font.Bold = True
        .Cells(reportRow + 1, 7).Value = totalPnL
        .Cells(reportRow + 1, 7).Font.Bold = True
        .Cells(reportRow + 1, 7).NumberFormat = "$#,##0.00"

        .Cells(reportRow + 2, 1).Value = "Long Exposure:"
        .Cells(reportRow + 2, 7).Value = totalLongs
        .Cells(reportRow + 2, 7).NumberFormat = "$#,##0.00"

        .Cells(reportRow + 3, 1).Value = "Short Exposure:"
        .Cells(reportRow + 3, 7).Value = totalShorts
        .Cells(reportRow + 3, 7).NumberFormat = "$#,##0.00"

        .Cells(reportRow + 4, 1).Value = "Net Exposure:"
        .Cells(reportRow + 4, 7).Value = totalLongs - totalShorts
        .Cells(reportRow + 4, 7).NumberFormat = "$#,##0.00"

        ' Auto-fit columns
        .Columns("A:H").AutoFit
    End With

    MsgBox "P&L Report generated!" & vbCrLf & _
           "Total P&L: " & Format(totalPnL, "$#,##0.00"), _
           vbInformation, "Report Complete"
End Sub

Output for Our Example

Trade IDTickerPositionQtyEntryCurrentP&L ($)P&L (%)
T001AAPLLONG500$142.50$148.20$2,850.004.00%
T002MSFTSHORT200$380.00$375.50$900.001.18%
T003GOOGLLONG100$140.25$152.80$1,255.008.95%
T004TSLASHORT150$245.00$258.30-$1,995.00-5.43%

Total P&L: $3,010.00

The AAPL and GOOGL longs are making money. The MSFT short is winning too (price went down, which is what you want when you are short). But that TSLA short is hurting. Elon probably tweeted something.


Project 3: Yield Curve Interpolation

You have a handful of benchmark yields (1Y, 2Y, 5Y, 10Y, 30Y) and you need to estimate the yield for maturities in between. This is linear interpolation on the yield curve, something every fixed income desk does daily.

The VBA Code

Option Explicit

Function InterpolateYield(targetMaturity As Double, _
                          maturities As Range, _
                          yields As Range) As Double
    '
    ' Linearly interpolates a yield for a given maturity
    ' from a set of benchmark maturities and yields.
    '
    Dim n As Long
    Dim i As Long
    Dim x1 As Double, x2 As Double
    Dim y1 As Double, y2 As Double

    n = maturities.Cells.Count

    ' Handle edge cases: target outside the curve
    If targetMaturity <= maturities.Cells(1).Value Then
        InterpolateYield = yields.Cells(1).Value
        Exit Function
    End If

    If targetMaturity >= maturities.Cells(n).Value Then
        InterpolateYield = yields.Cells(n).Value
        Exit Function
    End If

    ' Find the two surrounding points
    For i = 1 To n - 1
        If maturities.Cells(i).Value <= targetMaturity And _
           targetMaturity <= maturities.Cells(i + 1).Value Then

            x1 = maturities.Cells(i).Value
            x2 = maturities.Cells(i + 1).Value
            y1 = yields.Cells(i).Value
            y2 = yields.Cells(i + 1).Value

            ' Linear interpolation formula
            InterpolateYield = y1 + (y2 - y1) * _
                              (targetMaturity - x1) / (x2 - x1)
            Exit Function
        End If
    Next i
End Function

Usage in a Spreadsheet

Set up your benchmark data:

AB
Maturity (Years)Yield (%)
0.254.85
0.54.78
14.55
24.30
54.10
104.25
304.50

Then in any cell, type:

=InterpolateYield(3, A2:A8, B2:B8)

This returns 4.1667%, the linearly interpolated yield for a 3-year maturity between the 2Y (4.30%) and 5Y (4.10%) benchmarks.

Target MaturityInterpolated Yield
0.75 years4.665%
3 years4.167%
7 years4.160%
15 years4.313%
20 years4.375%

Key Insight: Linear interpolation on yields is the simplest approach. Production systems typically use cubic spline interpolation or Nelson-Siegel models, which produce smoother curves. But linear interpolation is perfectly adequate for quick estimates and sanity checks.

If a trader asks “what’s the 7-year yield?” and you say “let me fit a Nelson-Siegel-Svensson model,” they will throw something at you. Just interpolate linearly and give them the number. You can be precise after market close.


Project 4: Automated Email Report

At the end of each day, you want to email a summary of the P&L report to the team. VBA can automate this using Outlook.

Option Explicit

Sub EmailPnLReport()
    Dim olApp As Object
    Dim olMail As Object
    Dim totalPnL As Double
    Dim reportDate As String

    ' Get P&L from the report sheet
    totalPnL = Worksheets("P&L Report").Cells( _
        Worksheets("P&L Report").Cells(Rows.Count, 1).End(xlUp).Row - 3, _
        7).Value
    reportDate = Format(Date, "dd-mmm-yyyy")

    ' Create Outlook email
    Set olApp = CreateObject("Outlook.Application")
    Set olMail = olApp.CreateItem(0)

    With olMail
        .To = "trading-desk@example.com"
        .CC = "risk-team@example.com"
        .Subject = "Daily P&L Report - " & reportDate
        .HTMLBody = "<h2>Daily P&L Summary</h2>" & _
                    "<p>Date: " & reportDate & "</p>" & _
                    "<p><b>Total P&L: " & Format(totalPnL, "$#,##0.00") & _
                    "</b></p>" & _
                    "<p>Full report attached.</p>" & _
                    "<p>This is an automated message.</p>"

        ' Attach the workbook
        .Attachments.Add ThisWorkbook.FullName

        ' Display for review (use .Send to send automatically)
        .Display
    End With

    Set olMail = Nothing
    Set olApp = Nothing

    MsgBox "Email prepared!", vbInformation
End Sub

Never use .Send on the first attempt. Always use .Display so you can review the email before it goes out. One rogue VBA macro sending 400 emails to the CFO is a career-defining moment, and not in a good way.


Performance Tips: Making VBA Not Terrible

VBA’s default behavior is to update the screen and recalculate formulas after every single cell change. This makes loops painfully slow. Here is how to fix that.

The Speed Trifecta

Sub FastMacro()
    ' Turn off screen updating, calculations, and events
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False

    ' === Your actual code goes here ===
    Dim i As Long
    For i = 1 To 100000
        Cells(i, 1).Value = i * 2
    Next i
    ' === End of actual code ===

    ' ALWAYS turn them back on (use error handling in production)
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
End Sub

Performance Comparison

Operation (100,000 rows)Without OptimizationWith Optimization
Write values to cells45 seconds2 seconds
Read and process cells30 seconds1.5 seconds
Format cells60 seconds3 seconds

That is a 20x to 30x improvement. Not bad for three lines of code.

Use Arrays for Bulk Operations

Instead of reading cells one by one, load the entire range into an array, process it, and write it back.

Sub ArrayProcessing()
    Dim data As Variant
    Dim results() As Variant
    Dim i As Long
    Dim lastRow As Long

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

    ' Read entire range into array (instant)
    data = Range("A1:D" & lastRow).Value

    ' Process in memory (fast)
    ReDim results(1 To UBound(data, 1), 1 To 1)
    For i = 1 To UBound(data, 1)
        results(i, 1) = data(i, 3) * data(i, 4)  ' Qty * Price
    Next i

    ' Write results back in one operation (fast)
    Range("E1:E" & lastRow).Value = results
End Sub

Key Insight: Reading and writing cells individually is the number one performance killer in VBA. A single Range.Value = array call writing 100,000 values is 50 to 100 times faster than 100,000 individual Cells(i, j).Value = x calls. Always work with arrays for large datasets.

Think of it this way. You would not carry groceries from the car one item at a time. You would grab as many bags as possible. VBA arrays are the grocery bags of data processing.


Error Handling: Because Things Will Break

VBA without error handling is a ticking time bomb. Here is the standard pattern:

Sub RobustMacro()
    On Error GoTo ErrorHandler

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    ' === Your code here ===
    Dim price As Double
    price = Range("B2").Value

    If price <= 0 Then
        Err.Raise vbObjectError + 1, , "Invalid price: " & price
    End If

    ' ... more processing ...

CleanExit:
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Exit Sub

ErrorHandler:
    MsgBox "Error " & Err.Number & ": " & Err.Description, _
           vbCritical, "Macro Error"
    Resume CleanExit
End Sub

The CleanExit label ensures that screen updating and calculation are always restored, even if an error occurs. Without this pattern, a crash can leave your Excel session frozen with calculations turned off. And you will spend 30 minutes wondering why your formulas are not updating before realizing the macro crashed mid-execution.

“Why is nothing calculating?” is the VBA developer’s equivalent of “is it plugged in?” The answer is almost always that a crashed macro left Application.Calculation = xlCalculationManual.


Common Pitfalls

  1. Not using Option Explicit. Undeclared variables default to Variant type. A typo in a variable name silently creates a new variable initialized to Empty. Your code runs without errors and produces wrong results. This is the worst kind of bug.

  2. Using Integer instead of Long for row numbers. Integer overflows at 32,767. Excel has 1,048,576 rows. Use Long for anything that could be a row number.

  3. Hardcoding row numbers. Never write Range("A2:A150") when the data might grow. Always find the last row dynamically.

  4. Forgetting to restore Application settings. If your macro crashes between ScreenUpdating = False and ScreenUpdating = True, Excel appears frozen. Always use error handlers.

  5. Selecting and activating everything. Range("A1").Select followed by Selection.Value = 5 is the macro recorder’s favorite pattern. Never do this. Just write Range("A1").Value = 5. It is faster and cleaner.

  6. Not handling empty cells. An empty cell returns Empty (a Variant). Doing math on Empty gives zero, which might silently corrupt your calculations. Always validate inputs.


Wrapping Up

VBA is not winning any beauty contests. It has no package manager, no type inference, no lambda functions (well, it got them in 2021 but nobody noticed), and its debugging experience is from the 1990s. But it runs on every Windows desktop in every bank, fund, and trading firm on the planet. It integrates natively with the tool that finance professionals spend their entire day in. And it turns repetitive, error-prone manual tasks into one-click automations.

The bond pricer, the P&L report, the yield curve interpolator, and the email automation we built today are not toy examples. They are the kinds of tools that actually get used on trading desks. The key is writing them properly: with Option Explicit, error handling, performance optimization, and clear structure.

Learn VBA. Not because it is the best language, but because it is the most useful one in the room where the money is.


Cheat Sheet

Key Questions & Answers

Why VBA instead of Python for finance tasks?

VBA runs inside Excel, which is already on every desk. No installation, no IT approval, no deployment pipeline. Traders live in Excel and want their tools there. VBA is not better than Python for computation, but it is better for “I need this automated in the spreadsheet I already use.”

How do I make VBA macros run faster?

Three things: set Application.ScreenUpdating = False, set Application.Calculation = xlCalculationManual, and use arrays instead of cell-by-cell operations. These alone can give you 20x to 100x speedups. Always restore these settings when done, using error handlers to guarantee cleanup.

What is Option Explicit and why should I always use it?

Option Explicit forces you to declare all variables with Dim. Without it, a typo like stockPirce silently creates a new empty variable instead of throwing an error. This leads to bugs that are nearly impossible to find. Put Option Explicit at the top of every module. No exceptions.

How do I handle errors properly in VBA?

Use On Error GoTo ErrorHandler at the start, a CleanExit label for cleanup code, and an ErrorHandler label that displays the error and resumes to CleanExit. This pattern ensures Application settings (ScreenUpdating, Calculation) are always restored, even when a macro crashes.

Key Concepts at a Glance

ConceptSummary
VBA Editor accessAlt + F11 to open the Visual Basic Editor
Option ExplicitForces variable declaration, prevents typo bugs
Long vs IntegerAlways use Long for row numbers (Integer overflows at 32,767)
Find last rowCells(Rows.Count, 1).End(xlUp).Row
Speed optimizationDisable ScreenUpdating + Manual Calculation + Arrays
Array bulk readdata = Range("A1:D100").Value loads entire range at once
Array bulk writeRange("E1:E100").Value = results writes entire array at once
Error handlingOn Error GoTo, CleanExit, ErrorHandler pattern
Cell referenceRange("B2").Value or Cells(row, col).Value
Custom functionsFunction keyword creates UDFs usable in worksheet formulas
COM automationCreateObject("Outlook.Application") to control other Office apps
Bond pricingPV of coupons + PV of face value, discounted at YTM
InterpolationFind two surrounding points, apply linear formula
Variant typeAvoid when possible, use specific types for safety and speed

Sources & Further Reading

PreviousMonte Carlo Simulation - Pricing Options the Hacker Way