How to create emails from Excel table? - excel

I have a table in Excel. It is built as follows:
|Information on food|
|date: April 28th, 2021|
|Person|Email|Apples|Bananas|Bread|
|------|-----|------|-------|-----|
|Person_A|person_A#mailme.com|3|8|9|
|Person_B|person_B#mailme.com|10|59|11|
|Person _C|person_C#maime.com|98|12|20|
There is also a date field in the table. For a test, this could be set to todays date.
Based on this information, I am looking for a VBA code which prepares an email to each of the listed persons and is telling them what they have eaten on the specific date.
I need to access several fields in the table, and at the same time loop through the email addresses. Then I would like VBA to open Outlook and prepare the emails. Ideally not send them so I can take a final look before I send the mails.
It would be fine to access certain cells specifically via ranges etc. I am using Excel/Outlook 2016.
How can this be achieved in VBA?

Assuming the data is a named table and title/date are above the corner of the table as shown in your example. Also all the rows of the table have valid data. The emails are prepared and shown but not sent (unless you change the code where shown).
Option Explicit
Sub EmailMenu()
Const TBL_NAME = "Table1"
Const CSS = "body{font:12px Verdana};h1{font:14px Verdana Bold};"
Dim emails As Object, k
Set emails = CreateObject("Scripting.Dictionary")
Dim ws As Worksheet, rng As Range
Dim sName As String, sAddress As String
Dim r As Long, c As Integer, s As String, msg As String
Dim sTitle As String, sDate As String
Set ws = ThisWorkbook.Sheets("Sheet1")
Set rng = ws.ListObjects(TBL_NAME).Range
sTitle = rng.Cells(-1, 1)
sDate = rng.Cells(0, 1)
' prepare emails
For r = 2 To rng.Rows.Count
sName = rng.Cells(r, 1)
sAddress = rng.Cells(r, 2)
If InStr(sAddress, "#") = 0 Then
MsgBox "Invalid Email: '" & sAddress & "'", vbCritical, "Error Row " & r
Exit Sub
End If
s = "<style>" & CSS & "</style><h1>" & sDate & "<br>" & sName & "</h1>"
s = s & "<table border=""1"" cellspacing=""0"" cellpadding=""5"">" & _
"<tr bgcolor=""#ddddff""><th>Item</th><th>Qu.</th></tr>"
For c = 3 To rng.Columns.Count
s = s & "<tr><td>" & rng.Cells(1, c) & _
"</td><td>" & rng.Cells(r, c) & _
"</td></tr>" & vbCrLf
Next
s = s & "</table>"
' add to dictonary
emails.Add sAddress, Array(sName, sDate, s)
Next
' confirm
msg = "Do you want to send " & emails.Count & " emails ?"
If MsgBox(msg, vbYesNo) = vbNo Then Exit Sub
' send emails
Dim oApp As Object, oMail As Object, ar
Set oApp = CreateObject("Outlook.Application")
For Each k In emails.keys
ar = emails(k)
Set oMail = oApp.CreateItem(0)
With oMail
.To = CStr(k)
'.CC = "email#test.com"
.Subject = sTitle
.HTMLBody = ar(2)
.display ' or .send
End With
Next
oApp.Quit
End Sub

Related

How to loop through list, find data and send in HTML email?

