Send mails using Excel VBA and Outlook
This is a guest post by Vijay, our in-house VBA Expert.

In this article we well learn how to use VBA and Microsoft Outlook to send emails with your reports as attachment.
Scenario
We have an excel based reporting template for the Customer Service Dashboard. We want to update this template using VBA code to create a static version and email it to a list of people. We will define the recipient list in a separate sheet.
Features
1. Code will automatically create necessary folders to save the output file.
2. Email sheet to contain the list of people who are going to receive the report.
3. Sending mail using Microsoft Outlook, primary target is corporate people who are using Outlook as their mail program.

On our VBA project we would need to add references to the below
1. Microsoft Outlook Object Library
2. Microsoft Scripting Runtime Library
Please note the Outlook library will be available depending on the version of Microsoft Outlook installed on your system, in the example workbook the reference is towards version 14 as available with Outlook 2010. If you have a different version of Outlook installed on your system, you need to point to the correct library installed.

We have assumed the data used to create the report is already available in the sheet called “rawData”.
We have then updated the “rawData” sheet with 2 new columns having the Date and Time.
Date has been calculated in the rawData sheets using the Date Function.
=DATE(YEAR(B2),MONTH(B2),DAY(B2))
The time has been calculated by converting the actual time of the call into the relevant 30 minute interval.
=INT((TIME(HOUR(B2),MINUTE(B2),SECOND(B2)))/(1/48))*(1/48)
If you need to setup your report into 15 minutes interval then replace 1/48 with 1/96.
We have then used the COUNTIFS and SUMIFS function to create the data view in the Interval Data sheet.

Understanding the VBA code to send mails
I will be discussing only the key elements of the code here.
Sheets(Array("Cover", "Interval Data", "rawData")).Copy
This list will create a new workbook containing the 3 sheets that we have included within the Array() parameter. If your report has more sheets feel free to add them.
Set objfile = New FileSystemObject
If objfile.FolderExists(xDir & xMonth) Then
If objfile.FileExists(xPath) Then
objfile.DeleteFile (xPath)
newWB.SaveAs Filename:=xPath, FileFormat:=xlOpenXMLWorkbook, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False _
, CreateBackup:=False
Application.ActiveWorkbook.Close
Else
newWB.SaveAs Filename:=xPath, FileFormat:=xlOpenXMLWorkbook, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False _
, CreateBackup:=False
Application.ActiveWorkbook.Close
End If
Else
xNewFolder = xDir & xMonth
MkDir xNewFolder
newWB.SaveAs Filename:=xPath, FileFormat:=xlOpenXMLWorkbook, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False _
, CreateBackup:=False
Application.ActiveWorkbook.Close
End If
The above code checks if the correct folder exists for the report to be saved or not and creates one if not existing. This also takes cares of overwriting the existing report in case you need to re-run the report again during the same day.
Creating the List of recipients
currentWB.Activate
Sheets("Email").Visible = True
Sheets("Email").Select
strEmailTo = ""
strEmailCC = ""
strEmailBCC = ""
xStp = 1
Do Until xStp = 4
Cells(2, xStp).Select
Do Until ActiveCell = ""
strDistroList = ActiveCell.Value
If xStp = 1 Then strEmailTo = strEmailTo & strDistroList & "; "
If xStp = 2 Then strEmailCC = strEmailCC & strDistroList & "; "
If xStp = 3 Then strEmailBCC = strEmailBCC & strDistroList & "; "
ActiveCell.Offset(1, 0).Select
Loop
xStp = xStp + 1
Loop
The above code will create the list of people for whom the report is intended. We make use of the Do Until Loop here to update the 3 variables to hold the TO, CC and BCC list. The actual email addresses are captured from the Email sheet of the report template.
Please note: there should be no blanks in the list when you are defining the same.
Set olApp = New Outlook.Application
Dim olNs As Outlook.Namespace
Set olNs = olApp.GetNamespace("MAPI")
olNs.Logon
Set olMail = olApp.CreateItem(olMailItem)
olMail.To = strEmailTo
olMail.CC = strEmailCC
olMail.BCC = strEmailBCC
olMail.Subject = Mid(xFile, 1, Len(xFile) - 4)
olMail.Body = vbCrLf & "Hello Everyone," _
& vbCrLf & vbCrLf & "Please find attached the " & Mid(xFile, 1, Len(xFile) - 4) & "." _
& vbCrLf & vbCrLf & "Regards," _
& vbCrLf & "Chandoo.Org"
The above code creates a new instance of Outlook and then logs in to your default mailbox, using which we will be sending the mail out to the recipients. We also create the body of the mail and specify the To, CC and BCC list.
olMail.Attachments.Add xPath
olMail.Display
Finally we add the attachment to the email we have created and then using the Display method bring it on the screen. You may also use the .Send method to send the mail directly.
That is all the code we needed to create a copy of the report with selected few sheets and then send them out using VBA. There are a lot of other methods using which you may be able to send out mails, however this specifically helps out to create report templates to use within your organization and send out mails.
Do you also use VBA and Other methods to send mails, if yes please share the same for the benefit of everyone.
Download Excel File
Click here to download the file & save it on your system and use it to understand this technique.
Do you use Excel to automate emails?
I often use Excel to automatically email reports & messages. This is quite useful when you have to send a snapshot of a report to a large team, but need to customize the email for each recipient.
What about you? Have you used Excel to automate emails? What is your experience like? Do you use VBA or some other technique? Please share using comments.
More on VBA & Macros
If you want to learn more about using VBA to automate reporting & email tasks, read these:
- Automatically Generate Report Variations using Excel
- Birthday Reminder & Email in Excel
- What is VBA & Macros? Introduction
- Excel VBA Example Macros
- VBA tutorial videos
Join our VBA Classes
If you want to learn how to develop applications like these and more, please consider joining our VBA Classes. It is a step-by-step program designed to teach you all concepts of VBA so that you can automate & simplify your work.
Click here to learn more about VBA Classes & join us.
| ||||
|
| ||||
|
Leave a Reply
![]() |
Formula Forensic No 019. Converting uneven Text Strings to Time | Lets meet when I am in Australia | ![]() |



