hanif.codes

How to send an email from Excel (VBA and Outlook) automatically

Learn how to automate sending emails directly from Excel using VBA and Outlook. This step-by-step guide walks you through writing a simple macro that sends an email with just a few lines of code. Ideal for streamlining tasks, this VBA code is perfect for those who need to send routine emails quickly and efficiently.

VBA Code:

Sub Send_Email()

        ' Re-written by hanif.codes/vba/email.html
        ' Original code by Ron de Bruin
        ' Include the function RangetoHTML directly below.
        ' Working in Excel from 2000 to Office 365
    
        Dim OutApp As Object
        Dim OutMail As Object
    
        On Error Resume Next
    
        ' Define the worksheet name here (for the workbook the code is in)
        Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
    
        ' Define the address of the cells to send here
        Dim rng As Range: Set rng = ws.Range("A1:A10")
        Set rng = rng.SpecialCells(xlCellTypeVisible)
    
        On Error GoTo 0
    
        If rng Is Nothing Then
            MsgBox "The selection is not a range or the sheet is protected." & vbNewLine & vbNewLine & _
                    "Please correct and try again.", vbOKOnly + vbExclamation
            Exit Sub
        End If
    
        With Application
            .EnableEvents = False
            .ScreenUpdating = False
        End With
    
        Set OutApp = CreateObject("Outlook.Application")
        Set OutMail = OutApp.CreateItem(0)
    
        On Error Resume Next
        With OutMail
            
            .To = "vba-email@hanif.codes"
            .CC = ""            ' Comment out to disable
            .BCC = ""           ' Comment out to disable
            .Subject = "Subject here"
                    
            .HTMLBody = RangetoHTML(rng)
            
            '#######################################
            ' Code placeholder 1, delete if not used
            '#######################################
                    
            .Display
            '.Send      ' Enable only when ready
        End With
        On Error GoTo 0
    
        With Application
            .EnableEvents = True
            .ScreenUpdating = True
        End With
    
        Set OutMail = Nothing
        Set OutApp = Nothing
    
    End Sub
    
    Function RangetoHTML(rng As Range)
    
        ' Re-written by hanif.codes/vba/email.html
        ' Changed by Ron de Bruin 28-Oct-2006
        ' Working in Office 2000 to Office 365
        
        Dim fso As Object
        Dim ts As Object
        Dim TempFile As String
        Dim TempWB As Workbook
    
        TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy_h-mm-ss") & ".htm"
    
        ' Copy the range into a separate workbook
        rng.Copy
        Set TempWB = Workbooks.Add(1)
        With TempWB.Sheets(1)
            .Cells(1).PasteSpecial Paste:=8
            .Cells(1).PasteSpecial xlPasteValues, , False, False
            .Cells(1).PasteSpecial xlPasteFormats, , False, False
            .Cells(1).Select
            Application.CutCopyMode = False
            On Error Resume Next
            .DrawingObjects.Visible = True
            .DrawingObjects.Delete
            On Error GoTo 0
        End With
    
        ' Save it as an HTML file
        With TempWB.PublishObjects.Add( _
             SourceType:=xlSourceRange, _
             Filename:=TempFile, _
             Sheet:=TempWB.Sheets(1).Name, _
             Source:=TempWB.Sheets(1).UsedRange.Address, _
             HtmlType:=xlHtmlStatic)
            .Publish (True)
        End With
    
        ' Read the contents of the HTML
        Set fso = CreateObject("Scripting.FileSystemObject")
        Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
        RangetoHTML = ts.readall
        ts.Close
        
        ' Send back
        RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
                              "align=left x:publishsource=")
    
        ' Clean up
        TempWB.Close savechanges:=False
        Kill TempFile
    
        Set ts = Nothing
        Set fso = Nothing
        Set TempWB = Nothing
    
    End Function