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

Posted on 2004-09-18
Medium Priority
Last Modified: 2013-12-26
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!
Question by:bat6ee
  • 3

Author Comment

ID: 12095587
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.


Expert Comment

ID: 12119516
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


Accepted Solution

DrewK earned 2000 total points
ID: 12157050
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.**


Expert Comment

ID: 12157067
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!


Expert Comment

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


Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

589 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question