Would anyone be so kind and help me out with my problem? I have this example table:
I would like to send a personalized email for each row, this is what I got so far:
Sub SendEmails()
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
On Error GoTo cleanup
For Each cell In Columns("A").Cells.SpecialCells(xlCellTypeConstants)
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = cell.Value
.Subject = "Project" & Sheets("Sheet1").Range("C").Value ' insert subject from column C
.HTMLBody = "<p>Hello " & Sheets("Sheet1").Range("B").Value &"</p>" & _ ' insert Name from column B
"<p><strong><u>This is a test email</u></strong></p>"
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
I would like to have data from columns B and C in the email, but I have no idea how to reference them in For each loop and how to put them to the place I want.
Thank you
Try this code : (I changed 3 lines in your code, I marked Them with (X))
Sub SendEmails()
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
On Error GoTo cleanup
For Each cell In Columns("A").Cells.SpecialCells(xlCellTypeConstants)
i = cell.Row '(X)
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = cell.Value
.Subject = "Project" & Sheets("Sheet1").Range("C" & i).Value '(X)
.HTMLBody = "<p>Hello " & Sheets("Sheet1").Range("B" & i).Value & "</p>" & "<p><strong><u>This is a test email</u></strong></p>" '(X)
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Instead if using a Range Object you store the content of the Range you are using into a matrix (2D Array)
Now you can access the "cells" by indexing your array. So content of column B would be myArray(rowNumber,2)
Sub SendEmails()
Dim OutApp As Object
Dim OutMail As Object
Dim rng As Variant
myArray= ThisWorkbook.Sheets("Sheet1").Range("A1:C4")
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
For i = 2 To UBound(myArray)
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = myArray(i, 1)
.Subject = "Project" & myArray(i, 3)
.HTMLBody = "<p>Hello " & myArray(i, 2) & "</p>" & _
"<p><strong><u>This is a test email</u></strong></p>"
.Display
End With
Next i
Try it like this.
In column A : Names of the people
In column B : E-mail addresses
In column C:Z : Filenames like this C:\Data\Book2.xls (don't have to be Excel files)
The Macro will loop through each row in "Sheet1" and if there is a E-mail address in column B
and file name(s) in column C:Z it will create a mail with this information and send it.
Sub Send_Files()
'Working in Excel 2000-2016
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim OutApp As Object
Dim OutMail As Object
Dim sh As Worksheet
Dim cell As Range
Dim FileCell As Range
Dim rng As Range
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set sh = Sheets("Sheet1")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("B").Cells.SpecialCells(xlCellTypeConstants)
'Enter the path/file names in the C:Z column in each row
Set rng = sh.Cells(cell.Row, 1).Range("C1:Z1")
If cell.Value Like "?*#?*.?*" And _
Application.WorksheetFunction.CountA(rng) > 0 Then
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = cell.Value
.Subject = "Testfile"
.Body = "Hi " & cell.Offset(0, -1).Value
For Each FileCell In rng.SpecialCells(xlCellTypeConstants)
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
.Send 'Or use .Display
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
https://www.rondebruin.nl/win/s1/outlook/amail6.htm
Related
I want to send email with deferred delivery according to the cells ("A2:A4").
For instance, if today is 2 February 2023, send three emails for delivery on 6 February, 13 February and 20 February.
The VBA code sends an email for last cell ("A4").
For ("A2") AND ("A3") the email won't be created.
Sub Send_Deferred_Mail_From_Excel()
Dim OutlookApp As Object
Dim OutlookMail As Object
Dim xRg As Range
Set xRg = Range("A2:A4")
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookMail = OutlookApp.CreateItem(0)
'Send Email Using Excel VBA Macro Code
With OutlookMail
.To = "email"
.CC = ""
.BCC = ""
.Subject = "HI"
.Body = "HELLO"
'Send email on specific day & time
.DeferredDeliveryTime = Range("A2") + Range("A3") + Range("A4")
.Display 'or just put .Send to directly send the mail instead of display
End With
Set OutlookMail = Nothing
Set OutlookApp = Nothing
End Sub
Please try it like this.
Make a list in Sheets("Sheet1") with :
In column A : Names of the people
In column B : E-mail addresses
In column C:Z : Filenames like this C:\Data\Book2.xls (don't have to be Excel files)
The Macro will loop through each row in "Sheet1" and if there is a E-mail address in column B
and file name(s) in column C:Z it will create a mail with this information and send it.
Sub Send_Files()
'Working in Excel 2000-2016
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim OutApp As Object
Dim OutMail As Object
Dim sh As Worksheet
Dim cell As Range
Dim FileCell As Range
Dim rng As Range
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set sh = Sheets("Sheet1")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("B").Cells.SpecialCells(xlCellTypeConstants)
'Enter the path/file names in the C:Z column in each row
Set rng = sh.Cells(cell.Row, 1).Range("C1:Z1")
If cell.Value Like "?*#?*.?*" And _
Application.WorksheetFunction.CountA(rng) > 0 Then
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = cell.Value
.Subject = "Testfile"
.Body = "Hi " & cell.Offset(0, -1).Value
For Each FileCell In rng.SpecialCells(xlCellTypeConstants)
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
.Send 'Or use .Display
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
Sub Send_Deferred_Mail_From_Excel()
Dim OutlookApp As Object
Dim OutlookMail As Object
Dim xRg As Range
Set xRg = Range("A2:A4")
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookMail = OutlookApp.CreateItem(0)
'Send Email Using Excel VBA Macro Code
With OutlookMail
.To = "email"
.CC = ""
.BCC = ""
.Subject = "HI"
.Body = "HELLO"
''Try in a loop instead.
for each cell in xRg
'Send email on specific day & time
.DeferredDeliveryTime = cell
.Display 'or just put .Send to directly send the mail instead of display
next cell
End With
Set OutlookMail = Nothing
Set OutlookApp = Nothing
End Sub
I've got how to send multiple emails to one email address using date & time in cells
Sub Send_Deferred_Mail_From_Excel()
Dim i As Integer, OutlookMail As Object, lr As Long
Dim xRg As Range, Bk As Range
' get last row
lr = Cells(Rows.Count, "A").End(xlUp).Row
' create range from row 2 to last row
Set xRg = Range("A2:A" & lr)
Set OutlookMail = CreateObject("Outlook.Application")
For Each Bk In xRg
With OutlookMail.CreateItem(0)
.To = "email#gmail.com"
.CC = ""
.subject = "HI"
.Body = "HELLO"
' Send email on specific day & time
.DeferredDeliveryTime = Bk.Value
.Display
End With
Next Bk
End Sub
I found macros to send an email to each person in a column.
Column B shows the names which have "Yes" in column C. I have added this condition in Power Query.
Sub Send_Row_Or_Rows_Attachment_1()
'Working in 2000-2016
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Dim intHowManyRows As Integer
With Application
.ScreenUpdating = False
End With
intHowManyRows = Application.Range("B2").CurrentRegion.Rows.Count
For r = 1 To intHowManyRows
'Save, Mail, Close and Delete the file
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = ThisWorkbook.Sheets("Sheet3").Range("B1").Value
' Cells(r, 2).Value
.Subject = Cells(r, 3).Value
'.Attachments.Add FullName -> If you want to add attachments
.Body = "Hi there" & vbNewLine & vbNewLine & "How are you " & Cells(r, 2)
.Display 'Or use Send
End With
Next r
Set OutMail = Nothing
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Or:
Sub Test2()
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
'Working in Office 2000-2016
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
On Error GoTo cleanup
For Each cell In Columns("B").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" And _
LCase(Cells(cell.Row, "C").Value) = "yes" Then
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = ThisWorkbook.Sheets("Sheet3").Range("B1").Value
.Subject = "Reminder"
.Body = "Dear " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"Please contact us to discuss bringing " & _
"your account up to date"
'You can add files also like this
'.Attachments.Add ("C:\test.txt")
.Send 'Or use Display
End With
On Error GoTo 0
Set OutMail = Nothing
End If
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
I want to generate a single Outlook mail with all persons in column B in the "To" and also attach a file.
I adjusted Ron's code. See my comments and adjust it to fit your needs.
EDIT: As per niton's suggestion, remove the on error resume next and see what line causes the error.
Option Explicit
Public Sub SendEmail()
' For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
' Working in Office 2000-2016
' Adapted by Ricardo Diaz ricardodiaz.co
Dim OutApp As Object
Dim OutMail As Object
Dim sourceTable As ListObject
Dim evalRow As ListRow
Dim counter As Long
Dim toArray() As Variant
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
Set sourceTable = Range("Table1").ListObject ' -> Set the table's name
On Error GoTo cleanup
' Loop through each table's rows
For Each evalRow In sourceTable.ListRows
If evalRow.Range.Cells(, 2).Value Like "?*#?*.?*" And LCase(evalRow.Range.Cells(, 3).Value) = "yes" Then
ReDim Preserve toArray(counter)
toArray(counter) = evalRow.Range.Cells(, 2).Value
counter = counter + 1
End If
Next evalRow
' Setup the email
Set OutMail = OutApp.CreateItem(0)
With OutMail
' Add gathered recipients
For counter = 0 To UBound(toArray)
.Recipients.Add (toArray(counter))
Next counter
.Subject = "Reminder"
.Body = "Dear All" _
& vbNewLine & vbNewLine & _
"Please contact us to discuss bringing " & _
"your account up to date"
'You can add files also like this
.Attachments.Add ("C:\test.txt") ' -> Adjust this path
.Send ' -> Or use Display
End With
Set OutMail = Nothing
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Let me know if it works.
I'm new to the forum. I have a little problem with a vba macro in excel. Probably it's not so difficult for you, but I'm totally new on vba. I have two columns: column "A" with a choice (es. "yes" or "no") and column "B" with a string. I want to send an email with the "B" string list with all the strings (line-by-line) that have "yes" value in "A".
Sub Alert()
ActiveSheet.UsedRange.Select
On Error Resume Next
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Dim list As Object
Dim element As Variant
Application.ScreenUpdating = False
Do While Trim(Cells(cell.Row, "A").Value) = ""
On Error GoTo alertmail
For Each cell In Columns("A").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value = "yes" Then
element = Cells(cell.Row, "B").Value
Set list = CreateObject("System.Collections.ArrayList")
list.Add element
End If
Next cell
Loop
alertmail:
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "test#abc.com"
.Subject = "Alert"
.Body = "Your yes list is" & vbNewLine & PrintArray
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Exit Sub
Application.ScreenUpdating = True
End Sub
Until now, my best result was to send a set of different mail with only one "B" string for every "yes" "A" value (i.e. if I have 3 "yes" value I obtain 3 mails with the correct "B" string for each).
Try the following code:
Sub Alert()
ActiveSheet.UsedRange.Select
On Error Resume Next
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Dim list As String
Dim element As Variant
Application.ScreenUpdating = False
Do While Trim(Cells(cell.Row, "A").Value) = ""
On Error GoTo alertmail
For Each cell In Columns("A").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value = "yes" Then
element = Cells(cell.Row, "B").Value
list = list & vbNewLine & element
End If
Next cell
Loop
alertmail:
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "to#xyz.com"
.Subject = "Alert"
.Body = "Your yes list is" & vbNewLine & list
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Exit Sub
Application.ScreenUpdating = True
End Sub
I am currently trying to write a macro where it will email multiple attachments to recipients depending on whether each column has an X next to their name.
I have the email addresses in column G and 11 different report names ranging from columns H:R.
So far I've written a macro that will send an attachment (Report 1) if email recipients have an X in column H, but I'm unsure how to write a macro so it will search columns H:R for X and send the corresponding reports (i.e. If an email recipient has an X in column H and column J then I want them to receive both Report 1 and Report 3 in the same email).
Sorry if my explanation is difficult to interpret.
Any help is much appreciated
Private Sub CommandButton1_Click()
Dim OutApp As Object
Dim OutMail As Object
Dim sh As Worksheet
Dim cell As Range
Dim FileCell As Range
Dim rng As Range
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set sh = Sheets("Contacts")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("G").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" And _
LCase(Cells(cell.Row, "H").Value) = "x" Then
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = cell.Value
.Subject = "Report 1"
.body = "Hi " & cell.Offset(0, -3).Value
'Link file path for attachment
.Attachments.Add ("C:\Users\smcelroy021218\Desktop\Email Macro Working.xlsm")
.Display
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
You don't say where the file paths come from: in this example I'm picking them up from the first row of your sheet (so from H1:R1).
Private Sub CommandButton1_Click()
Dim OutApp As Object
Dim OutMail As Object
Dim sh As Worksheet
Dim cell As Range, c As Range
Dim FileCell As Range
Dim rng As Range, rngAttach As Range
Set sh = Sheets("Contacts")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("G").Cells.SpecialCells(xlCellTypeConstants)
Set rngAttach = cell.Offset(0, 7).Resize(1, 11)
'EDIT: must have at least one attachment to create a mail
If cell.Value Like "?*#?*.?*" And _
Application.Countif(rngAttach, "x") > 0 Then
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = cell.Value
.Subject = "Report 1"
.body = "Hi " & cell.Offset(0, -3).Value
'loop over H:R and check for "x"
For Each c In rngAttach.Cells
If LCase(Trim(c.Value)) = "x" Then
'pick up the file path from the top row of the sheet
.Attachments.Add sh.Cells(1, c.Column).Value
End If
Next c
.Display
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
End Sub
I send email with this script. I added a date input box which will add the date in email subject line. If I give a wrong date it accepts and sends the email.
Sub Send_Files()
'Working in Excel 2000-2013
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim OutApp As Outlook.Application
Dim OutMail As Outlook.MailItem
Dim sh As Worksheet
Dim cell As Range
Dim FileCell As Range
Dim rng As Range
Dim strDate As String
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
strDate = InputBox("Insert date in format dd/mm/yy", "User date", Format(No(),"dd/mm/yyyy"))
If IsDate(strDate) Then
strDate = Format(CDate(strDate), "dd/mm/yyyy")
MsgBox strDate
Else
MsgBox "Wrong date format"
End if
Set sh = Sheets("Sheet2")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("c").Cells.SpecialCells(xlCellTypeConstants)
'Enter the path/file names in the C:Z column in each row
Set rng = sh.Cells(cell.Row, 1).Range("d1:Z1")
If cell.Value Like "?*#?*.?*" And _
Application.WorksheetFunction.CountA(rng) > 0 Then
Set OutMail = OutApp.CreateItem(olMailItem)
With OutMail
.To = cell.Value
.Subject = "Testfile" & strDate
.Body = "Hi " & cell.Offset(0, -1).Value
For Each FileCell In rng.SpecialCells(xlCellTypeConstants)
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
.Display 'Or use Send
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
Exit Sub after the Msgbox line. But move your EnableEvents and ScreenUpdating block after the test for a valid Date, or they won't get switched back when you exit. – Tim Williams