Go Premium for a chance to win a PS4. Enter to Win

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 552
  • Last Modified:

VBA / Macro to distribute different excel sheets via email using a distribution list

I have an excel report which is made up of different sheets for each cost centre. This report has to be emailed to people on a distribution list. However not everybody should get the same report;

I need email recipients to only receive the sheets that relate to them.

I need to automate this process as I am sick to death of doing it manually and creating a separate excel document containing the appropriate cost centre sheets for each manager! Please help a VBA novice!
  • 3
1 Solution
bat6eeAuthor Commented:
The distribution list is just an excel sheet with the recipients name in the cell in row A and then the cost centre sheets they require in the same column (each different cost centre is on a different row)


John Smith

I need email recipients to only receive the sheets that relate to them.

The default email program is Groupwise.

This will work for you:

Function Mail_It()

strPath = "InsertAttachmentFolderPath"
strSender = "InsertSenderAddress"
strSMTP = "InsertSMTPServer"
strSubject = "InsertSubject"
strBody = "InsertMessageBody"
strExt = "InsertFileExtension"

c = 1
r = 1

strRecipient = Cells(r, c) & " <" & Cells(r + 1, c) & ">"
Set iMsg = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")
iConf.Load -1    ' CDO Source Defaults
Set Flds = iConf.Fields
With Flds
    .Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTP
    .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
End With
With iMsg
    Set .Configuration = iConf
    .To = strRecipient
    .CC = ""
    .BCC = ""
    .From = "<" & strSender & ">"
    .Subject = strSubject
    .TextBody = strBody
    r = 3
    If Not Cells(r, c) = "" Then
    .AddAttachment strPath & Cells(r, c) & strExt
    r = r + 1
    End If
    Loop While Not Cells(r, c) = ""
End With
Set iMsg = Nothing
Set iConf = Nothing
c = c + 1
r = 1
Loop While Not Cells(r, c) = ""
End Function

I would suggest rearranging your distribution list so that all of your cost centres are in the same column and all of the corresponding names and addresses for each cost centre are in their respective rows.  It should look something like this:

   |        A         |        B               |                 C                        
1 | Cost Centre  |    Name            |     E-mail
2 | 110111        |    John Smith     |    jsmith@hotmail.com
3 | 110112        |    John Smith     |    jsmith@hotmail.com
4 | 110150        |    John Smith     |    jsmith@hotmail.com
5 | 112113        |    John Smith     |    jsmith@hotmail.com
6 | 222222        |    Jane Doe        |    jdoe@yahoo.com

Doing that, you will have more of a database to work with.  It's not "normalized", but it is better structured than what you currently have.

Next, you want to make sure that that each sheet in your workbook is named with the same number found in the "Cost Centre" column (in my example, that would be Excel column A).

Your code can then use a looping sequence to read each cost centre name, attribute that name to the worksheet in your workbook with the same name, and then send the e-mail to the person in the same row that the cost centre was found.

For example:

Public Sub Export_and_Email_Reports()
    Dim objWkbook as Workbook, objCurrWkbk as Workbook
    Dim strCostCentre as String, strName as String, strEmail as String
    Dim i as Integer

    Application.DisplayAlerts = False   'turn off the warning messages for deleting sheets
    Application.ScreenUpdating = False 'turning this off speeds up your program

    Activesheet.Range("A2").Activate  'I put field names in row 1; data begins row 2
    Set objCurrWkbk = ActiveWorkbook  'keep track of your current workbook

    While Activecell.Value <> ""         'do until you reach a blank cell
        strCostCentre = ActiveCell.Value
        strName = ActiveCell.Offset(0,1).Value
        strEmail = ActiveCell.Offset(0,2).Value

        Set objWkbook = Workbooks.Add  'create a new workbook for each cost centre

        ActiveWorkbook.Sheets(strCostCentre).Copy After:=objWkbook.Sheets(3)

        For i = 1 to 3           'normally a new workbook has three blank worksheets
            Sheets(1).Delete  'delete each blank sheet (we copied the cost sheet as fourth)
        ActiveWorkbook.SaveAs Filename:="C:\" & strCostCenter & ".xls", FileFormat:= _
        xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False _
        , CreateBackup:=False

       '**need code here to attach workbook to e-mail message. see note below **

     Application.DisplayAlerts = True         'turn warning messages back on
     Application.ScreenUpdating = True     'turn screen updating back on
End Sub

**I purposely didn't take the time to type out the code for the e-mail message since I'm not sure that the stuff I've put here is what you are looking for.  If it is, I can go the next step and show you how to attach to e-mail message.  I normally use "early binding" and set the reference to Microsoft Outlook Object Library in the VB Editor.**

Oops I forgot.

You'll need to include:

ActiveCell.Offset(1,0).Activate  'go to next line

right above (before) the line of code that reads:


You'll find "Wend" towards the end of the subroutine.

This is necessary to advance the cursor to read the next line each iteration of the loop!

Sorry...hope I didn't confuse you!

I have nothing else to add at this time...I believe my response would solve the problem.


Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now