OfficeTalk: Using the Excel Object Model to Send Workbooks and Ranges through E-Mail with Outlook (Part 1 of 2)

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

Summary: Microsoft Excel MVP Ron de Bruin provides several samples and a useful add-in that makes it easy for customers to send items from Excel with Outlook. From sending a workbook to sending items to multiple recipients, the code samples and add-in should become a part of your reference library. (8 printed pages)

Applies to:   Microsoft Excel 2000 | Microsoft Excel 2002 | Microsoft Excel 2003 | Microsoft Excel 2007 | Microsoft Excel 2010 | Microsoft Outlook 2000 | Microsoft Outlook 2002 | Microsoft Outlook 2003 | Microsoft Outlook 2007 | Microsoft Outlook 2010
Provided by:   MVP   Ron de Bruin, Microsoft Excel MVP | Frank Rice, Microsoft Corporation | About the Authors

Contents

  • Sending Outlook E-mail Messages from Excel

  • Mailing Workbooks as E-mail Attachments

  • Mailing Single Sheets as Attachments

  • Conclusion

Read Part Two: OfficeTalk: Using the Excel Object Model to Send Workbooks and Ranges through E-Mail with Outlook (Part 2 of 2)

Sending Outlook E-mail Messages from Excel

This article features code samples that you can use to perform various e-mail functions from Microsoft Office Excel by using the Microsoft Office Outlook object model. Ron de Bruin, an Excel Most Valuable Professional (MVP) and a frequent contributor to the newsgroups, provides the samples and add-in. You can find many more samples and an excellent add-in (RDBMail Add-in) that gives you several e-mail options on the Ribbon user interface (UI), at Ron’s Web site.

Sending workbooks and workbook components from Excel with Outlook is a frequently requested activity. It is relatively easy to do much of this by using commands on the Ribbon UI. However, you may want more control over what you can send. Doing this by using Microsoft Visual Basic for Applications (VBA) in Excel is where developers can make the biggest impact.

One method to use is the SendMail method in the Excel object model. This method works very well but is limited in what it can do. You can find examples using the SendMail method and a link to download a useful add-in created by Ron de Bruin in the article titled Working with Excel Workbooks and Worksheets in E-Mail.

Note

The code samples that are presented in this article will only work with Microsoft Outlook. They will not work with Microsoft Outlook Express or Microsoft Windows Mail.

You need to be aware of two security features for Outlook 2002, Outlook 2003, Outlook 2007, and Outlook 2010. Note that these features are implemented through a security update in Outlook 2000:

  • Blocking of a customizable list of file attachments considered unsafe because they can be used to propagate viruses.

  • Pop-up confirmation dialog boxes that occur when a program accesses address-related properties or attempts to send a message.

For more information about Outlook 2007 and Outlook 2010, see the article titled Code Security Changes in Outlook 2007.

In the following sections, I describe some of the VBA code samples created by Ron de Bruin.

Mailing Workbooks as E-mail Attachments

The following subroutine sends the last saved version of the active workbook in an e-mail message. Change the mail address and subject in the macro before you run the procedure.

Sub Mail_Workbook_1()
' Works in Excel 2000, Excel 2002, Excel 2003, Excel 2007, Excel 2010, Outlook 2000, Outlook 2002, Outlook 2003, Outlook 2007, Outlook 2010.
' This example sends the last saved version of the Activeworkbook object .
    Dim OutApp As Object
    Dim OutMail As Object

    Set OutApp = CreateObject("Outlook.Application")
    Set OutMail = OutApp.CreateItem(0)

    On Error Resume Next
   ' Change the mail address and subject in the macro before you run it.
    With OutMail
        .To = "ron@debruin.nl"
        .CC = ""
        .BCC = ""
        .Subject = "This is the Subject line"
        .Body = "Hello World!"
        .Attachments.Add ActiveWorkbook.FullName
        ' You can add other files by uncommenting the following line.
        '.Attachments.Add ("C:\test.txt")
        ' In place of the following statement, you can use ".Display" to
        ' display the mail.
        .Send   
    End With
    On Error GoTo 0

    Set OutMail = Nothing
    Set OutApp = Nothing
