AtTips, Tricks & Tools
for Microsoft® Office Outlook®

Green arrowBuy an Upgrade now

Deutsch
Tips Programming Mail merge with attachments

Mail merge with attachments

In Outlook® you can sent mass mails but without attachments.

With the following code you can send mass mails with attachments by category. If you do not work with categories please set the constant MYCATEGORIES As String = "".

First of all create an e-mail without recipients but with subject and attachments and save it as a template (.oft). The code uses a template called Mail.oft and is saved to C:\.

If the e-mails will not be sent imeadetly they will be saved per default in the drafts folder. To sent these e-mails mark them and drag them into the outbox folder. In the article E-mail remains in the outbox you find out how these e-mails can be sent.

The code works for plain text and HTML e-mails. HTML e-mails may not have the same font as the inserted salutation. For this reason the constant CSSTITLE will be used. With this constant you can format the salutation as you want. Therfore you need some CSS knowledge but the important properties are already available.

The original code askes you every time for a folder with reciepients. If you use always the same folder or if you have only one folder you can predefine the folder. Pleas read the comment Predefine contact folder.

To use this example please read the important notes and have a look to the workshop Use VBA in Outlook®. You can insert this code into a new module (Insert -> Module in the VBA-Editor).

For Outlook® 2002, Outlook® 2003, Outlook® 2007

Option Explicit
 
' Sent e-mails only to this categories:
' Seperate multiple categories by a colon (;)
' Leave empty to send to all contacts
Private Const MYCATEGORIES As String = ""
 
' Mail template (with or without attachments):
Private Const TEMPLATE As String = "C:\Mail.oft"
 
' CSS code to format the title in HTML-e-mails:
Private Const CSSTITLE As String = _
    "font-family: Arial; font-size: 10pt; color: black; font-weight: normal"
 
' Titel for dialogs:
Private Const MSGBOXTITLE As String = "Create Mail Merge"
 
