To send email from Excel with VBA, use a macro to read a recipient, subject, and message from cells, then create a message in classic Outlook for Windows. The example below opens the message for review before sending; you can change one line to send automatically after you have checked that the workbook and recipient data are correct. You need desktop Excel and classic Outlook configured on the same Windows computer.
What You’ll Need
- Excel for Microsoft 365 desktop on Windows. Excel for the web cannot create or run VBA macros.
- Classic Outlook for Windows, installed and set up with an account that can send mail. Outlook automation through VBA does not work with the new Outlook for Windows.
- A workbook saved as an Excel Macro-Enabled Workbook (.xlsm), plus permission to run macros under your organization’s security policy.
- A copy of the workbook to use while setting up and checking the macro. Macro actions cannot be undone with Ctrl+Z.
This example uses late binding, so you do not need to add an Outlook reference in the Visual Basic Editor. It creates an email draft rather than sending immediately, which makes it easier to catch incorrect addresses, missing information, or unexpected formatting.
Step-by-Step
-
Set up the worksheet. Add a worksheet named
Email. Put the recipient address in A2, the subject in B2, and the plain-text message in C2. For example, enter a test address you control in A2, “Monthly report” in B2, and “Please find the report attached.” in C2. The code reads those cells from the workbook containing the macro. -
Save a working copy as an .xlsm file. In Excel, choose File > Save As, select a location, and choose Excel Macro-Enabled Workbook (*.xlsm) as the file type. Saving as .xlsx removes VBA code. Keep the original workbook unchanged until you have tested the copy.
-
Open the Visual Basic Editor and insert a module. In Excel for Windows, press Alt+F11, or use Developer > Visual Basic. In the editor, choose Insert > Module. If the Developer tab is not visible, enable it through File > Options > Customize Ribbon and select Developer. On Excel for Mac, use Tools > Macro > Visual Basic Editor; the keyboard shortcut may require Option+F11 or Fn+Option+F11 depending on the keyboard. This Outlook COM example itself is for Windows, not Mac.
-
Paste the macro into the module. The macro checks that the required cells are filled, creates an Outlook message, and displays it for review. It uses generic Object variables for Outlook, so no reference setting is needed.
Option Explicit Sub CreateEmailFromSheet() Dim ws As Worksheet Dim olApp As Object Dim olMail As Object Dim recipient As String Dim emailSubject As String Dim messageBody As String On Error GoTo ErrHandler ' Read the email details from the Email worksheet. Set ws = ThisWorkbook.Worksheets("Email") recipient = Trim$(CStr(ws.Range("A2").Value)) emailSubject = Trim$(CStr(ws.Range("B2").Value)) messageBody = CStr(ws.Range("C2").Value) ' Stop rather than open a blank or misdirected draft. If recipient = "" Or emailSubject = "" Or messageBody = "" Then MsgBox "Fill in the recipient, subject, and message first.", vbExclamation Exit Sub End If If InStr(1, recipient, "@", vbTextCompare) = 0 Then MsgBox "Check the recipient address in cell A2.", vbExclamation Exit Sub End If ' Create a message in classic Outlook and show it for review. Set olApp = CreateObject("Outlook.Application") Set olMail = olApp.CreateItem(0) With olMail .To = recipient .Subject = emailSubject .Body = messageBody .Display End With CleanExit: Set olMail = Nothing Set olApp = Nothing Exit Sub ErrHandler: MsgBox "Email could not be created: " & Err.Description, vbExclamation Resume CleanExit End SubThe address check is deliberately basic: it catches a missing at sign, but it cannot confirm that an address exists or is deliverable. Outlook can also accept multiple recipients separated by semicolons. Test with a single address first.
-
Save the VBA project. In the Visual Basic Editor, press Ctrl+S on Windows, then return to Excel with Alt+Q or close the editor. If Excel asks whether to save the workbook, confirm. On Mac, use Command+S to save, but remember that the Outlook automation code above is not compatible with Mac Outlook.
-
Allow the macro to run if required. When you reopen the file, Excel may show a security warning. Only enable macros for a workbook you trust. If the computer is managed by an employer, policy may block macros; do not try to bypass that restriction. Ask the administrator for an approved method.
-
Run the macro and inspect the draft. In Excel for Windows, press Alt+F8, select
CreateEmailFromSheet, and choose Run. You can also run it from Developer > Macros. Outlook should open a message with the cell values filled in. Confirm the To address, subject, message, and sending account before clicking Send in Outlook. Press Alt+F8 again to run it after changing the worksheet values. -
Switch to immediate sending only if appropriate. Once the draft version behaves as intended, replace
.Displaywith.Sendin the macro. That sends without giving you a review screen, usually through the default Outlook account. Test with your own address and a small number of messages first. For business or bulk mail, use an approved mailing or automation system and follow your organization’s consent and privacy rules.
Common Mistakes
Using new Outlook instead of classic Outlook: VBA’s CreateObject("Outlook.Application") relies on Outlook’s Windows COM automation interface. New Outlook for Windows does not provide that interface. If this line fails, check which Outlook app is installed and whether classic Outlook is available; do not assume reinstalling Excel will fix it.
Saving as .xlsx: This format cannot retain macros. Save the file as .xlsm and reopen that copy. Also make sure the macro is in a standard module, not pasted into a worksheet’s code window, unless you deliberately intend to use an event procedure.
Changing worksheet names or cell locations: The code requires a sheet named exactly Email and values in A2, B2, and C2. If you use other locations, update the sheet name and range references in the macro. Leading or trailing spaces in a sheet name can cause a “Subscript out of range” error.
Sending before reviewing: Replacing .Display with .Send too early can send incomplete messages or expose information to the wrong recipient. The sample’s basic address check is not a substitute for verifying the full address. Keep .Display until the process has been checked end to end.
Tips
Use a separate test sheet or a copy of your workbook while developing the macro. Include a clear test subject, and send only to an address you control. After testing, keep a visible note near the input cells explaining what each one is for and whether the macro sends automatically or opens a draft.
For a multi-line message, type line breaks directly into C2, or build the body in VBA with vbCrLf between lines. The sample uses .Body, which creates a plain-text message. For formatted HTML email, you can use Outlook’s .HTMLBody property, but the body must contain valid HTML and should be tested in Outlook before sending. Do not simply put HTML tags into C2 while leaving the code set to .Body; recipients will see the tags as text.
You can add an attachment with .Attachments.Add inside the With olMail block, but use a real, accessible file path and check that the file exists before adding it. A hard-coded path can stop working when a workbook moves to another computer or folder. If you add an attachment feature, test it with a harmless file and confirm the attachment appears in the draft.
Keep the review step for messages containing personal, financial, or confidential information. When creating many messages, add safeguards such as a recipient count limit, a confirmation prompt, and logging of what was prepared. Avoid sending bulk mail through a personal account without checking applicable organizational rules and recipient permissions.
Troubleshooting
“ActiveX component can’t create object” or an automation error: Confirm that classic Outlook for Windows is installed and has been opened and configured at least once. New Outlook does not support this COM approach. Also verify that Excel and Outlook are desktop apps on the same Windows computer, rather than Excel in a browser or Outlook on the web.
“Subscript out of range”: Check that the worksheet tab is named Email exactly and is in the same workbook as the code. The sample uses ThisWorkbook, meaning the workbook that contains the macro, not necessarily whichever workbook is currently active.
The macro does not appear in Alt+F8: Check that the code is in a standard module, the procedure is named CreateEmailFromSheet, and it is a public macro with no arguments. Confirm the file is .xlsm and that macros are allowed. A company security policy can prevent running it even when the code is correct.
Outlook opens but no message is created or sent: Run the version with .Display and read any error message. Check that A2, B2, and C2 are not blank, that the address is spelled correctly, and that Outlook has a working account. If a draft appears but sending fails, use Outlook’s Outbox and connection status to diagnose the mail delivery issue; Excel cannot override account or server restrictions.
Messages go from the wrong account or show an unexpected signature: Outlook may use its default account or insert a signature according to its settings. Review the draft’s From field and content before sending. If your workflow requires a particular account, configure and test account selection explicitly rather than relying on an assumed default.
Frequently Asked Questions
Can Excel send an email without Outlook?
This example requires classic Outlook for Windows. Excel VBA can use other services or interfaces, but they need separate configuration, authentication, and often administrator approval. Do not paste email passwords into a macro; use an approved method for your mail service.
Does this work in Excel for the web?
No. Excel for the web can open an .xlsm workbook but cannot run its VBA macros. Open the workbook in desktop Excel for Windows, with classic Outlook available, to use this particular code.
Can I send to multiple people?
Yes. In Outlook’s To field, separate addresses with semicolons. You can also use the Cc and Bcc properties in VBA, such as .CC = "person@example.com" or .BCC = "person@example.com". Check every address and be mindful of recipient privacy before sending.
Can I send an email with an attachment?
Yes. Add an attachment using Outlook’s .Attachments.Add method inside the message’s With block, providing the full path to an existing file. Verify the path and inspect the draft to make sure the intended file is attached.
Will the macro work on a Mac?
Not as written. It uses Windows COM automation to control classic Outlook, which is not available in Excel for Mac. Mac users need a different approach, such as an approved AppleScript-based workflow or an organizational automation service, and should test compatibility with their specific Outlook setup.
Can I undo an email sent by the macro?
Ctrl+Z cannot undo a sent email. Depending on the mail system, a limited recall feature may be available, but it is not reliable across recipients. Use .Display, verify the draft, and send a test message before enabling automatic sending.
Related
- Excel Solver: Find Combinations That Sum to a Target
- Excel Slicers Explained: Filtering PivotTables and Tables
- Excel Slicer Search: How to Find Items in a Slicer
Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.
More in VBA & macros
- Import CSV to Excel Using VBA: A Safe, Repeatable MethodTo import a CSV file into Excel with VBA, use Workbooks.OpenText to parse the file, then copy its…
- Excel VBA Delete a Workbook: Safe Methods and CodeYes. Excel VBA can delete a workbook file from disk, but the workbook must be closed first: Workbook.Close…
- VBA Error Handling for Multiple Errors in One MacroVBA handles runtime errors one at a time: use On Error GoTo to route an unexpected failure to…
- Active Worksheet in VBA: How to Reference ItIn Excel VBA, use the ActiveSheet object to refer to the tab that is active at that moment.…
- Excel VBA: How to Find the Next Empty Cell in a ColumnTo find the next empty cell below the last entry in an Excel column, use VBA’s End(xlUp) navigation…
- VBA Find Function: Examples, Options, and Common FixesIn Excel VBA, use the Range.Find method to search a range for a value or text. For example,…
Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources
Spotted an error in this guide? Let us know.