Send Multiple Emails Via VBA - excel

I wonder whether someone could help me please.
I'm trying to write a script which send multiple emails to addressees on a spreadsheet, with various other pieces of information.
I've started to use a solution from Ron de Bruin (below).
Sub Email()
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Dim Src As Worksheet
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
Set Src = ThisWorkbook.Sheets("List")
On Error GoTo cleanup
Src.Select
For Each cell In Columns("C").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" Then
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = cell.Value
.Subject = "Splunk Access"
.Body = "Hi " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"I have created an account: Production." & _
vbNewLine & vbNewLine & _
"Your username and password for this environment is:" & _
vbNewLine & vbNewLine & _
"Username: " & Cells(cell.Row, "B").Value & _
vbNewLine & _
"Password: " & Cells(cell.Row, "E").Value & _
vbNewLine & vbNewLine & _
"Please log in at your earliest convenience and change your password to a more secure one. " & _
vbNewLine & vbNewLine & _
"You can do this by clicking on your name on the top menu and select ‘Edit Account’." & _
vbNewLine & vbNewLine & _
"You can use this link to get to the log in page for this environment: " & _
vbNewLine & vbNewLine & _
"PROD: right/en-US/account/logout " & _
vbNewLine & vbNewLine & _
"Many thanks and kind regards"
.send
End With
On Error GoTo 0
Set OutMail = Nothing
End If
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
This script works, but I then receive the 'Outlook' security ,message, which with over 100 recipients, isn't practical to keep pressing "Ok" to send the email.
So following more research I changed:
.send
to
.Display
Application.Wait (Now + TimeValue("0:00:01"))
Application.SendKeys "%"
But the problem I have is that the email is created, but isn't sent. Again not practical to keep pressing "Send" for over 100 users.
I then tried a CDO solution, but I ran into problems with the SMTP address because I'm using my works Microsoft Exchange which I'm not an administrator for, and so don't have any of the SMTP details.
I just wondered whether someone may be able to look a this please, and offer some guidance on how I can create the macro to run automatically.
Many thanks and kind regards
Chris

All,
I managed to get this working with the following:
Sub Email()
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Dim Src As Worksheet
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
Set Src = ThisWorkbook.Sheets("List")
On Error GoTo cleanup
Src.Select
For Each cell In Columns("C").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" Then
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = cell.Value
.Subject = "Access"
.Body = "Hi " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"I have created an account for you" & _
vbNewLine & vbNewLine & _
"Your username and password for this environment is:" & _
vbNewLine & vbNewLine & _
"Username: " & Cells(cell.Row, "B").Value & _
vbNewLine & _
"Password: " & Cells(cell.Row, "E").Value & _
vbNewLine & vbNewLine & _
"Please log in at your earliest convenience and change your password to a more secure one. " & _
vbNewLine & vbNewLine & _
"You can do this by clicking on your name on the top menu and select 'Edit Account'." & _
vbNewLine & vbNewLine & _
"You can use this link to get to the log in page for this environment: " & _
vbNewLine & vbNewLine & _
"PROD: https://right/en-US/account/logout " & _
vbNewLine & vbNewLine & _
"Many thanks and kind regards"
' .send
.Display
Application.Wait (Now + TimeValue("0:00:02"))
Application.SendKeys "%s"
Application.SendKeys "+o"
End With
On Error GoTo 0
Set OutMail = Nothing
End If
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
I found through further testing, that a automatic pop up appeared when the 'Send' button was clicked by this command Application.SendKeys "%s", so I added Application.SendKeys "+o2, to automatically click "OK".
Kind regards
Chris

try
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual
this is of course using .Send
make sure to turn them back on at end of sub

Related

Adding attachment to email