End Sub

The following subroutine sends a newly created workbook as a copy of the ActiveWorkbook object. Before sending the workbook, it is saved with a date-time stamp. After the file is sent, the workbook is deleted from the hard disk drive.

Sub Mail_workbook_Outlook_2()
' Works in Excel 2000, Excel 2002, Excel 2003, Excel 2007, Excel 2010, Outlook 2000, Outlook 2002, Outlook 2003, Outlook 2007, Outlook 2010.
    Dim wb1 As Workbook
    Dim wb2 As Workbook
    Dim TempFilePath As String
    Dim TempFileName As String
    Dim FileExtStr As String
    Dim OutApp As Object
    Dim OutMail As Object

    Set wb1 = ActiveWorkbook
    If Val(Application.Version) >= 12 Then
        If wb1.FileFormat = 51 And wb1.HasVBProject = True Then
            MsgBox "There is VBA code in this xlsx file. There will" & vbNewLine & _
                   "be no VBA code in the file you send. Save the" & vbNewLine & _
                   "file as a macro-enabled (. Xlsm) and then retry the macro.", vbInformation
            Exit Sub
        End If
    End If

    With Application
        .ScreenUpdating = False
        .EnableEvents = False
    End With

    ' Make a copy of the file.
    ' If you want to change the file name then change only TempFileName variable.
    TempFilePath = Environ$("temp") & "\"
    TempFileName = "Copy of " & wb1.Name & " " & Format(Now, "dd-mmm-yy h-mm-ss")
    FileExtStr = "." & LCase(Right(wb1.Name, _
                                   Len(wb1.Name) - InStrRev(wb1.Name, ".", , 1)))

    wb1.SaveCopyAs TempFilePath & TempFileName & FileExtStr
    Set wb2 = Workbooks.Open(TempFilePath & TempFileName & FileExtStr)

    Set OutApp = CreateObject("Outlook.Application")
    
    Set OutMail = OutApp.CreateItem(0)

    On Error Resume Next
   ' Change the mail address and subject in the macro before you run this procedure.
    With OutMail
        .To = "ron@debruin.nl"
        .CC = ""
        .BCC = ""
        .Subject = "This is the Subject line"
        .Body = "Hello World!"
        .Attachments.Add wb2.FullName
        ' You can add other files by uncommenting the following line.
        '.Attachments.Add ("C:\test.txt")
        ' In place of the following statement, you can use ".Display" to
        ' display the mail.
        .Send   
    End With
    On Error GoTo 0

    wb2.Close SaveChanges:=False

    ' Delete the file.
    Kill TempFilePath & TempFileName & FileExtStr

    Set OutMail = Nothing
    Set OutApp = Nothing

    With Application
        .ScreenUpdating = True
        .EnableEvents = True
    End With
End Sub

Tip

In the previous example, the file wb2 is opened by using the Workbooks.Open method and then mailed, closed, and finally deleted. It is also possible to perform these operations on the file without first opening it. However, by opening the file, you can add code to perform other operations such as the following statement which inserts text and a date into cell A1. You can also perform other operations such as deleting a worksheet or range in the workbook before sending it.

wb2.Worksheets(1).Range("A1").Value = "Copy created on " & Format(Date, "dd-mmm-yyyy")

wb2.Save

Early Binding

If you want to use IntelliSense help show you the properties and methods of objects as you type them into the VBA Code Editor, you can use early binding. For more information about early binding, see the Word MVP site.