I have the following list with one, or multiple entries for a specific ID.
I have a second list with with unique IDs and email addresses.
I need to loop through the list, send an email to every ID and list data from each matching row in the email, also mentioning the total amount.
Example of the email sent to ID 1234 foo#bar.com:
What I have so far:
Sub SendEmail()
Dim strbody1 As String
Dim strbody2 As String
Dim Signature As String
Dim i As Integer, Mail_Object, Email_Subject, o As Variant, lr As Long
lr = Cells(Rows.Count, "A").End(xlUp).Row
strbody1 = "Hi,<br><br>" & _
"Test.<br><br>"
strbody2 = "Test1.<br><br>" & _
"Foobar,"
Signature = "<H4><B>My Name</B></H4>" & _
"Something<br>" & _
"Something<br>" & _
"T: +1 000 000 000<br>" & _
"foo#bar.com<br>" & _
"www.bar.com"
If MsgBox(("This will send all emails in the list. Do you want to proceed?"), vbYesNo) = vbNo Then Exit Sub
Set Mail_Object = CreateObject("Outlook.Application")
For i = 2 To lr
With Mail_Object.CreateItem(o)
.Subject = Range("B" & i).Value
.SentOnBehalfOfName = "foo#bar.com"
.To = Range("A" & i).Value
.Body = Range("C" & i).Value
.HTMLBody = strbody1 & strbody2 & Signature
.Send 'disable display and enable send to send automatically
End With
Next i
MsgBox "E-mail successfully sent", 64
Application.DisplayAlerts = False
Set Mail_Object = Nothing
End Sub
You can put the IDs into a Dictionary Object. Then scan the data for each ID in turn adding the rows with that ID to an html table. If performance is an issue copy the data to an array first and scan that.
Option Explicit
Sub SendEMail()
Const WS_ID = "Sheet1"
Const WS_DATA = "Sheet2"
Const HEAD = "<head><style>body {font: 20px Verdana;} " & _
" .amount {text-align:right;}</style></head>"
Const TABLE = "<table cellspacing=""0"" cellpadding=""5""" & _
" border=""1"">" & _
"<tr bgcolor=""#EEEEEE""><th>REF</th><th>Amount</th></tr>"
Const TXT = "This is a test email"
Dim wb As Workbook, ws As Worksheet
Dim iLastRow As Long, i As Long
Dim dictID As Object, ID, addr As String
Set dictID = CreateObject("Scripting.Dictionary")
' get list of IDS
Set wb = ThisWorkbook
Set ws = wb.Sheets(WS_ID)
iLastRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To iLastRow
ID = Trim(ws.Cells(i, "A"))
addr = Trim(ws.Cells(i, "B"))
If dictID.exists(ID) Then
MsgBox ID & " is duplicated", vbCritical, "Duplicate ID"
Exit Sub
ElseIf InStr(1, addr, "#") > 0 Then
dictID.Add ID, addr
End If
Next
Dim objOut
Set objOut = CreateObject("Outlook.Application")
' scan data
Dim total As Double, htm As String
Set ws = wb.Sheets(WS_DATA)
iLastRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
For Each ID In dictID
total = 0
addr = dictID(ID)
' build html table
htm = "<html>" & HEAD & "<body><p>" & TXT & "</p>" & TABLE
For i = 2 To iLastRow
If ws.Cells(i, "A") = CStr(ID) Then
htm = htm & "<tr><td>" & ws.Cells(i, "B") & _
"</td><td class=""amount"">" & ws.Cells(i, "C") & "</td></tr>" & vbCrLf
total = total + ws.Cells(i, "C")
End If
Next
total = Format(total, "#,##0")
htm = htm & "<tr bgcolor=""#CCFFCC"" style=""font-weight:bold""><td>TOTAL</td>" & _
"<td class=""amount"">" & total & "</td></tr></table><br/>" & _
"<p>The total amount is " & total & "</p></body></html>"
' send email
Call SendOneEMail(objOut, CStr(ID), addr, htm)
Next
MsgBox dictID.Count & " emails sent", vbInformation
End Sub
Sub SendOneEMail(objOut, sID As String, sTo As String, htm As String)
' create email
With objOut.CreateItem(0) 'olMailItem
.Subject = sID
.SentOnBehalfOfName = "foo#bar.com"
.To = sTo
.HTMLBody = htm
.Display
'.Send 'disable display and enable send to send automatically
End With
End Sub

Create email with contents in order: Text, Image, Text, Image, Text, Signature

