Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

How to Send Group emails

0

Hi,

I have a workbook with data that changes every week, I set up the VBA code to send emails to my sales reps, but now its sending 300 emails.

is there a way to get VBA to send out one Bulk mail per rep?

attached is my workbook

Answer
Discuss

Discussion

Your workbook isn't attached, which is probably just as well. You wouldn't send out "bulk" emails to your reps. "Bulk" is considered in the hunmdreds of thousands and there are online services for that, including free ones. Normal email accounts set a limit, often 100 (depending upon the service provider), of how many copies you can send of one mail. 
But if you have a list of reps and want to send individual emails to them you should start with code by Ron de Bruin. Look for the guy's name on the internet to find his code. Then, if you still have questions, come back here with the result of what you have found and studied.
Variatus (rep: 4889) Nov 16, '20 at 5:34 am
Sub email()
Dim OutApp As Object
Dim OutMail As Object
Dim i, lr As Long
Dim Path, Signature As String
Dim Rng As Range
Dim rng1 As Range

Application.ScreenUpdating = False
    
lr = Sheet1.Cells(Rows.Count, "B").End(xlUp).Row
On Error Resume Next
For i = 2 To Sheet1.Cells(Rows.Count, "K").End(xlUp).Row
    
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)

With OutMail
.Display
End With
Signature = OutMail.HTMLBody
 
If Sheet1.Cells(i, "W").Value = "999" Then
Set rng1 = Range("A1:Y1")
Set Rng = Range("A" & i & ":Y" & i)
With OutMail
.To = Sheet1.Cells(i, "Z").Value
.CC = "juan@effectivesales.co.za"
.Subject = "SOH with No Sales"
.HTMLBody = "Good day, " & Chr(11) & Chr(11) & "Please advise on below 99 lines (SOH No Sales):" & Chr(11) & Chr(11) & RangetoHTML(rng1) & RangetoHTML(Rng) & Chr(11) & Chr(11) & Signature
.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
End If
Next i

With Application
.CutCopyMode = False
.ScreenUpdating = True
End With
End Sub
 
Yolanidvdberg (rep: 4) Nov 16, '20 at 5:58 am
Function RangetoHTML(Rng As Range)
'
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"


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
 
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


Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).openastextstream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _"align=left x:publishsource=")
 
TempWB.Close SaveChanges:=False


Kill TempFile
 
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
Yolanidvdberg (rep: 4) Nov 16, '20 at 6:00 am
Above is the code I used (split in 2 inorder to fit into comment)

I need the email to send one email per rep instead of 10+ emails to each rep

the code works perfect otherwise
Yolanidvdberg (rep: 4) Nov 16, '20 at 6:01 am
Add to Discussion

Answers

1
Selected Answer

Yolandi

As Variatus suggests, please change your question title to refer to Group emails (rather than Bulk).

Further to your code in the discussion, I've modified the workbook you sent last week to:

   1) Have a sheet called "Send Rep email" wth a button to click

   2) Include a sheet "Reps" which is the Contact info but with duplicates removed.

In the macro behind the button in 1 above, I define RepRows as a range then use this basic structure:

For Each rep In Worksheets("Reps").Range("A2:A10")

<< code to match data with rep>>
<< code to send emails>>

Next Rep

In my case in the < <code to match data with rep>>, there's your For Next loop with an If Then decision- this just matches the column A value with the rep's name (from the For Each) and extends the range RepRows if it matches. Once the For Next loop is run, all rows in Report for a given Rep will be in the Range.

In the << code to send emails>>, I've just changed the HTML body to includes HTML conversion of that RepRows range.

You will get a single email per rep with ALL the rows in Report which match the rep's names. I leave you to modify the If decision to limilt that (to your 999 codes say) and tidy unused bits of the code and in the Send Rep emails sheet.

Hope this works. Please Select my answer if it does. Good luck

Private Sub Cb_GrpEmails_Click()

Dim OutApp As Object
Dim OutMail As Object
Dim i, lr As Long
Dim Path, Signature As String
Dim Rng As Range
Dim rng1 As Range
Dim RepRows As Range

On Error Resume Next

Application.ScreenUpdating = False

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