I want to create a button that saves a worksheet in pdf format, Attaches to a new mail and send it.
i can create the pdf, save the pdf on my desktop, create and e-mail. but the PDF is never attached. Where am I going wrong?
Dim pdfName As String
pdfName = PONumberLabel.Caption ' add PO number on label to a variable
' create pdf and save to desktop
ChDir "C:\Users\roanderson\Desktop" ' selects directory to save
Sheet4.ExportAsFixedFormat _
Type:=xlTypePDF, _
OpenAfterPublish:=True, _
Quality:=xlQualityStandard, _
Filename:="C:\Users\roanderson\Desktop\" & pdfName ' directory put t
' sending email for approval
Dim xOutApp As Object
Dim xOutMail As Object
Dim xMailBody As String
On Error Resume Next
Set xOutApp = CreateObject("Outlook.Application")
Set xOutMail = xOutApp.CreateItem(0)
xMailBody = "Please approve PO Number" & " " & PONumber & vbNewLine & vbNewLine & _
"Cost Centre:" & " " & costcentre & vbNewLine & _
"Description:" & " " & description & vbNewLine & _
"Currency:" & " " & POCurrency & vbNewLine & _
" Total:" & " " & total
On Error Resume Next
With xOutMail
.To = "Ross.anderson#work.com"
.CC = ""
.BCC = ""
.Subject = "PO Number " & PONumber & " " & "Approval"
.Body = xMailBody
.Display 'or use .Send
.Attachments.Add "C:\Users\roanderson\Desktop\" & pdfName
.VotingOptions = "Accept;Reject"
End With
On Error GoTo 0
Set xOutMail = Nothing
Set xOutApp = Nothing
Everything works except attaching pdf to email.
Change the Statement
.Attachments.Add "C:\Users\roanderson\Desktop\" & pdfName
To
.Attachments.Add "C:\Users\roanderson\Desktop\" & pdfName & ".pdf"
As it seems like pdfname does not have the full name with Extension.

Trying to generate email from data in Excel spreadsheet, getting compile error "User defined type not defined"

I'm trying to generate an email from data input on to a spreadsheet, to create an offer of work. But when I do, I keep getting the same error: Compile error, user-defined type not defined
I've gone into "Tools" > References and ticked the "Microsoft Outlook 16.0 Object Library" checkbox, but I get the same error. When I'm trying to search for other answers on this subject, this seems to be the solution for most.
Option Explicit
Private Sub Generate_offer()
Dim strFile As String
Dim OutApp As Outlook.Application
Dim objOutlookMsg As Outlook.MailItem
Set OutApp = CreateObject("Outlook.Application")
Set objOutlookMsg = OutApp.CreateItem(olMailItem)
With objOutlookMsg
.SentOnBehalfOfName = ""
.To = ""
.Subject = "xxxxxxxx"
.Body = "Dear " & vbNewLine & vbNewLine & "xxxxxxxx" & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "C").Value & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "J").Value & " - " & Cells(ActiveCell.Row, "K").Value & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "M").Value & "xxxxxxxx" & vbNewLine _
& "Notes: " & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine & vbNewLine & "xxxxxxxx"
.display
End With
'objOutlookMsg.Send
Set OutApp = Nothing
End Sub
Any help much appreciated.
Your code is using 'Early Binding'.. where in order to use Dim Something As Outlook.Something, Excel needs to have the Outlook Library referenced.
You have two options.
You can rectify this by either
Adding the reference -
In the VB Editor window, ensuring the code execution is halted entirely, go to Tools > References and tick Microsoft Outlook x.x Object Library (x.x will depend on the version you have installed).
Or use late binding - which keeps the declarations open (as objects) that get bound as you use them:
Option Explicit
Private Sub Generate_offer()
Dim strFile As String
Dim OutApp As Object
Dim objOutlookMsg As Object
Dim olMailItem As Long
olMailItem = 0 ' (0 = Mail item, 1 = Appointment, 2 = Contact etc..)
Set OutApp = CreateObject("Outlook.Application")
Set objOutlookMsg = OutApp.CreateItem(olMailItem)
With objOutlookMsg
.SentOnBehalfOfName = ""
.To = ""
.Subject = "xxxxxxxx"
.Body = "Dear " & vbNewLine & vbNewLine & "xxxxxxxx" & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "C").Value & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "J").Value & " - " & Cells(ActiveCell.Row, "K").Value & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "M").Value & "xxxxxxxx" & vbNewLine _
& "Notes: " & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine & vbNewLine & "xxxxxxxx"
.display
End With
'objOutlookMsg.Send
Set OutApp = Nothing
End Sub
Note - the main reason I'd use Late Binding would be if the macro is going to be used on multiple machines with different Excel versions installed. If Early Binding is used and the reference is pointing at a specific version that isn't installed, you'll get an error. Late Binding will find any version that provides Outlook.
I get no errors when changing your Dim to Objects
Option Explicit
Private Sub Generate_offer()
Dim strFile As String
Dim OutApp As Object
Dim objOutlookMsg As Object
Set OutApp = CreateObject("Outlook.Application")
Set objOutlookMsg = OutApp.CreateItem(0)
With objOutlookMsg
.SentOnBehalfOfName = ""
.To = ""
.Subject = "xxxxxxxx"
.Body = "Dear " & vbNewLine & vbNewLine & "xxxxxxxx" & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "C").Value & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "J").Value & " - " & Cells(ActiveCell.Row, "K").Value & vbNewLine _
& "xxxxxxxx" & Cells(ActiveCell.Row, "M").Value & "xxxxxxxx" & vbNewLine _
& "Notes: " & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine & vbNewLine _
& "xxxxxxxx" & vbNewLine & vbNewLine & "xxxxxxxx"
.display
End With
'objOutlookMsg.Send
Set OutApp = Nothing
End Sub