I am working in Excel. I want to draft an email in a specific format.
I can't find anything where an email is in this format:
Words
Image
Words
Image
Words
Signature
I found ones that are words, image, image and signature which I used to build mine.
This is how it appears:
This is how it should look:
I left all I tried as commented out sections.
Sub EmailGenerate()
Dim objOutApp As Object, objOutMail As Object
Dim strBody As String, strSig As String, strEnd As String, strBody2 As String
Dim rng As Range, rng2 As Range
Dim r As Long, r2 As Long
Dim wdDoc As Word.Document
Dim Selection As Word.Selection
Dim Selection2 As Word.Selection
r = shEmail.Cells(Rows.Count, 15).End(xlUp).Row
Set rng = shEmail.Range("K1:" & Cells(r, 21).Address)
r2 = shEmail.Cells(Rows.Count, 23).End(xlUp).Row
Set rng2 = shEmail.Range("W1:" & Cells(r2, 29).Address)
Set objOutApp = CreateObject("Outlook.Application")
Set objOutMail = objOutApp.CreateItem(0)
Set wdDoc = objOutMail.GetInspector.WordEditor
With objOutMail
'If sent on behalf of another email address
' .SentOnBehalfOfName = ""
'Setting the email conditions
.To = shEmail.Cells(1, 2).Value
.CC = shEmail.Cells(2, 2).Value
.BCC = ""
'Checks all email names
.Recipients.ResolveAll
.Subject = shEmail.Cells(4, 2).Value
'This must be visible to get the default signature
.Display
'Get the html code from the signature
strSig = .htmlbody
'This is what the email body should say
' rng.Copy
' wdDoc.Application.Selection.Start = Len(strBody)
' wdDoc.Application.Selection.End = wdDoc.Application.Selection.Start
' wdDoc.Application.Selection.PasteAndFormat (wdChartPicture)
' wdDoc.Content.InsertParagraphAfter
' rng2.Copy
' wdDoc.Application.Selection.Start = Len(strBody) + Len(strBody2)
' wdDoc.Application.Selection.End = wdDoc.Application.Selection.Start
' wdDoc.Application.Selection.PasteAndFormat (wdChartPicture)
' rng1.Copy
' wdDoc.Paragraphs(2).Range.PasteSpecial , , , , wdPasteBitmap
rng.Copy
wdDoc.Content.InsertParagraphBefore
wdDoc.Paragraphs(2).Range.PasteSpecial , , , , wdPasteBitmap
wdDoc.Content.InsertParagraphAfter
strBody = "<Body style=font-size:11pt;font-family:Calibri>" & _
shEmail.Cells(5, 2).Value & "</p>" & _
"<p>" & "</p>" & _
"<p>" & shEmail.Cells(6, 2).Value & "</p>" & _
"<p>" & shEmail.Cells(7, 2).Value & "</p>" & _
"<p>" & "</p>" & _
"<p>" & shEmail.Cells(8, 2).Value & "</p>"
strBody2 = "<Body style=font-size:11pt;font-family:Calibri>" & _
shEmail.Cells(10, 2).Value & "</p>" & _
"<p>" & "</p>"
rng2.Copy
wdDoc.Content.InsertParagraphBefore
wdDoc.Paragraphs(1).Range.PasteSpecial , , , , wdPasteBitmap
wdDoc.Content.InsertParagraphAfter
objOutMail.htmlbody = strBody2 & _
.htmlbody
' rng2.Copy
' wdDoc.Application.Selection.Start = Len(strBody) + Len(strBody2)
' wdDoc.Application.Selection.End = wdDoc.Application.Selection.Start
' wdDoc.Application.Selection.PasteAndFormat (wdChartPicture)
'Combines the email with image and the signature
objOutMail.htmlbody = strBody & _
.htmlbody
'Automatically sends the email, should pop up briefly.
'.Send
End With
On Error GoTo 0
Set objOutMail = Nothing
Set objOutApp = Nothing
End Sub
rng is the larger table and rng2 is the smaller table.
.Cells(5,2) through to (8,2) go before rng and (10,2) goes after rng and before rng2 then (12,2) would go after rng2 and before the signature.
Please, try the next approach. It is difficult to mix WordEditor with html, at least, I did not do it an I do not know how/if it can be done. Everything (I understood) you need can be done using WordEditor object or html using PropertyAccessor and link to picture paths. I am using in your adapted code only WordEditor:
Sub EmailGenerate()
Dim objOutApp As Object, objOutMail As Object
Dim rng As Range, rng2 As Range, shEmail As Worksheet
Dim r As Long, r2 As Long
Dim wdDoc As Word.document, wdRange As Word.Range
Set shEmail = ActiveSheet 'use here your necessary sheet
r = shEmail.cells(Rows.count, 15).End(xlUp).row
Set rng = shEmail.Range("K1:" & cells(r, 21).Address)
r2 = shEmail.cells(Rows.count, 23).End(xlUp).row
Set rng2 = shEmail.Range("W1:" & cells(r2, 29).Address)
Set objOutApp = CreateObject("Outlook.Application")
Set objOutMail = objOutApp.CreateItem(0)
Set wdDoc = objOutMail.GetInspector.WordEditor
With objOutMail
'If sent on behalf of another email address
'.SentOnBehalfOfName = ""
'Setting the email conditions
.To = shEmail.cells(1, 2).Value
.cc = shEmail.cells(2, 2).Value
.BCC = ""
'Checks all email names
.Recipients.ResolveAll
.subject = shEmail.cells(4, 2).Value
'This must be visible to get the default signature
.display 'Please, look here if its appearance is what you need.
'Declare the string variables to be used:
Dim strFrst As String, strSec As String, strThird As String, strF As String
'Give values to the strings (they can take the values from the sheet...)
strFrst = "Hello All!" & vbCrLf & vbCrLf
strSec = "Please, receive the picture you requested:" & vbCrLf & vbCrLf
strThird = "And the second picture is following:" & vbCrLf & vbCrLf
strF = "The last necessary string is here..." & vbCrLf
'Write the first two text lines:________________
wdDoc.Paragraphs(1).Range.InsertAfter (strFrst)
wdDoc.Paragraphs(2).Range.InsertAfter (vbCrLf) 'insert an empty line
wdDoc.Paragraphs(3).Range.InsertAfter (strSec)
'_______________________________________________
'Embed the first picture__________________________________________
rng.Copy
wdDoc.Paragraphs(5).Range.PasteSpecial , , , , wdPasteBitmap
'_________________________________________________________________
wdDoc.Paragraphs(5).Range.InsertAfter (vbCrLf) 'empty line after first picture
'insert the third string:_______________________
wdDoc.Paragraphs(6).Range.InsertAfter (strThird)
'_______________________________________________
'Embed the second picture___________________________________
rng2.Copy
wdDoc.Paragraphs(8).Range.PasteSpecial , , , , wdPasteBitmap
'___________________________________________________________
'insert the fourth string:__________________
wdDoc.Paragraphs(8).Range.InsertAfter (strF)
'___________________________________________
'Automatically sends the email, should pop up briefly.
'.Send
End With
End Sub
Please, test it and send some feedback.