To add early binding, follow these steps:

  1. First, add a reference to the Outlook Object Library. Open the VBA editor by typing Alt +F11.

  2. On the Tools menu, click References.

  3. Select Outlook xx Object Library where xx is the version number such as the Microsoft Outlook 12.0 Object Library.

  4. Next, replace the following three statements in the code:

    Dim OutApp As Object
    Dim OutMail As Object
    Set OutMail = OutApp.CreateItem(0)
    

    With these three statements.

    Dim OutApp As Outlook.Application
    Dim OutMail As Outlook.MailItem
    Set OutMail = OutApp.CreateItem(olMailItem)
    

Mailing Single Sheets as Attachments

The following subroutine sends a newly created workbook with just a single sheet as the ActiveSheet object. The procedure saves the workbook before mailing with a date-time stamp. After the file is sent, the workbook is deleted from the hard disk. Change the mail address and subject in the macro before you run the procedure.

Note

For additional information about how to work with different versions of Excel, see the section following this code block.

Sub Mail_ActiveSheet()
' Works in Excel 2000, Excel 2002, Excel 2003, Excel 2007, Excel 2010, Outlook 2000, Outlook 2002, Outlook 2003, Outlook 2007, Outlook 2010
    Dim FileExtStr As String
    Dim FileFormatNum As Long
    Dim Sourcewb As Workbook
    Dim Destwb As Workbook
    Dim TempFilePath As String
    Dim TempFileName As String
    Dim OutApp As Object
    Dim OutMail As Object

    With Application
        .ScreenUpdating = False
        .EnableEvents = False
    End With

    Set Sourcewb = ActiveWorkbook

    ' Next, copy the sheet to a new workbook.
    ' You can also use the following line, instead of using the ActiveSheet object, 
   ' if you know the name of the sheet you want to mail : 
    ' Sheets("Sheet5").Copy 
    ActiveSheet.Copy
    Set Destwb = ActiveWorkbook

    ' Determine the Excel version, and file extension and format.
    With Destwb
        If Val(Application.Version) < 12 Then
            ' For Excel 2000-2003
            FileExtStr = ".xls": FileFormatNum = -4143
        Else
            ' For Excel 2007-2010, exit the subroutine if you answer 
            ' NO in the security dialog that is displayed when you copy
            ' a sheet from an .xlsm file with macros disabled.
            If Sourcewb.Name = .Name Then
                With Application
                    .ScreenUpdating = True
                    .EnableEvents = True
                End With
                MsgBox "You answered NO in the security dialog."
                Exit Sub
            Else
                Select Case Sourcewb.FileFormat
                Case 51: FileExtStr = ".xlsx": FileFormatNum = 51
                Case 52:
                    If .HasVBProject Then
                        FileExtStr = ".xlsm": FileFormatNum = 52
                    Else
                        FileExtStr = ".xlsx": FileFormatNum = 51
                    End If
                Case 56: FileExtStr = ".xls": FileFormatNum = 56
                Case Else: FileExtStr = ".xlsb": FileFormatNum = 50
                End Select
            End If
        End If
    End With

    ' You can use the following statements to change all cells in the 
   ' worksheet to values.
    '    With Destwb.Sheets(1).UsedRange
    '        .Cells.Copy
    '        .Cells.PasteSpecial xlPasteValues
    '        .Cells(1).Select
    '    End With
    '    Application.CutCopyMode = False

    ' Save the new workbook, mail, and then delete it.
    TempFilePath = Environ$("temp") & "\"
    TempFileName = "Part of " & Sourcewb.Name & " " _
                 & Format(Now, "dd-mmm-yy h-mm-ss")

    Set OutApp = CreateObject("Outlook.Application")
    
    Set OutMail = OutApp.CreateItem(0)

    With Destwb
        .SaveAs TempFilePath & TempFileName & FileExtStr, _
                FileFormat:=FileFormatNum
        On Error Resume Next
       ' Change the mail address and subject in the macro before 
       ' running the procedure.
        With OutMail
            .To = "ron@debruin.nl"
            .CC = ""
            .BCC = ""
            .Subject = "This is the Subject line"
            .Body = "Hello World!"
            .Attachments.Add Destwb.FullName
            ' You can add other files by uncommenting the following statement.
            '.Attachments.Add ("C:\test.txt")
            ' In place of the following statement, you can use ".Display" to
            ' display the mail.
            .Send   
        End With
        On Error GoTo 0
        .Close SaveChanges:=False
    End With

    ' Delete the file after sending.
    Kill TempFilePath & TempFileName & FileExtStr

    Set OutMail = Nothing
    Set OutApp = Nothing

    With Application
        .ScreenUpdating = True
        .EnableEvents = True
    End With
