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.
Related
I am trying to get my email lists from all worksheets that apply to the set rules to pull the email lists from said worksheet when appropriate. The column for mailing is S for every worksheet. I'm new to vba so I'm struggling a bit. This is the code I currently have. I guess I want the rules to kind of apply to the email list as well and pull from pages that have been proven true to generate the email in the first place. Thank you in advance for any help.
Option Explicit
Sub Main_AllWorksheets()
Dim sh As Worksheet, i As Long, shtsRotations As String
Dim shtsFunctions As String, shtsOK As String
Dim shtsManufacture As String
For Each sh In ActiveWorkbook.Worksheets
If Application.CountIf(sh.Range("O3:O70"), "<1") > 0 Then
shtsRotations = shtsRotations & vbLf & sh.Name
Else
shtsOK = shtsOK & vbLf & sh.Name & " (Rotations)"
End If
If Application.CountIf(sh.Range("P3:P70"), "<1") > 0 Then
shtsFunctions = shtsFunctions & vbLf & sh.Name
Else
shtsOK = shtsOK & vbLf & sh.Name & " (Functions)"
End If
If Application.CountIf(sh.Range("Q3:Q70"), "<1") > 0 Then
shtsManufacture = shtsManufacture & vbLf & sh.Name
Else
shtsOK = shtsOK & vbLf & sh.Name & " (Manufacturing Date)"
End If
Next sh
Dim myDataRng As Range
Set myDataRng = Range("S2:S15" & Cells(Rows.Count, "S").End(xlUp).Row)
Dim cell As Range
Dim iCnt As Integer
Dim sMail_ids As String
For Each cell In myDataRng
If Trim(sMail_ids) = "" Then
sMail_ids = cell.Offset(1, 0).Value
Else
sMail_ids = sMail_ids & vbCrLf & ";" & cell.Offset(1, 0).Value
End If
Next cell
Set myDataRng = Nothing ' Clear the range.
If Len(shtsRotations) > 0 Then
SendReminderMail sMail_ids, "Equipment rotations are due!", _
"Hello Team, " & vbNewLine & vbNewLine & _
"Check customer sheets: " & shtsRotations & vbLf & vbNewLine & _
"In the attatched workbook, you can see what equipment needs to be rotated by the red dates, indicating their last rotation."
End If
If Len(shtsFunctions) > 0 Then
SendReminderMail "sMail_ids", "Equipment functions are due! ", _
"Hello Team, " & vbNewLine & vbNewLine & _
"Check customer sheets: " & shtsFunctions & vbLf & vbNewLine & _
"In the attatched workbook, you can see what equipment needs to be functioned by the red dates, indicating their last function."
End If
If Len(shtsManufacture) > 0 Then
SendReminderMail "test#test.com", "Manufacturing date has surpassed 3 years!", _
"Hello Team, " & vbNewLine & vbNewLine & _
"Check customer sheets: " & shtsRotations & vbLf & vbNewLine & _
"In the attatched workbook, you can see what equipment has reached it's 3 years past manufacturing."
End If
If Len(shtsOK) > 0 Then
MsgBox "These sheets are OK: " & vbLf & shtsOK, vbInformation
End If
End Sub
Sub SendReminderMail(sTo As String, sSubject As String, sBody As String)
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim TempFilePath As String
Dim TempFileName As String
Dim FileExtStr As String
Dim OutApp As Object
Dim OutMail As Object
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set wb1 = ActiveWorkbook
TempFilePath = Environ$("temp") & "\"
TempFileName = "Copy of " & wb1.Name & " " & Format(Now, "dd-mmm-yy h-mm-ss")
FileExtStr = "." & LCase(Right(wb1.Name, Len(wb1.Name) - InStrRev(wb1.Name, ".", , 1)))
wb1.SaveCopyAs TempFilePath & TempFileName & FileExtStr
Set wb2 = Workbooks.Open(TempFilePath & TempFileName & FileExtStr)
wb2.Worksheets(1).Range("A1").Value = "Copy created on " & Format(Date, "dd-mmm-yyyy")
wb2.Save
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.to = sTo
.CC = ""
.BCC = ""
.Subject = sSubject
.Body = sBody
.Attachments.Add wb2.FullName
.Display 'or use .Display
End With
On Error GoTo 0
wb2.Close savechanges:=False
Kill TempFilePath & TempFileName & FileExtStr
Set OutMail = Nothing
Set OutApp = Nothing
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
MsgBox "Your Automated Email for the Workbook was successfully ran at " & TimeValue(Now), vbInformation
End Sub
Use the Recipients property of the MailItem class for specifying recipients. For example:
recipients = mail.Recipients
' now we add new recipietns to the e-mail
recipientTo = recipients.Add("Eugene Astafiev")
recipientTo.Type = Outlook.OlMailRecipientType.olTo
recipientCC = recipients.Add("Dmitry K.")
recipientCC.Type = Outlook.OlMailRecipientType.olCC
recipientBCC = recipients.Add("eugene.astafiev#somedomain.com")
recipientBCC.Type = Outlook.OlMailRecipientType.olBCC
retValue = recipients.ResolveAll()
Read more about that in the following articles:
How To: Fill TO,CC and BCC fields in Outlook programmatically
How To: Create and send an Outlook message programmatically
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
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
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
Next is some macro which compare cell D with current date and if it is in past it send notification to email defined in cell L. The problem here is that the macro need to be run manually by pressing Alt+F8, so the question is how to make the macro automatically run when it noticed that updated cell D value is in past, so there is no need all the time to run the macro manually.
Thanks in advance
Sub SendMail()
Dim OutApp As Object
Dim OutMail As Object
Dim RelDate As Range
Dim lastRow As Long
Dim dateCell, dateCell1 As Date
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
OutApp.Session.Logon
lastRow = Range("A" & Rows.Count).End(xlUp).Row
On Error GoTo cleanup
For Each RelDate In Range("D2:D" & lastRow)
If RelDate = "" Then GoTo 1
dateCell = RelDate.Value
dateCell1 = Cells(RelDate.Row, "C").Value
If dateCell < Date Then ' this if cell value is smalle than today then it will send notification
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = Cells(RelDate.Row, "L").Value
.Subject = "Release Date Changed" ' Change your massage subject here
'Change body of the massage here
.Body = "Dear " & Cells(RelDate.Row, "E").Value _
& vbNewLine & vbNewLine & _
"The release date of " & Cells(RelDate.Row, "A").Value & _
" is changed to " & dateCell _
& vbNewLine & vbNewLine _
& vbNewLine & vbNewLine & _
"Regards," & vbNewLine & _
"Your Name"
.send
End With
On Error GoTo 0
Set OutMail = Nothing
End If
' Cells(RelDate.Row, "C").Value = dateCell
' RelDate.ClearContents
1: Next RelDate
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Use this code in worksheet_change event. It will compare the date in all the changed cells in column "D" and if condition is true, it will call the sendmail procedure. Please adjust your sendmail code accordingly.
This code also works if you copy paste multiple rows of data.
Hope that help!. :-)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim to_email As String
Dim subject As String
Dim body As String
For Each cell In Target.Cells
On Error Resume Next
If cell.Column = 4 And cell < Date Then
On Error GoTo errhandler
to_email = ActiveSheet.Cells(cell.Row, "L").Value
subject = "Release Date Changed"
body = "Dear " & ActiveSheet.Cells(cell.Row, "E").Value _
& vbNewLine & vbNewLine & _
"The release date of " & ActiveSheet.Cells(cell.Row, "A").Value & _
" is changed to " & ActiveSheet.Cells(cell.Row, 4) _
& vbNewLine & vbNewLine _
& vbNewLine & vbNewLine & _
"Regards," & vbNewLine & _
"Your Name"
sendmail to_email, subject, body
End If
Next cell
Exit Sub
errhandler:
Err.Raise Err.Number, Err.Source, Err.Description
End Sub
Sub sendmail(to_email As String, subject As String, body As String)
adjust your code accordingly
End Sub