How can I call a cell value within a string?

I'm trying to set up a macro to send an email, updating people on a due date timeline. This email should pull dates from specific cells and place them into the message body. So far I'm able to set up the email to read the way I want, but am having trouble calling the dates.
I'm super new at vba and this may not be a function that's possible, but any workarounds would be appreciated! Thanks!
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Dim rev_1 As Date, rev_2 As Date, final_due As Date
rev_1 = Range(I2)
rev_2 = Range(K2)
final_due = Range(M2)
strbody = "XXXXXXX" & vbNewLine & vbNewLine & _
"This is an update on your project dates:" & vbNewLine & vbNewLine & _
"Review 1 Suspense: CALL CELL I2 HERE" & vbNewLine & _
"Review 2 Suspense: CALL CELL K2 HERE" & vbNewLine & _
"Final Due Date: CALL CELL M2 HERE" & vbNewLine & vbNewLine & _
"Acoording to this timeline, you are AHEAD/ON TIME/BEHIND." & vbNewLine & vbNewLine & _
"If you have any questions, please contact XXXX." & vbNewLine & vbNewLine & _
On Error Resume Next
With OutMail
.To = ""
.CC = ""
.BCC = ""
.Subject = "Upcoming Project - Timeline Update"
.Body = strbody
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
hello you could do like this
"Review 1 Suspense: " & range("I2") & vbNewLine & _

need help fixing my code for sending automatic emails through vba

I have recently written a code that allows me to send an email to a specific person in a range when clicking the command button. My code originally was working fine, however, I wanted to reference my range of these peoples emails on another sheet named "Parameter" instead of the active sheet.
When I changed my code it worked but instead of sending one email it sent three. I need help ending my code so that it will only send one email.
Private Sub JLechner_Click()
Dim sh As Worksheet
Dim sh2 As Worksheet
Dim wb As Workbook
Dim FileExtStr As String
Dim FileFormatNum As Long
Dim TempFilePath As String
Dim TempFileName As String
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
TempFilePath = Environ$("temp") & "\"
If Val(Application.Version) < 12 Then
'You use Excel 97-2003
FileExtStr = ".xls": FileFormatNum = -4143
Else
'You use Excel 2007-2016
FileExtStr = ".xlsm": FileFormatNum = 52
End If
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set sh2 = ThisWorkbook.Sheets("Parameter")
For Each sh In ThisWorkbook.Worksheets
If sh2.Range("K8").Value Like "?*#?*.?*" Then
sh.Copy
Set wb = ActiveWorkbook
TempFileName = "Sheet " & sh.Name & " of " _
& ThisWorkbook.Name & " " & Format(Now, "dd-mmm-yy h-mm-ss")
Set OutMail = OutApp.CreateItem(0)
With wb
.SaveAs TempFilePath & TempFileName & FileExtStr, FileFormat:=FileFormatNum
strbody = "(See below for english version)" & vbNewLine & vbNewLine & _
"Hallo," & vbNewLine & vbNewLine & _
"Maß " & sh.Range("E4").Value & " muss geprüft werden." & vbNewLine & _
"Bitte im Sharepoint die prüfung durchführen." & vbNewLine & vbNewLine & _
"Die Maßnahmenblätter finden Sie unter folgendem Link:" & vbNewLine & vbNewLine & _
"Wenn die Prüfung abgeschlossen ist, bitte die Taste auf der rechten Seite der tabelle drücken, um die Maßnahme zum folgendem Bearbeiter weiterzuleiten." & vbNewLine & _
"Wenn Sie Unterstützung brauchen, bitte kontaktieren Sie Bob and Ryan." & vbNewLine & vbNewLine & _
"Vielen Dank." & vbNewLine & _
"Mit freundlichen Grüßen" & vbNewLine & _
"Team" & vbNewLine & vbNewLine & vbNewLine & _
"----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------" & vbNewLine & vbNewLine & vbNewLine & _
"Hello," & vbNewLine & vbNewLine & _
"Measure " & sh.Range("E4").Value & " must be checked." & vbNewLine & _
"Please access the Sharepoint and proceed with your corresponding check." & vbNewLine & vbNewLine & _
"Measures can be found using the following link:" & vbNewLine & vbNewLine & _
"When finished, please forward the measure to the next responsible person using the buttons on the right side of the table." & vbNewLine & _
"If you require support, contact any MTM responsible persons." & vbNewLine & vbNewLine & _
"Thank you," & vbNewLine & _
"Best regards," & vbNewLine & _
"Team"
On Error Resume Next
With OutMail
.To = sh2.Range("K8").Value
.CC = ""
.BCC = ""
.Subject = "Bitte Maßnahmenblatt bearbeiten: " & sh.Range("E4").Value
.Body = strbody
.Send 'or use .Display
End With
On Error GoTo 0
.Close savechanges:=False
End With
Set OutMail = Nothing
Kill TempFilePath & TempFileName & FileExtStr
End If
Next sh
Set OutApp = Nothing
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Please let me know if anyone can help me with this.
I think you need to just change this
For Each sh In ThisWorkbook.Worksheets
If sh2.Range("K8").Value Like "?*#?*.?*" Then
to this
For Each sh In ThisWorkbook.Worksheets
If sh.Range("K8").Value Like "?*#?*.?*" Then
Because you are looping over every sheet but checking condition for sheet Parameter everytime which results TRUE for every worksheet.