How to keep the hyperlinks, in table column, clickable when sending to body of mail?

I am trying to send an email via Outlook using VBA.
I have a column filled with hyperlinks. When the email is constructed, the hyperlinks turns into plain text and are not clickable.
I reference the column using Cells(row_num,1) because all the hyperlinks are unique.
How to make them show up as hyperlinks?
Sub SendEmail()
Dim olook As Outlook.Application
Dim omailitem As Outlook.MailItem
Dim i As Byte, row_num As Byte
row_num = 2
Set olook = New Outlook.Application
For i = 1 To 15
Set omailitem = olook.CreateItem(0)
With omailitem
.To = Sheets(1).Cells(row_num, 2)
.Subject = "Tool Notification"
.Body = "Hello!" & vbNewLine & vbNewLine & _
"Below are the link(s) to the task(s) that you have due on: " & _
Cells(row_num, 4).Value & _
vbNewLine & vbNewLine & "Link: " & Cells(row_num, 1).Value & _
vbNewLine & vbNewLine & "Thank you," & _
vbNewLine & vbNewLine & "Tool"
.Display
End With
row_num = row_num + 1
Next
End Sub
Sample Data
https://i.stack.imgur.com/m9Stx.png
Check the code's comments and adjust it to fit your needs.
This should be pasted in a standard module.
EDIT: Adjusted to accumulate links by sender
Code:
Option Explicit
Sub SendEmail()
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim targetSheet As Worksheet
Dim targetRange As Range
Dim cell As Range
Dim lastRow As Long
Dim recipientAddr As String
Dim bodyContent As String
Dim duedateFormat As String
Dim linkFormat As String
' Set reference to target Sheet (replace 1 with the sheet's name or codename)
Set targetSheet = ThisWorkbook.Worksheets(1)
' Find last cell in column b
lastRow = targetSheet.Cells(targetSheet.Rows.Count, 2).End(xlUp).Row
' Set target range
Set targetRange = targetSheet.Range("B2:B" & lastRow)
' Start new outlook instance
Set olApp = New Outlook.Application
' Loop through each cell in column B
For Each cell In targetRange.Cells
' If cell has data
If cell.Value <> vbNullString Then
' Check if is the same recipient as next
If cell.Value = cell.Offset(1, 0).Value Then
linkFormat = linkFormat & "" & cell.Offset(0, -1) & "<br>"
Else
linkFormat = linkFormat & "" & cell.Offset(0, -1) & ""
' Collect email data from cells
recipientAddr = cell.Value
duedateFormat = Format(cell.Offset(0, 2).Value, "mm-dd-yyyy")
' Build the link string
bodyContent = "Hello!<br><br>" & _
"Below are the link(s) to the task(s) that you have due on: " & duedateFormat & "<br><br>" & _
"Link(s): <br>" & _
linkFormat & "<br><br>" & _
"Thank you,<br><br>" & _
"Tool"
' Create the mail item and display it
Set olMail = olApp.CreateItem(olMailItem)
With olMail
.To = cell.Value
.Subject = "Tool Notification"
.HTMLBody = bodyContent
.Display
End With
' Reset the link
linkFormat = vbNullString
End If
End If
Next cell
End Sub
Let me know if it works