End Sub

Note

You can also use the following statement if you know the sheet you want to mail. It does not have to be the active sheet. Sheets("Sheet5").Copy

Additional Information

In the macro, you see that if Val(Application.Version) < 12 is true, the next statement is as follows: FileExtStr = ".xls": FileFormatNum = -4143. This value represents the workbook format for Excel versions 97 through 2003.

However, if you run the code in Excel 2007 or Excel 2010, the code will look at the file format of the parent workbook and save the new file in that format.

If the parent workbook is a macro-enabled file (.xlsm) and there is no code in the new workbook, the new file will be saved as a macro-free file (. xlsx). This way, the e-mail recipient can recognize that this is a macro-free file. If the parent workbook is not an .xlsx, .xlsm, or .xls file, the new workbook will be saved as an Excel binary file (.xlsb).

The following are the main formats in Excel 2007 and Excel 2010:

  • 51 = xlOpenXMLWorkbook (macro-free file . xlsx)

  • 52 = xlOpenXMLWorkbookMacroEnabled (macro-enabled file . xlsm)

  • 50 = xlExcel12 (Excel binary workbook with or without macros .xlsb)

  • 56 = xlExcel8 (Excel version 97 through 2003 format file .xls)

If you always want to save in a specific format, you can replace the following statements in the macro.

Select Case Sourcewb.FileFormat
   Case 51: FileExtStr = ".xlsx": FileFormatNum = 51
   Case 52:
      If .HasVBProject Then
         FileExtStr = ".xlsm": FileFormatNum = 52
      Else
         FileExtStr = ".xlsx": FileFormatNum = 51
      End If
   Case 56: FileExtStr = ".xls": FileFormatNum = 56
   Case Else: FileExtStr = ".xlsb": FileFormatNum = 50
End Select

With one of these statements.

FileExtStr = ".xlsb": FileFormatNum = 50 
FileExtStr = ".xlsx": FileFormatNum = 51
FileExtStr = ".xlsm": FileFormatNum = 52
FileExtStr = ".xls": FileFormatNum = 56

In addition to saving the workbook in an Excel file format, you can also save the single-sheet workbook to one of the following formats:

  • Comma separated value file (.csv)

  • Text file (.txt)

  • Printable file (.prn.)

You should use one of the following statements, respectively.

FileExtStr = ".csv": FileFormatNum = 6
FileExtStr = ".txt": FileFormatNum = -4158
FileExtStr = ".prn": FileFormatNum = 36

If you want to use IntelliSense help show you the properties and methods of objects as you type them into the VBA Code Editor, you can use early binding. See the previous section for more information about early binding.

To use early binding in this procedure, replace these three statements in the code.

Dim OutApp As Object
Dim OutMail As Object
Set OutMail = OutApp.CreateItem(0)

With these three statements.

Dim OutApp As Outlook.Application
Dim OutMail As Outlook.MailItem

Set OutMail = OutApp.CreateItem(olMailItem)

Conclusion

In the second part of this article, you will see the procedures for additional ways to send mail from Excel to Outlook. To continue, read OfficeTalk: Using the Excel Object Model to Send Workbooks and Ranges through E-Mail with Outlook (Part 2 of 2)

About the Authors

MVP   Ron de Bruin is an Excel Most Valuable Professional (MVP) and a frequent contributor to the newsgroups. For more information, see Ron's Excel page.

Frank Rice is a senior programming writer and frequent contributor to the Microsoft Office Developer Center.