I am trying to create a macro where the all pending tasks for one person, one e-mail, will be included in one Outlook e-mail. Basically the program will search for the pending tasks, group them all and send it to the e-mail address of the person it is assigned to.
I was able to modify/create a code where the pending task reminders are sent automatically, but it is sending one task per e-mail. This floods the person with multiple reminders.
Is it possible to have one e-mail reminder that includes all the pending tasks for that person?
Sub Reminder()
Dim wStat As Range, i As Long
Dim dam As Object
For Each wStat In Range("D6", Range("D" & Rows.Count).End(xlUp))
If wStat.Value = "Pending" Then
i = wStat.Row
If Cells(i, "I").Value <= Range("I3").Value Then
Set dam = CreateObject("Outlook.Application").CreateItem(0)
dam.To = Range("L" & i).Value
dam.CC = Range("L" & i).Value
dam.Subject = Range("B" & i).Value
dam.Body = "Dear " & Range("E" & i).Value & "," & vbCr & vbCr & _
"This is to remind you that the task: " & Range("B" & wStat.Row).Value & " - " & " " & _
"is still pending." & vbCr & vbCr & _
"Thank you!"
'
dam.Send 'change send to display if you want to check
wStat.Value = "Pending"
End If
End If
Next
MsgBox "Reminders Sent!"
End Sub
This is the sample Excel file
This is what it looks like now
This is what I want it to look like
Based on the image of the file, to create only one email
Option Explicit
Sub Reminder()
Dim wks As Worksheet
Set wks = ActiveSheet
Dim LastRow As Long
Dim taskStr As String
Dim olApp As Object
Dim dam As Object
Set olApp = CreateObject("Outlook.Application")
Set dam = olApp.CreateItem(0)
dam.To = wks.Range("B2").Value
dam.Subject = "Pending Tasks"
LastRow = wks.Cells(wks.Rows.count, "A").End(xlUp).Row
Debug.Print "LastRow: " & LastRow
For i = 2 To LastRow
taskStr = taskStr & wks.Range("A" & i).Value & vbCr
Debug.Print taskStr
Next
dam.body = "Dear " & wks.Range("C2").Value & "," & vbCr & vbCr & _
"The tasks below are still pending: " & vbCr & vbCr & taskStr
dam.Display
End Sub
Related
I want to collect all the data of all the sheets in my workbook based on the due dates in every worksheet and sum all the data of from all the sheets and paste into one email.
My code works for one selected sheet.
If I select all the sheets it takes the data of one sheet and copies the same thing by the number of sheets selected.
Sub Followup()
Dim EmailApp As Outlook.Application
Dim Source As String
Set EmailApp = New Outlook.Application
Dim EmailItem As Outlook.MailItem
Set EmailItem = EmailApp.CreateItem(olMailItem)
Dim ws As Worksheet
Dim DateDueCol As Range
Dim DateDue As Range
Dim NotificationMsg As String
Set DateDueCol = Range("R2:R100")
For Each ws In ActiveWindow.SelectedSheets
For Each DateDue In DateDueCol
If DateDue <> "" And Date >= DateDue + Range("AC1") Then
NotificationMsg = NotificationMsg & "<br>" & DateDue.Offset(0, -16) & " " & DateDue.Offset(0, -13) & " " & "CL#- " & DateDue.Offset(0, -11) & " " & "DOS- " & DateDue.Offset(0, -10)
End If
Next DateDue
Next ws
EmailItem.To = "xxxxxxxxxxxxxxxxxxxxxxxxxxx "
EmailItem.Subject = "CLAIMS CROSSED THE FOLLOW-UP DUE DATE"
EmailItem.HTMLBody = "Hi," & "<br>" & "<br>" & "The following claims
need chasing today: " & "<br>" & NotificationMsg & _
"<br>" & "<br>" & _
"Regards," & "<br>" & _
"<br>" & "xxxxxxxxxx" & _
"<br>" & " "
EmailItem.Display
End Sub
The problem is on the line
For Each ws In ActiveWindow.SelectedSheets
That's why it works only on the selected sheet. You should write something like:
For Each ws In ThiswWorkbook.Worksheets
That way you would loop through all of the sheets.
I need a piece of code I can use to create a Macro that outputs each row of my spreadsheet below as an individual Outlook email, to the email address in the column titled "Email" below. I also need to add the columns titled, "Call", "Type", "Balance" and "Company Name" to the the body of the email.
I also need to add some free text to my email which is the same for each email sent: Body of email
The following procedure should accomplish this task. It is assumed that your data is stored in the columns A:G. If this is not the case, you will need to modify the specific parts accordingly. In addition, the code already includes the feature that the subject-varying part of the "body of the e-mail" is already in bold face.
Importantly, in its current state, the code only creates and displays the e-mails. If you want to send them, you need to change this part of the code from .Display to .Send (see comment in the code):
Sub sendOlMail()
Application.ScreenUpdating = False
Dim ws As Worksheet, olApp, olMail As Object, cell As Range, lr As Long, i As Integer, strBody1, strBody2 As String
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set olApp = CreateObject("Outlook.Application")
lr = Cells(Rows.Count, "G").End(xlUp).Row 'determine row with last value for loop
strBody1 = "Dear Sir/Madam,<br/><br/>" _
& "We are still awaiting payment from you for: <br/><br/>"
strBody2 = "Please can you provide us with an update? We have recently resent out invoice/card payment links as a gentle reminder. <br/><br/>" _
& "Please note it is a legal requirement for anyone using wireless radio equipment to hold a valid licence. On occasions we carry out site visits to ensure that any frequencies being used for wireless radio equipment are being used legally. <br/><br/>" _
& "Unfortunately, we may also have to look at revoking your company’s access to our Online Portal until such time as this payment is made. <br/><br/>" _
& "Kind Regards, Joe Bloggs"
For i = 2 To lr
Set olMail = olApp.CreateItem(0)
With olMail
.To = Range("G" & i).Value
.Subject = "E-Mail Subject" 'adjust subject of your e-mail
.htmlBody = strBody1 & "<b>" _
& Range("A" & i).Value & ", " & Range("C" & i).Value & ", " & Range("D" & i).Value & ", " & Range("E" & i).Value & "</b>" & "<br/><br/>" _
& strBody2
.Display 'change to .Send if you want to send out the e-mail
End With
Set olMail = Nothing
Next i
Application.ScreenUpdating = True
End Sub
EDIT: Adding additional functionality to the code based on comment
1: I have modified the .htmlBody element so that it also contains the headers of the respective categories. Instead of hard-coding the names of the headers, I take the headers directly from the Excel file (first row in the respective columns). The advantage of this specification is that it is dyanmically specified, which means that if you change the name of your heading in the Excel file, it will be automatically reflected.
2: Including the signature is a bit more tricky, but there are several ways to accomplish this. For this step, you should make sure that you specify your signature outside the loop, otherwise this will cause unnecessary overhead. You should also make sure that you declare your signature as a string variable.
(I) Retrieving the signature from the Outlook folder. This is a bit more complicated, but for me the better solution since the formatting of the signature is preserved (I have included this approach in the updated code).
(II) Retrieving the signature from the body of an email. The disadvantage of this method is that the formatting specified by the user is not preserved. However, if this is not an issue, this could be an even simpler solution. Then simply change the signature-related parts of the code with the following parts:
Set olMail = olApp.CreateItem(0)
olMail.Display
signature = olMail.Body
Set olMail = Nothing
The code with the additional functionalities (i.e., inclusion of headers and signature) looks as follows:
Sub sendOlMail()
Application.ScreenUpdating = False
Dim ws As Worksheet, olApp, olMail As Object, cell As Range, lr As Long, i As Integer, strBody1, strBody2, signature As String
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set olApp = CreateObject("Outlook.Application")
lr = Cells(Rows.Count, "G").End(xlUp).Row 'determine row with last value for loop
' prepare signature
signature = Environ("appdata") & "\Microsoft\Signatures\"
If Dir(signature, vbDirectory) <> vbNullString Then signature = signature & Dir$(signature & "*.htm") Else signature = ""
signature = CreateObject("Scripting.FileSystemObject").GetFile(signature).OpenAsTextStream(1, -2).ReadAll
strBody1 = "Dear Sir/Madam,<br/><br/>" _
& "We are still awaiting payment from you for: <br/><br/>"
strBody2 = "Please can you provide us with an update? We have recently resent out invoice/card payment links as a gentle reminder. <br/><br/>" _
& "Please note it is a legal requirement for anyone using wireless radio equipment to hold a valid licence. On occasions we carry out site visits to ensure that any frequencies being used for wireless radio equipment are being used legally. <br/><br/>" _
& "Unfortunately, we may also have to look at revoking your company’s access to our Online Portal until such time as this payment is made. <br/><br/>" _
& "Kind Regards, Joe Bloggs"
For i = 2 To lr
Set olMail = olApp.CreateItem(0)
With olMail
.To = Range("G" & i).Value
.Subject = "E-Mail Subject" 'adjust subject of your e-mail
.htmlBody = strBody1 & "<b>" _
& Range("A" & 1).Value & ": " & Range("A" & i).Value & ", " _
& Range("C" & 1).Value & ": " & Range("C" & i).Value & ", " _
& Range("D" & 1).Value & ": " & Range("D" & i).Value & ", " _
& Range("E" & 1).Value & ": " & Range("E" & i).Value & "</b>" & "<br/><br/>" _
& strBody2 & "<br/><br/>" _
& signature
.Display 'change to .Send if you want to send out the e-mail
End With
Set olMail = Nothing
Next i
Application.ScreenUpdating = True
End Sub
My goal: An Excel spreadsheet with VBA code, where
- User ID in Column A is used for the sending address.
- user's first name in Column B is used in the greeting line of the email body.
What I have: I created multiple emails with an email body for each User ID in Column A.
What I cannot figure out: How to use the name from Column B in the email body.
For every email:
Here is the code thus far, asterisks have been used to replace email text.
Sub SendEmail()
Dim i As Integer, Mail_Object, Email_Subject, o As Variant, lr As Long
Dim strbody As String
lr = Cells(Rows.Count, "A").End(xlUp).Row
Set Mail_Object = CreateObject("Outlook.Application")
strbody = "Hello " & vbNewLine & _
"***********************" & vbNewLine & vbNewLine & _
"***********************" & vbNewLine & _
"***********************" & vbNewLine & vbNewLine & _
"***********************" & vbNewLine & _
"***********************" & vbNewLine
For i = 2 To lr
With Mail_Object.CreateItem(o)
.Subject = Range("C2").Value
.To = Range("A" & i).Value
.Body = strbody
.SentOnBehalfOfName = "*****"
'.Send
.display '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
Just add the value from cell(2,i) to .body in the loop like below
`Sub SendEmail()
Dim i As Integer, Mail_Object, Email_Subject, o As Variant, lr As Long
Dim strbody As String, Strbody1 as String
lr = Cells(Rows.Count, "A").End(xlUp).Row
Set Mail_Object = CreateObject("Outlook.Application")
strbody = "Hello "
strbody1 = vbNewLine & _
"***********************" & vbNewLine & vbNewLine & _
"***********************" & vbNewLine & _
"***********************" & vbNewLine & vbNewLine & _
"***********************" & vbNewLine & _
"***********************" & vbNewLine
For i = 2 To lr
With Mail_Object.CreateItem(o)
.Subject = Range("C2").Value
.To = Range("A" & i).Value
.Body = strbody & Range("B" & i).Value & strbody2
.SentOnBehalfOfName = "*****"
'.Send
.display '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`
Will give my comment as an answer:
First, do the Excel activities at once, storing what's needed in variables so you're not changing focus back and fourth between Excel/Outlook:
Public toString as String
Private Sub excelActivities()
with thisworkbook.sheets("NAME")
dim lr as long
lr = .Cells(.Rows.Count, "A").End(xlUp).Row
dim i as long
for i = 2 to lr
toString = toString & ";" & .Cells(i,1).Value
next i
end with
End Sub
Then you can use your Excel values, stored as variables, when performing your Outlook activities... could be two separate subroutines called in series:
Sub generateEmail()
excelActivities
outlookActivities
End Sub
Your outlookActivities would include creating the email, adding the .To = toString, etc.
I would like to learn:
I have a column (column 'F') of flags('1' for Yes and '0' for No). I would like to loop through each cell in the column and if the flag in that cell is a '1', I would like to use a string variable to hold the data in the other cells on that row adjacent to the cell containing the '1' Flag.
This is so I can take these string to customize the email with these string and send many emails to different users using the email Id's in column 'C'.
Img
Here is my code so Far:
Sub Sendmail()
Dim answer As String
Dim SubmitLink_BorrowerName As String
Dim SubmitLink_BookName As String
Dim SubmitLink_CheckoutDate As String
Dim KeyCells As Range
Dim i As Long
Set KeyCells = Range("F2:F10") 'Range of 'Y/N' for whole column
SubmitLink_BorrowerName = Range("A2").Value 'SubmitLink contains content of cell B1
SubmitLink_BookName = Range("B2").Value 'SubmitLink contains content of cell B1
SubmitLink_CheckoutDate = Range("D2").Value 'SubmitLink contains content of cell B1
answer = MsgBox("Do you wish to save this change. An Email will be sent to the User", vbYesNo, "Save the change")
If answer = vbNo Then Cancel = True
If answer = vbYes Then
For i = 2 To 20
If Cells(i, 6).Value = 1 And Not IsEmpty(Cells(i, 6).Value) Then
Cells(i, 6).Font.Color = vbBlue
'Open Outlook
Set OutlookApp = CreateObject("Outlook.Application")
Set OlObjects = OutlookApp.GetNamespace("MAPI")
Set newmsg = OutlookApp.CreateItem(olMailItem)
'Add recipient
newmsg.Recipients.Add Worksheets("Sheet1").Range("C2").Value
'Add subject
newmsg.Subject = "Book: " & SubmitLink_BookName & " overdue" 'Worksheets("Sheet1").Range("F1").Value
'Add body
newmsg.Body = "Dear " & SubmitLink_BorrowerName & "," & vbLf & vbLf & "This is a friendly reminder that Book: " & SubmitLink_BookName & " borrowed on " & SubmitLink_CheckoutDate & " has not yet been returned to the PC team." & vbLf & vbLf & "Kindly return this book to the Book shelf" & vbLf & "Regards, " & vbLf & vbLf & "Admin"
'Display
newmsg.Display
newmsg.Send
MsgBox "Modification confirmd", , "Confirmation"
End If
End If
End Sub
Thanks in advance!
You forgot to add Next i.strong text
If answer = vbYes Then
For i = 2 To 20
If Cells(i, 6).Value = 1 And Not IsEmpty(Cells(i, 6).Value) Then
Cells(i, 6).Font.Color = vbBlue
'Open Outlook
Set OutlookApp = CreateObject("Outlook.Application")
Set OlObjects = OutlookApp.GetNamespace("MAPI")
Set newmsg = OutlookApp.CreateItem(olMailItem)
'Add recipient
newmsg.Recipients.Add Worksheets("Sheet1").Range("C2").Value
'Add subject
newmsg.Subject = "Book: " & SubmitLink_BookName & " overdue" 'Worksheets("Sheet1").Range("F1").Value
'Add body
newmsg.Body = "Dear " & SubmitLink_BorrowerName & "," & vbLf & vbLf & "This is a friendly reminder that Book: " & SubmitLink_BookName & " borrowed on " & SubmitLink_CheckoutDate & " has not yet been returned to the PC team." & vbLf & vbLf & "Kindly return this book to the Book shelf" & vbLf & "Regards, " & vbLf & vbLf & "Admin"
'Display
newmsg.Display
newmsg.Send
MsgBox "Modification confirmd", , "Confirmation"
End If
Next i
End If
So I'm in need of some help. I'm trying to update my company's Excel tool that they use to manage clients. I currently need help with updating the Send Email function of the tool. So employees will have a list of clients they need to send an email to, and each client will have specific information like name, client number, etc., and the employees should be able to click the "Send Email" macro button that's built in, and different emails will populate in Outlook with the specific info for each client built into the Email recipient, Title and Body.
I am currently stuck. For example, I will choose 3 clients to send an email to, click the "Send Email" button, and I will get 3 emails to populate (as I should). The first email will have all of the correct info in the right place for Client #1. However, Email #2 will have the correct Email Recipient & Email Title, but then the Email Body will have the correct info for Client #2, and below that also in the Email Body will be all of the email body info for Client #1. And same for Email #3, it will have the correct recipient and title, but the Body will have body info for Client #3, then Client #2, then Client #1.
So I know that I need to fix it through some sort of loop for the email body, but I have been working on this for so long I just can't see it anymore. I've removed any sensitive information and put in placeholders, but I think you should get the idea.
Please let me know if you have any questions.
Sub SendEMail()
Dim Email As String
Dim Subj As String
Dim Msg As String
Dim URL As String
Dim r As Integer
Dim x As Double
Dim OApp As Object
Dim OMail As Variant
Dim Signature As String
Dim strbody As String
strbody = "<html><body>"
With Sheets("Email").Select
lastrow = Cells(Rows.Count, "B").End(xlUp).Row
End With
For r = 2 To lastrow
Set OApp = CreateObject("Outlook.Application")
Set OMail = OApp.CreateItem(0)
' Get the email address
Sheets("Email").Select
Email = Cells(r, "F")
' Message subject
Sheets("Email").Select
Subj = "Renewal for " & Cells(r, "B").Text & " Contract " & Cells(r, "A").Text & " Effective " & Cells(r, "C").Text
' Message body
Sheets("Email").Select
strbody = strbody & "Dear " & Cells(r, "AR").Text & ", <br><br>" & _
"I will be working with you on " & Cells(r, "B") & ", client number " & Cells(r, "A") & ", which is effective " & Cells(r, "C") & ".<br><br>" & _
"For this year's contract, we are requesting the following information: <br>" & _
"<li>" & Cells(r, "AH") & "</li>" & "<br><br>" & _
"The application form may be downloaded from:<br>" & _
"<li>Option #1</li>: " & "" & "Link#1" & "" & "<br>" & _
"<li>Option #2</li>: " & "" & "link#2" & "" & "<br><br>" & _
"Once we receive the requested information, you will receive your contract within 5 business days. Should you have any questions, please don't hesitate to contact me at this email address or phone number <br><br>" & _
"As always, we would like to thank you for your business. <br><br>" & _
"Regards, <br>"
On Error Resume Next
Sheets("Email").Select
With OMail
.Display
.To = Email
.Subject = Subj
.HTMLBody = strbody & vbNewLine & .HTMLBody
End With
Next r
On Error GoTo 0
Set OMail = Nothing
Set OApp = Nothing
End Sub
Please take a look at this example.
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
You can learn more about it from the link below.
http://www.rondebruin.nl/win/s1/outlook/amail6.htm
If you want to use this macro instead of a mail merge the problem you are having is here:
strbody = strbody & "Dear " & Cells(r, "AR").Text & ", <br><br>" & _
"I will be working with you on " & Cells(r, "B") & ", client number " & Cells(r, "A") & ", which is effective " & Cells(r, "C") & ".<br><br>" & _
"For this year's contract, we are requesting the following information: <br>" & _
"<li>" & Cells(r, "AH") & "</li>" & "<br><br>" & _
"The application form may be downloaded from:<br>" & _
"<li>Option #1</li>: " & "" & "Link#1" & "" & "<br>" & _
"<li>Option #2</li>: " & "" & "link#2" & "" & "<br><br>" & _
"Once we receive the requested information, you will receive your contract within 5 business days. Should you have any questions, please don't hesitate to contact me at this email address or phone number <br><br>" & _
"As always, we would like to thank you for your business. <br><br>" & _
"Regards, <br>"
This takes the variable strbody and adds the rest of the string to it.
Update it to:
strbody = "Dear " & Cells(r, "AR").Text & ", <br><br>" & _
"I will be working with you on " & Cells(r, "B") & ", client number " & Cells(r, "A") & ", which is effective " & Cells(r, "C") & ".<br><br>" & _
"For this year's contract, we are requesting the following information: <br>" & _
"<li>" & Cells(r, "AH") & "</li>" & "<br><br>" & _
"The application form may be downloaded from:<br>" & _
"<li>Option #1</li>: " & "" & "Link#1" & "" & "<br>" & _
"<li>Option #2</li>: " & "" & "link#2" & "" & "<br><br>" & _
"Once we receive the requested information, you will receive your contract within 5 business days. Should you have any questions, please don't hesitate to contact me at this email address or phone number <br><br>" & _
"As always, we would like to thank you for your business. <br><br>" & _
"Regards, <br>"
And it will overwrite it each time which is what I think you want.
Also you don't need to select the sheet each time (or at all really). Selecting sheets, cells, etc is generally bad coding practice that can significantly slow down your code.