Reading cell value

So I have created a macro which is sending an email via outlook. I am stuck at some point. I need to include new cell values and corresponding cell values on top of the column in the body of an email. So basically I need my macro to read those two values.
This is my module:
Sub SendEmail()
Dim olApp As Outlook.Application
Set olApp = CreateObject("Outlook.Application")
Dim olMail As Outlook.MailItem
Set olMail = olApp.CreateItem(olMailItem)
'So I want to send an email with cell new value and top of the column
'value corresponding to that cell
'Example: I wanna change cell C3 from A to X and I want to include
'that change in body of my email automatically
'So it reads "New cell value is X on 3-06"
olMail.To = "*****#*****.com"
olMail.Subject = "Look what has been changed"
olMail.Body = "Hi" & vbNewLine & vbNewLine & _
"New cell value is <Here is new cell value> on <Top of the column
of that cell value> " & vbNewLine & vbNewLine & _
"BR"
olMail.Send
End Sub
And this is my macro:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("A3:AP3")) Is Nothing Then SendEmail
End Sub
And this is a part of the worksheet I am working on:
One of the problems you are facing is that the Target can be multiple cells and one Worksheet_Change change can be over multiple cells at the same time, not just once cell. You could check if the Target is one cell size, and do nothing if more than 1, 1 size, but then you would loose that change or parts of it at least.
An approach would be to hold a history of the changes, and send that email even if the changes are over multiple cells at once.
With that in mind, you should create an additional sheet that holds last changes, say sheet History Sheet.
In the sheet your working on, place in the code part of the sheet:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("A3:AP3")) Is Nothing Then
checkHistory Target.Worksheet.Range("A3:AP3")
End If
End Sub
In any module in the same workbook, add this:
Sub checkHistory(rng As Range)
Dim wsHistory As Worksheet: Set wsHistory = ThisWorkbook.Sheets("History Sheet")
Dim arrData As Variant, arrHistory As Variant
Dim R As Long, C As Long
Dim bChanges As Boolean
arrData = rng.Offset(-2).Resize(3)
arrHistory = wsHistory.Range(rng.Offset(-2).Resize(3).Address)
Dim arrChanges() As String: ReDim arrChanges(LBound(arrData) To UBound(arrData), LBound(arrData, 2) To UBound(arrData, 2))
For C = LBound(arrData, 2) To UBound(arrData, 2)
If arrData(3, C) <> arrHistory(3, C) Then
arrChanges(3, C) = arrData(3, C)
If Not bChanges Then bChanges = True
End If
Next C
If bChanges Then
Dim strNewVal As String, strHeading As String
wsHistory.Range(rng.Offset(-2).Resize(3).Address) = arrData
For C = LBound(arrChanges, 2) To UBound(arrChanges, 2)
If arrChanges(3, C) <> "" Then
strNewVal = strNewVal & ", " & arrChanges(3, C) 'new values
strHeading = strHeading & ", " & arrData(1, C) 'heading
End If
Next C
strNewVal = Right(strNewVal, Len(strNewVal) - 2)
strHeading = Right(strHeading, Len(strHeading) - 2)
SendEmail strNewVal, strHeading
End If
End Sub
Sub SendEmail(strNewVal As String, strHeading As String)
Dim olApp As Outlook.Application
Set olApp = CreateObject("Outlook.Application")
Dim olMail As Outlook.MailItem
Set olMail = olApp.CreateItem(olMailItem)
olMail.To = "*****#*****.com"
olMail.Subject = "Look what has been changed"
olMail.Body = "Hi" & vbNewLine & vbNewLine & _
"New cell value is " & strNewVal & " on " & strHeading & vbNewLine & vbNewLine & _
"BR"
olMail.Send
End Sub
With the above, you would send that email regardless if the change is over 1 cell, or more, as comma separated values.
Some small changes:
Sub SendEmail(rng As Range)
Dim olApp As Outlook.Application, c As Range, bdy
If rng Is Nothing Then Exit Sub '<< nothing to report
Set olApp = CreateObject("Outlook.Application")
Dim olMail As Outlook.MailItem
Set olMail = olApp.CreateItem(olMailItem)
olMail.To = "*****#*****.com"
olMail.Subject = "Look what has been changed"
bdy = "Hi" & vbNewLine & vbNewLine
'check each changed cell
For Each c in rng.Cells
bdy = bdy & "New cell value is '" & c.Value & _
"' on " & c.EntireColumn.Cells(1).Value & _
vbNewLine & vbNewLine
Next c
olMail.Body = bdy & vbNewLine & vbNewLine & "BR"
olMail.Send
End Sub
Event handler:
Private Sub Worksheet_Change(ByVal Target As Range)
SendEmail Application.Intersect(Target, Me.Range("A3:AP3"))
End Sub