At Chandoo.org, I have one goal, "to make you awesome in excel and charting". This blog is started in 2007 and today has 450+ articles and tutorials on using excel, making better charts. 
25 Responses to “Send mails using Excel VBA and Outlook”
I’ve written code for Excel to email Commission Statements to Sales People each month – so the commission is firstly calculated using a combination of Access (to manipulate Raw Data from a Mainframe System) and Excel (to put this data into a readable format and calculate commission due – each sales person then has his/her own statement). VBA is then used to run through a list of Sales People, attach the relevant spreadsheet file (sometimes zipping 2 or more files for Sales Team Managers etc) and email to the relevant sales person with a bespoke email message.
This used to be a manual task and take a small team the best part of an afternoon to manual complete.
VBA is fantastic in these situations.
Hi Chandoo and once again huge thanks for the website. It’s truelly awesome!
I was wondering what would be your solution for the notification that Outlook brings up when trying to automatically send the email via VBA? At least I get an notice that a program is trying to automatically send a email on my behalf when I use the .Send method.
Keijo,
Refer to the article from Microsoft on this issue.
http://office.microsoft.com/en-us/outlook-help/i-get-warnings-about-a-program-accessing-e-mail-address-information-or-sending-e-mail-on-my-behalf-HA001229943.aspx
~VijaySharma
Thanks Vijay and the rest of you all for your tips and advices. They are very much appreciated. I’ve already solved the issue with a application.sendkeys command to send the mail, but it isn’t a very “awesome” solution so I was just wondering about other solutions. I’ll be checking out those links that you all send, thanks!
I use the ExpressClickYes application. The basic version is free and works great for me.
For many year, I have used a combination of Excel, Access and Outlook to mail various reports to the proper team members. I use a combination of my own VBA code and email code from http://www.rondebruin.nl/sendmail.htm to help automate the process. I use data from the Excel sheets to determine things like: email suject, email priority, the body of the email, etc. I’ve used this method for so long, I don’t know if I could do it manually any longer.
thanks a ton for the link to this website
that website is awesome !!! such beautiful programs for sending mail with / without attachments
regards
Subu
Good stuff! For users who might want to also venture into creating things like Meetings and Task Requests as well as emails, or want to use additional properties/methods associated with the MailItem object, you might want to check this out:
http://www.experts-exchange.com/Software/Office_Productivity/Office_Suites/MS_Office/A_4316-Automate-Outlook-in-VBA-with-the-OutlookCreateItem-Class.html
Hi Vijay,
Nice stuff, and super handy. I’ve been emailing reports from Excel for years, and finally got tired of writing the full blown code each project.
I created a class module to make this much easier, which may be of some interest to your users. It’s late bound, so no need to set any references, and works with all versions of Outlook. The frame to set up an email becomes very easy as well.
You can find it here if you’re interested: http://www.excelguru.ca/content.php?249-Easy-Outlook-Email-Integration
I email several reports and dashboards to several people each day. I prefer to simply send “screenshots” (using greenshot or similar) in the body on the email rather than trying to inserct worksheet ranges and what not particulary when sending charts.
I have been unable to find a good source of vba to automate this procedure. Everyting I can find only captures worksheet ranges instead of screen captures ( just part of the screen, like when you use the crosshairs in greenshot). If anyone has vba that will capute a partial screenshot based on screen coordinates along with the code to paste that screenshot into an outlook body I would greatly indebted.
Thanks in advance
Steve Bullen’s code comes in very handy for selecting particular sections from a worksheet, copy those to dashboard and then pasting them wherever you need. You can find it at http://www.oaltd.co.uk/excel/default.htm; look for PastePicture.zip. Works like a charm…
I’ve used the outmail thing for mailing gadgets for quite sometime.
I’ve been using a combination of Access, Excel and Outlook to send the reports for some years now. As the data and manipulation of data is straightforward, I always do the manipulation in Access. I have to generate my reports each month, and Access gives me the structure to manipulate without copying formulas etc. Once built, it works for all new added data. And while doing, you build a history. That has proven a good thing as well.
The final report is created in (or exported to) Excel, and send with Outlook. VBA makes it possible to do this without leaving Access.
@Keijo: I used to run a little program called ClickYes to get rid of the Outlook notifications. You can call this program from VBA as well. That was in Office 2003 days.
@Joe: There’s a lot of useful VBA examples around, and Ron de Bruin is one of my favorite places to go, as is Chandoo’s since the last year or so.
Hi Rene,
I agree that Ron DeBruin’s site has the best source of code all in one place for vba to email excel.
The one thing missing is the ability to email partial screenshots in an outlook body.
This is really what I need!
I use Excel and VBA with Novel GroupWise to email task update notifications from a spreadsheet we use for task tracking (Thanks to Chandoo a few years ago for some of the ideas from a TODO LIST posting). The program manager or supervisor can add a task to the job list (each person has a separate worksheet in the shared workbook) then select the rows with the new additions and run the macro. The “canned” e-mail is created with an additional message from the manager and sent to the individual and supervisor with only the updated tasks numbered and listed.
I don’t send the entire worksheet only the contents of the rows and a special few of the columns selected. Not perfect in automation but it works very well manually.
We have just changed to IBM Lotus Notes and I need to change the VBA code next week, so this post is right on time to keep me thinking straight. I have already found the VBA references I need to change to make NOTES work but it is always good to review the basics.
Thanks again Chandoo and Vijay.
Chandoo, you really need some kind of syntax highlighter.
Vijay, thanks for posting this code. I’m confused about a couple of things. Your code has Format(xDate, “mm mmmm yy”) in it, I think you meant Format(xDate, “dd mmmm yy”)? Why do you check if a file exists before deleting it? Also, why do you use FSO instead of ‘Dir’ and ‘Kill’ when you already use ‘MkDir’? Thanks for your time.
@JP,
Thanks for pointing out the “dd”, a typo from me on this.
As you can see the report was desinged at 30 minutes interval and if you needed to run the report multiple times during the day, it would be unnecessary to create multiple copies of the same, hence the delete code.
FSO is used to bring another object for people to learn, as a lot of time people do not know what are the objects / libraries that exist and how to make use of them.
~VijaySharma
I’ve been using Excel to send meeting notices to our annual internal technical conference attendees. I get an extract of the data from our registration system, then sort the data by technical session. Each session is 1 or 2 hours, and there are 3 days of sessions.
I then use VBA to build a meeting notice and add the attendees names to the meeting notice. The notice shows the data and time of the session, along with the room location. The nice part about this is that each technical session is then put in everyone’s calendar.
Since I am the originator of the meetings, I can easily send updates to the attendees if anything about the session changes (i.e, room location changes). Attendees can also see their entire schedule in outlook and on their smart phones. To do this manually would be nearly impossible. The VBA program sends out thousands of meeting notices in a few minutes through this automated process, and it works flawlessly.
[...] enjoy reading articles about interop between Outlook and Excel using VBA code. So I read the recent guest post on Chandoo's site with interest. I downloaded the sample workbook to study the code, and I suggest you do the same. [...]
I have used the VBA in Excel 2007 to send emails for bulk emails that I need, has significantly increased my productivity.
The Outlook version I have is 2007. For every email that the XLS tries to send I have to “Allow/Deny” is there a way to remove this “security” feature to allow the email/s to be directly sent w/o user intervention?
Hi everbody, I’m looking for a macro that would allow me to email thet active worksheet but that the email address is not hard coded; something that allows me enter the email address before sending it.
Any help would be very much appreciated
Hi sir,
I have tried for send mail using Excel, but When I am trying to add
5 mailing ids in the “CC” column it’s showing #value error message.
Please suggest how to send mail more than 4 or 5 people at a time.
Thanks,
ram
I am really amazed. Today I spent a lot of time searching for something interesting on this topic. Finally I found your blog. Thanks for that!
<a href=”http://medcaremso.com”><b>Medical Billing Services</b></a>
I have several basic email messages saved as xxx.msg files from outlook. I use these as templates for emailing some specific items. I’d like to incorporate the use of the the .msg file (basically just the body). I can’t seem to get it to work. Any thoughts?
Thanks,
John
Thanks for providing detailed information about email sending though Excel VB & outlook.
Open Multiple URL