Public Sub MailMerge()
 
    '=====================================================================
    ' Creates e-mails from a contact folder (by category) with attachments
    ' (and send it).
    ' (c) Peter Marchert - http://www.outlook-stuff.com
    ' 2008-11-05 Version 1.0.0
    '=====================================================================
 
    Dim vbResult As VBA.VbMsgBoxResult      ' User action
 
    Dim objFolder As Outlook.MAPIFolder     ' Contact folder
    Dim objItems As Outlook.Items           ' Items of a folder
    Dim objContact As Outlook.ContactItem   ' Single contact
    Dim objMail As Outlook.MailItem         ' Single E-Mail
 
    Dim strFilter As String                 ' Filter
 
    Dim lngMails As Long                    ' Created e-mails
    Dim blnSend As Boolean                  ' Send e-mail imeadetly?
 
    '---------------------------------------------------------------------
    ' Predefine a contact folder (for the Business contacts of the
    ' Business Contact Manager please remove the first and second apostrophe,
    ' for the default contacts folder please remove only the last apostrophe).
    '---------------------------------------------------------------------
    'Set objFolder = Outlook.Session.Folders("Business Contact Manager")
    'Set objFolder = objFolder.Folders("Business Contacts")
    'Set objFolder = Outlook.Session.GetDefaultFolder(olFolderContacts)
 
    '---------------------------------------------------------------------
    ' If no folder is predefined a folder picker will be shown
    '---------------------------------------------------------------------
    If objFolder Is Nothing Then Set objFolder = ChooseFolder
 
    '---------------------------------------------------------------------
    ' No contacts folder predefined/choosen?
    '---------------------------------------------------------------------
    If objFolder Is Nothing Then Exit Sub
 
    '---------------------------------------------------------------------
    ' Send e-mails imeadetly?
    '---------------------------------------------------------------------
    vbResult = MsgBox("Should the e-mails be send imeadetly?", vbQuestion + _
        vbYesNoCancel + vbDefaultButton2, MSGBOXTITLE)
    If vbResult = vbYes Then
        blnSend = True
    ElseIf vbResult = vbCancel Then
        GoTo ExitProc
    End If
 
    '---------------------------------------------------------------------
    ' Some time for the message box to close
    '---------------------------------------------------------------------
    DoEvents
 
    '---------------------------------------------------------------------
    ' Reference the elements in the folder
    '---------------------------------------------------------------------
    Set objItems = objFolder.Items
 
    '---------------------------------------------------------------------
    ' Only contacts are needed, no distlists. To filter by categories is
    ' not possible with VBA, otherwise it could be done here too.
    '---------------------------------------------------------------------
    strFilter = "[MessageClass] <> ""IPM.DistList"""
 
    '---------------------------------------------------------------------
    ' Filter the elements
    '---------------------------------------------------------------------
    Set objItems = objItems.Restrict(strFilter)
 
    '---------------------------------------------------------------------
    ' Proceed the contacts
    '---------------------------------------------------------------------
    For Each objContact In objItems
 
        '-----------------------------------------------------------------
        ' If he containst the specified category the e-mail will be created
        '-----------------------------------------------------------------
        If CreateMail(objContact.Categories) Then
 
            '-------------------------------------------------------------
            ' Create new e-mail from template
            '-------------------------------------------------------------
            Set objMail = Outlook.CreateItemFromTemplate(TEMPLATE)
 
            With objMail
 
                '---------------------------------------------------------
                ' E-mail address is missing?
                '---------------------------------------------------------
                If InStr(objContact.Email1Address, "@") = 0 Then
                    If MsgBox("The contact """ & objContact.FullName & _
                        """ has no e-mail address.", vbExclamation + _
                        vbOKCancel, MSGBOXTITLE) = vbCancel Then Exit Sub
                    GoTo Skippy
                End If
 
                '---------------------------------------------------------
                ' Set the e-mail address
                '---------------------------------------------------------
                If Left(Trim(objContact.Email1DisplayName), 1) = "(" Then
                    .To = objContact.Email1Address
                Else
                    .To = objContact.Email1DisplayName
                End If
 
                '---------------------------------------------------------
                ' Get the salutation and insert it
                '---------------------------------------------------------
                Call InsertHello(objMail, objContact)
 
                '---------------------------------------------------------
                ' Save new e-mail (Default is the folder "Drafts")
                '---------------------------------------------------------
                .Save
 
                '---------------------------------------------------------
                ' If send then send
                '---------------------------------------------------------
                If blnSend Then .Send
 
                '---------------------------------------------------------
                ' Increase counter for summary message
                '---------------------------------------------------------
                lngMails = lngMails + 1
 
            End With
 
        End If
 
Skippy:
 
        '-----------------------------------------------------------------
        ' Clear reference to the contact
        '-----------------------------------------------------------------
        Set objContact = Nothing
 
        '-----------------------------------------------------------------
        ' Clear reference to the e-mail
        '-----------------------------------------------------------------
        Set objMail = Nothing
 
    Next
 
    '---------------------------------------------------------------------
    ' Inform user
    '---------------------------------------------------------------------
    If blnSend Then
        MsgBox "Sent e-mails: " & lngMails & Chr(9), vbInformation _
            + vbOKOnly, MSGBOXTITLE
    Else
        MsgBox "Created e-mails: " & lngMails & Chr(9), vbInformation + _
            vbOKOnly, MSGBOXTITLE
    End If
 
ExitProc:
 
    '---------------------------------------------------------------------
    ' Clear references
    '---------------------------------------------------------------------
    Set objItems = Nothing
    Set objFolder = Nothing
 
End Sub
 
Private Function ChooseFolder() As Outlook.MAPIFolder
 
    '=====================================================================
    ' Returns a choosen contact folder
    ' 2008-11-05 Version 1.0.0
    '=====================================================================
 
    Dim objFolder As Object
 
    '---------------------------------------------------------------------
    ' Show a hint
    '---------------------------------------------------------------------
    If MsgBox("Please choose in the next dialog the" & vbCrLf & _
        "contact folder with the desired reciepients.", vbInformation _
        + vbOKCancel, MSGBOXTITLE) = vbCancel Then Exit Function
 
    '---------------------------------------------------------------------
    ' Stay in loop until a valid contact folder was choosen or the user
    ' breaked the dialog
    '---------------------------------------------------------------------
    Do
 
        '-----------------------------------------------------------------
        ' Show the folder picker
        '-----------------------------------------------------------------
        Set objFolder = Nothing
        Set objFolder = Outlook.Session.PickFolder
 
        '-----------------------------------------------------------------
        ' User cancled?
        '-----------------------------------------------------------------
        If objFolder Is Nothing Then Exit Function
 
        '-----------------------------------------------------------------
        ' Wrong folder type?
        '-----------------------------------------------------------------
        If InStr(objFolder.DefaultMessageClass, "IPM.Contact") = 0 Then
            Set objFolder = Nothing
            If MsgBox("Please choose a folder for contacts." _
                , vbCritical + vbOKCancel, "Choose contact folder") = vbCancel Then
                Exit Function
            End If
        End If
 
    Loop While objFolder Is Nothing
 
    '---------------------------------------------------------------------
    ' Return folder and/or nothing
    '---------------------------------------------------------------------
    Set ChooseFolder = objFolder
 
    '---------------------------------------------------------------------
    ' Clean Up
    '---------------------------------------------------------------------
    Set objFolder = Nothing
 
End Function
 
Private Function CreateMail(ByVal strCategories As String) As Boolean
 
    '=====================================================================
    ' Returns true if the contact contains the defined categories
    ' 2008-11-05 Version 1.0.0
    '=====================================================================
 
    Dim aryContactCats() As String    ' Array with categories of the contact
    Dim aryConstantCats() As String   ' Array with categories of the constant
 
    Dim lngConstant As Long     ' Loop counter for the constant
    Dim lngContact As Long      ' Loop counter for the contact
 
    On Error Resume Next
 
    '---------------------------------------------------------------------
    ' If no categories are defined the e-mail will be sent always
    '---------------------------------------------------------------------
    If Trim(Replace(MYCATEGORIES, ";", "")) = "" Then
        CreateMail = True
        Exit Function
    End If
 
    '---------------------------------------------------------------------
    ' Load the contacts categories into a field
    '---------------------------------------------------------------------
    aryContactCats() = Split(strCategories, ";")
 
    '---------------------------------------------------------------------
    ' Load the constants categories into a field
    '---------------------------------------------------------------------
    aryConstantCats() = Split(MYCATEGORIES, ";")
 
    '---------------------------------------------------------------------
    ' Contains the contact all categories of the constant?
    '---------------------------------------------------------------------
    For lngConstant = 0 To UBound(aryConstantCats())
 
        '-----------------------------------------------------------------
        ' Reset function
        '-----------------------------------------------------------------
        CreateMail = False
 
        '-----------------------------------------------------------------
        ' Proceed all categories of the contact
        '-----------------------------------------------------------------
        For lngContact = 0 To UBound(aryContactCats())
 
            '-------------------------------------------------------------
            ' If he contains the searched category this function will be
            ' set to "True"
            '-------------------------------------------------------------
            If LCase(Trim(aryContactCats(lngContact))) = _
                LCase(aryConstantCats(lngConstant)) Then
                CreateMail = True
                Exit For
            End If
 
        Next
 
        '-----------------------------------------------------------------
        ' End, if the contact did not contain the category
        '-----------------------------------------------------------------
        If Not CreateMail Then Exit For
 
    Next
 
End Function
 
Private Sub InsertHello(ByRef objMail As Outlook.MailItem, _
    ByVal objContact As Outlook.ContactItem)
 
    '=====================================================================
    ' Gets the salutation and insert it into the e-mail
    ' 2008-11-05 Version 1.0.0
    '=====================================================================
 
    Dim lngBodyEnd As Long     ' End of the body tag
 
    With objMail
 
        '-----------------------------------------------------------------
        ' Get the end of the body line (for HTML e-mails)
        '-----------------------------------------------------------------
        lngBodyEnd = InStr(LCase(.HTMLBody), "<body")
        If lngBodyEnd Then lngBodyEnd = InStr(lngBodyEnd + 1, .HTMLBody, ">")
 
        '-----------------------------------------------------------------
        ' If a last name exists this will be used
        '-----------------------------------------------------------------
        If Trim(objContact.LastName) <> "" Then
 
            '-------------------------------------------------------------
            ' Exists a German male title?
            '-------------------------------------------------------------
            If objContact.Title = "Herr" Then
 
                If .BodyFormat = olFormatHTML Then
                    .HTMLBody = Left(.HTMLBody, lngBodyEnd) & _
                        "<span style=" & Chr(34) & CSSTITLE & Chr(34) & _
                        ">Sehr geehrter Herr " & objContact.LastName & _
                        ",</span><br><br>" & Mid(.HTMLBody, lngBodyEnd + 1)
                Else
                    .Body = "Sehr geehrter Herr " & objContact.LastName _
                        & "," & vbCrLf & vbCrLf & .Body
                End If
 
            '-------------------------------------------------------------
            ' Exists a German female title?
            '-------------------------------------------------------------
            ElseIf objContact.Title = "Frau" Then
 
                If .BodyFormat = olFormatHTML Then
                    .HTMLBody = Left(.HTMLBody, lngBodyEnd) & _
                        "<span style=" & Chr(34) & CSSTITLE & Chr(34) & _
                        ">Sehr geehrte Frau " & objContact.LastName & _
                        ",</span><br><br>" & Mid(.HTMLBody, lngBodyEnd + 1)
                Else
                    .Body = "Sehr geehrte Frau " & objContact.LastName _
                        & "," & vbCrLf & vbCrLf & .Body
                End If
 
            '-------------------------------------------------------------
            ' Exists an English male title?
            '-------------------------------------------------------------
            ElseIf LCase(objContact.Title) = "mr." Then
 
                If .BodyFormat = olFormatHTML Then
                    .HTMLBody = Left(.HTMLBody, lngBodyEnd) & _
                        "<span style=" & Chr(34) & CSSTITLE & Chr(34) & _
                        ">Dear Mr. " & objContact.LastName & _
                        ",</span><br><br>" & Mid(.HTMLBody, lngBodyEnd + 1)
                Else
                    .Body = "Dear Mr. " & objContact.LastName _
                    & "," & vbCrLf & vbCrLf & .Body
                End If
 
            '-------------------------------------------------------------
            ' Exists an English female title?
            '-------------------------------------------------------------
            ElseIf LCase(objContact.Title) = "mrs." Then
 
                If .BodyFormat = olFormatHTML Then
                    .HTMLBody = Left(.HTMLBody, lngBodyEnd) & _
                        "<span style=" & Chr(34) & CSSTITLE & Chr(34) & _
                        ">Dear Mrs. " & objContact.LastName & _
                        ",</span><br><br>" & Mid(.HTMLBody, lngBodyEnd + 1)
                Else
                    .Body = "Dear Mrs. " & objContact.LastName _
                    & "," & vbCrLf & vbCrLf & .Body
                End If
 
            End If
 
        '-----------------------------------------------------------------
        ' No title exists -> use a general salutation
        '-----------------------------------------------------------------
        Else
 
            If .BodyFormat = olFormatHTML Then
                .HTMLBody = Left(.HTMLBody, lngBodyEnd) & _
                    "<span style=" & Chr(34) & CSSTITLE & Chr(34) & _
                    ">Dear ladies and sirs," & _
                    "</span><br><br>" & Mid(.HTMLBody, lngBodyEnd + 1)
            Else
                .Body = "Dear ladies and sirs," & vbCrLf & _
                    vbCrLf & .Body
            End If
 
        End If
 
    End With
 
    '---------------------------------------------------------------------
    ' Clean Up
    '---------------------------------------------------------------------
    Set objContact = Nothing
 
End Sub

Newsletter

NewsletterSorry, the Newsletter Service from outlook-stuff.com is currently only available in German. If you are nevertheless interested you may translate them with an online translation service.

Cart

Your cart is empty
Show the product page...

Product State

Updates

Report a bug

On this page you have a bug:

Newsflash

5. Newsletter wurde verschickt!

Sorry, no translation available.

Heute wurde der 5. Newsletter an alle Abonennten verschickt.

 Read more...

Lifetime Updates incl.!

Yes, it is really true: In outlook-stuff.com, you pay not a penny extra for updates!
Lifetime Updates incl.!

Pay once = use forever!

to the Shop...

Product Range

Close