select which account to send outlook email from?

I have this code which sends out an email using outlook. I have multiple email accounts in outlook and I am trying to add in a way so i can tell it which email address to send it from? Can someone please show me how i can do this?
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = Range("AS1").Column Then
If Target.Row > 7 And Target.Value = "Send Email" Then
Range("AU" & Target.Row).Value = Date
End If
End If
If Target.Column = Range("CD1").Column Then
If Target.Row > 7 And Target.Value = "Notify" Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = "Dear " & Range("AE" & ActiveCell.Row) & "," & vbNewLine & vbNewLine & _
"This is an automated email, sent to you by the purchasing department." & vbNewLine & _
"We have an update on the status of your New Supplier Request. Please see the information below." & vbNewLine & vbNewLine & _
"Supplier Name: " & Range("B" & ActiveCell.Row) & vbNewLine & _
"Supplier Reference Number: " & Range("AG" & ActiveCell.Row) & vbNewLine & _
"Supplier Status: " & Range("D" & ActiveCell.Row) & vbNewLine & vbNewLine & _
"Description:" & vbNewLine & _
"We have successfully recieved your application and we have sent out our required documents to the supplier. Once these have been returned we will contact you with a further update. If you have any queries, please contact us at Purchasing#hewden.co.uk." & vbNewLine & vbNewLine & _
"What does this mean?" & vbNewLine & _
"We ask that all New Suppliers be registered to allow us to manage a more efficient supply chain. Right now you don't need to do anything else, we will contact the supplier and gather any additional information which we need. Please keep a note of your reference number in the event you should have any enquiries." & vbNewLine & vbNewLine & _
"Kind Regards," & vbNewLine & _
"Automated Purchasing Email"
On Error Resume Next
With OutMail
.to = Range("AF" & ActiveCell.Row)
.CC = "something#something.com"
.BCC = ""
.Subject = "New Supplier Request - Update"
.Body = strbody
'You can add a file like this
'.Attachments.Add ("C:\test.txt")
.Send 'or use .Display
End With
On Error GoTo 0
End If
End If
End Sub
If you are using multiple POP3/SMTP accounts, set the MailItem.SendUsingAccount property to one of the accounts from the Namespace.Accounts collection.
If you are using Exchange, set the MailItem.SentOnBehalfOfName property - you must have an explicit permission to send on behalf of that user.
Try this
With OutMail
.SentOnBehalfOfName = "YourEmailAccount#Email.com"
.to = Range("AF" & ActiveCell.Row)
.CC = "something#something.com"
.BCC = ""
.Subject = "New Supplier Request - Update"
.Body = strbody
'You can add a file like this
'.Attachments.Add ("C:\test.txt")
.Send 'or use .Display
End With

Resources