Improve process of taking email address from spreadsheet

I have a spreadsheet that I have set up to automatically pdf and email nightly based on email addresses I have listed out on a hidden worksheet. I currently have to dim seperate variable for each address and then specify which cell each variable equals. This works but I feel like there must be a better way to do this. Specifically, I would like to not have to add or delete dim'ed variables if I delete or add additional addresses to the list. Here is the code I am using:
Sub PDF_Email()
Dim OutLookApp As Object
Dim OutLookMailItem As Object
Dim myAttachment As Object
Dim MDir As String
Dim MName As String
Dim Address1 As String
Dim Address2 As String
Dim Address3 As String
Dim Address4 As String
Dim Address5 As String
Dim Address6 As String
Dim Address7 As String
Dim Address8 As String
Dim Address9 As String
Dim Address10 As String
Dim Address11 As String
Set OutLookApp = CreateObject("Outlook.application")
Set OutLookMailItem = OutLookApp.CreateItem(0)
Set myAttachment = OutLookMailItem.Attachments
Address1 = Worksheets("EmailList").Cells(1, 1).Value
Address2 = Worksheets("EmailList").Cells(2, 1).Value
'Prevent Macro from running if different user
Const AllowedName As String = "nbelair"
If Environ("username") <> AllowedName Then
Exit Sub
End If
MName = ActiveSheet.Name & " " & Format(Now() - 1, "dddd, mmmm, d, yyyy")
MDir = ActiveWorkbook.Path
ChDir "Y:\SMHC Management Team\Daily Labor Management\Dashboard\Archived
Dashboards" 'Update to
ActiveWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"Y:\SMHC Management Team\Daily Labor Management\Dashboard\Archived
Dashboards\" & MName & ".pdf", OpenAfterPublish:=True 'Update
With OutLookMailItem
.To = Address1 & ";" & Address2
.Subject = "SMHC Daily Labor Management Dashboard - " & Format(Now() - 1,
"dddd, mmmm, d, yyyy")
.Body = "Attached please find the SMHC Daily Labor Management Dashboard for
" _
& Format(Now() - 1, "dddd, mmmm, d, yyyy") & ". You are receiving this
email because you are currently " _
& "on the distribution list for this report. If you have any questions
" _
& "or concerns regarding this email or report please let me know by
responding to this email or contacting me at 207 467 6983."
myAttachment.Add "Y:\SMHC Management Team\Daily Labor
Management\Dashboard\Archived Dashboards\" & MName & ".pdf"
.Display
.Send
End With
'Clear Outlook Variables
Set OutLookMailItem = Nothing
Set OutLookApp = Nothing
'Quit
ThisWorkbook.Saved = True
Application.Quit
End Sub
Being new to coding, I would greatly appreciate any thoughts or suggestions someone might have. I am quickly falling in love with coding and welcome the chance to learn something new!
Thank You
The first loop builds the string of To:
The second loop builds the string of CC:
Email addresses span column F for To and column G for CC
Dim i As Integer
Dim EmailTo As String
Dim EmailCC As String
For i = 2 To 30
EmailTo = EmailTo & ThisWorkbook.Sheets("Email").Range("F" & i) & ";"
Next i
For i = 2 To 30
EmailCC = EmailCC & ThisWorkbook.Sheets("Email").Range("G" & i) & ";"
Next i
ThisWorkbook.Sheets("Dash").Range("C2:Q63").Select
ThisWorkbook.EnvelopeVisible = True
With ThisWorkbook.Sheets("Dash").MailEnvelope
.Introduction = ""
.Item.To = EmailTo
.Item.CC = EmailCC
.Item.Subject = "Subject " & Date
.Item.Display
End With

Resources