
π This article includes 1 downloadable practice file β
Sending the same report to twenty people with slightly different numbers is exactly the kind of job VBA was made for. This macro reads a list in Excel and creates one Outlook email per row. It has a preview mode so you can check everything before anything is sent.
In this article
Set up the sheet
| A: Name | B: Email | C: CC | D: Amount | E: Attachment path | F: Status |
|---|---|---|---|---|---|
| Asha | [email protected] | 12500 | C:\Reports\North.pdf |
The macro
Option Explicit
Sub SendMailMerge()
Const PREVIEW_ONLY As Boolean = True ' change to False to send
Dim ol As Object, mail As Object
Dim ws As Worksheet, r As Long, lastRow As Long
Set ws = ThisWorkbook.Sheets("Mail")
Set ol = CreateObject("Outlook.Application")
lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
For r = 2 To lastRow
If ws.Cells(r, "F").Value <> "Sent" Then
Set mail = ol.CreateItem(0) ' 0 = olMailItem
With mail
.To = ws.Cells(r, "B").Value
.CC = ws.Cells(r, "C").Value
.Subject = "Your monthly statement"
.HTMLBody = "<p>Hi " & ws.Cells(r, "A").Value & ",</p>" & _
"<p>Your balance this month is <b>₹" & _
Format(ws.Cells(r, "D").Value, "#,##0") & "</b>.</p>" & _
"<p>Regards,<br>Atul</p>"
If Len(ws.Cells(r, "E").Value) > 0 Then
If Dir(ws.Cells(r, "E").Value) <> "" Then
.Attachments.Add ws.Cells(r, "E").Value
Else
ws.Cells(r, "F").Value = "Missing attachment"
GoTo NextRow
End If
End If
If PREVIEW_ONLY Then .Display Else .Send
End With
ws.Cells(r, "F").Value = IIf(PREVIEW_ONLY, "Previewed", "Sent")
End If
NextRow:
Next r
End Sub
Why it is written this way
- Late binding (
CreateObject) means you do not need to tick the Outlook reference, and the file works on PCs with different Office versions. - PREVIEW_ONLY opens each email instead of sending it. I never run a mail macro for the first time without it.
- The Status column makes the macro safe to re-run: rows already marked βSentβ are skipped.
- Dir() checks the attachment exists before adding it, so one missing PDF does not stop the whole batch.
β οΈ Your company may block programmatic sending or show a security prompt. If so, keep
.Display and press Send yourself β still much faster than typing.π‘ Want your default Outlook signature? Call
.Display first, then set .HTMLBody = yourText & .HTMLBody β Outlook inserts the signature when the message is displayed.FAQ
Can I send from a shared mailbox?
Yes: set .SentOnBehalfOfName = "[email protected]" (you need βsend on behalfβ permission).
Does this work with the new Outlook for Windows?
No. The new Outlook does not support COM automation. It works with classic Outlook desktop.
Try it yourself: step by step
- Download mail-merge-list.xlsx and send-mail-merge.bas. Save the workbook as .xlsm.
- Replace the example.com addresses with your own address in every row for the first test.
- Alt+F11 β File β Import File β send-mail-merge.bas.
- Run
SendMailMerge(Alt+F8). WithPREVIEW_ONLY = Truefour draft emails open β nothing is sent, and column F says βPreviewedβ. - Clear column F, set
PREVIEW_ONLY = Falseand run again to send to yourself. Only then put real recipients in.
π Practice files for this article
- πMail merge workbook with the macro inside (.xlsm)Open, click Enable Content, put your own test address in column B and press the SendMailMerge button. Starts in safe preview mode.β¬ XLSM Β· 19 KB
Free to use for learning. Files with macros (.bas) are plain text β import them with Alt+F11 β File β Import File, and always test on a copy.