For Each rep In Worksheets("Reps").Range("A2:A10")
MsgBox "Preparing email for " & rep & ": " & rep.Offset(0, 3).Value ' check

    'lr = Sheet1.Cells(Rows.Count, "B").End(xlUp).Row

    Set RepRows = Sheet1.Range("A1:Y1")
    For i = 2 To Sheet1.Cells(Rows.Count, "K").End(xlUp).Row
    If Trim(Sheet1.Cells(i, 1).Value) = rep.Value Then
       'If Sheet1.Cells(i, "W").Value = "999" Then
        'Set rng1 = Range("A1:Y1")
        Set RepRows = Union(RepRows, Sheet1.Range("A" & i & ":Y" & i))
     End If
    Next i

    With OutMail
    .Display
    End With
    Signature = OutMail.HTMLBody


    With OutMail
    .To = rep.Offset(0, 3).Value
    .CC = "juan@effectivesales.co.za"
    .Subject = "SOH with No Sales"
    .HTMLBody = "Good day, " & Chr(11) & Chr(11) & "Please advise on below 999 lines (SOH No Sales):" & Chr(11) & Chr(11) & RangetoHTML(RepRows) 'RangetoHTML(rng1) & RangetoHTML(Rng) & Chr(11) & Chr(11) & Signature
    .Display
    End With

Next rep

Set OutMail = Nothing
Set OutApp = Nothing



With Application
.CutCopyMode = False
 .ScreenUpdating = True
End With
End Sub
Discuss

Discussion

Thank you so much, this is exactly what i needed, thank you 
Yolanidvdberg (rep: 4) Nov 16, '20 at 10:52 am
That's good, thanks
John_Ru (rep: 6142) Nov 16, '20 at 11:00 am
Hi, I am working on the report you sent me, Thanks again for your help on that.
but everytime it creates an email after the first mail it inputs the datat from the first mail as well.
so on Mail 5 you have 4 previous reps datta as well.

how would i fix this?
Yolanidvdberg (rep: 4) Nov 20, '20 at 1:31 am
Yolandi. 
I'll need to check later but are you sending each email as the macro creates it?
John_Ru (rep: 6142) Nov 20, '20 at 2:46 am
Hi Yes I am

No rush, thank you though
Yolanidvdberg (rep: 4) Nov 20, '20 at 5:45 am
Yolandi
I  ran the macro in DISPO REPORT with Grouped email send v0_a.xlsm (from the button) and (for example) it produced an email per rep and  the last draft (to Victor) included only rows for Victor.

Each has DIFFERENT data on it BUT if you don't click send on the email (before the next draft is prepared), all you will see is the latest email (and some of the email addresses are quite similar).

Not sure why it's a problem for you but I suggest you (1) send each email as it's displayed and (2) modify the code in the sub Cb_GrpEmails_Click() to include the change in bold below- this will greet the rep in question:

   
    With OutMail
    .To = Rep.Offset(0, 3).Value
    .CC = "juan@effectivesales.co.za"
    .Subject = "SOH with No Sales"
    .HTMLBody = "Good day " & Rep & "," & Chr(11) & Chr(11) & "Please advise on below 999 lines (SOH No Sales):" & Chr(11) & Chr(11) & RangetoHTML(RepRows) 'RangetoHTML(rng1) & RangetoHTML(Rng) & Chr(11) & Chr(11) & Signature
    .Display
    '.Save
    '.Send
    .Close
    End With
 
Next Rep



John_Ru (rep: 6142) Nov 20, '20 at 6:52 am
hi,

still pulling the same, dont stress though I will just modify the emails 

thank you for all your help though
Yolanidvdberg (rep: 4) Nov 20, '20 at 7:17 am
hi,

is there a reason why when i send one of the mails it takes away the rest without sending or displaying them?
Yolanidvdberg (rep: 4) Nov 20, '20 at 7:23 am
my First problem seems to come in when I add my signiture to the body of the mail
& Chr(11) & Chr(11) & Signature
Yolanidvdberg (rep: 4) Nov 20, '20 at 7:38 am
Sorry but I don't know and I'm too busy at present to investigate. As I recall, you (not me) added the previous lines (before mine) where you set the signature:

    With OutMail
    .Display
    End With
    Signature = OutMail.HTMLBody
John_Ru (rep: 6142) Nov 20, '20 at 8:20 am
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login