E-Mail notification when cell reaches date - status update does not work - vba

I finally made it happen that my macro at least works 90%. Every time I open my Excel file, automatic e-mails are sent out to the right people.
However, I have one issue, which I cannot solve: I was hoping to implement a status, sent vs not sent, which triggers whether another e-Mail should be sent the next day.
Unfortunately, the status never updates.
I would be very happy if you can have a look at it:
Private Sub Worksheet_Calculate()
Dim FormulaRange As Range
Dim FormulaCell As Range
Dim NotSentMsg As String
Dim MyMsg As String
Dim SentMsg As String
Dim Deadline As Double
NotSentMsg = "Not Sent"
SentMsg = "Sent"
Deadline = Date
Set FormulaRange = Me.Range("S2:S64")
On Error GoTo EndMacro:
For Each FormulaCell In FormulaRange.Cells
With FormulaCell
If .Value < Deadline Then
MyMsg = NotSentMsg
If .Offset(0, 3).Value = NotSentMsg Then
Call Mail_with_outlook1(FormulaCell)
End If
Else
MyMsg = NotSentMsg
End If
Application.EnableEvents = False
.Offset(0, 3).Value = MyMsg
Application.EnableEvents = True
End With
Next FormulaCell
ExitMacro:
Exit Sub
EndMacro:
Application.EnableEvents = True
MsgBox "Some Error occurred." _
& vbLf & Err.Number _
& vbLf & Err.Description
End Sub
Sub Mail_with_outlook1(FormulaCell As Range)
Dim OutApp As Object
Dim OutMail As Object
Dim strto As String, strcc As String, strbcc As String
Dim strsub As String, strbody As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strto = Cells(FormulaCell.Row, "T").Value
strcc = Cells(FormulaCell.Row, "U").Value
strbcc = ""
strsub = "Notice Period in 6 Months"
strbody = "Hi " & Cells(FormulaCell.Row, "D").Value & _
vbNewLine & vbNewLine & "The notice period for your customer " & Cells(FormulaCell.Row, "A").Value & " is in 180 days." & _
vbNewLine & vbNewLine & "Thank you very much and feel free to reach out to me in case of any question." & _
vbNewLine & vbNewLine & "Best regards, Marius"
With OutMail
.To = strto
.CC = strcc
.BCC = strbcc
.Subject = strsub
.Body = strbody
'You can add a file to the mail like this
'.Attachments.Add ("C:\test.txt")
.Display ' or use .Send
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub

Answer on comment.
Thanks Roland,
Based on your comment and the fresh mindset of the next day I finally figured it out.
I have to move the line after the first if statement 'MyMsg = NotMsgSent' to after the second if statement, Then it works perfectly fine. Thank you!

Related

Sending Email for Each Row in Pivot Table

I'm attempting to send an email for each attendance event that is being displayed within the Pivot Table. Though it will recognize the count of rows, only the 1st row is being sent in email up to as many emails as there are rows of data.
I believe I need my offset parameters to change so it's changing by row & cell. Any suggestions?
enter image description here
Sub EmailBody()
Application.ScreenUpdating = False
ThisWorkbook.RefreshAll
'Tells it to re-run every x hours and min.
Application.OnTime Now + TimeValue("1:00"), "EmailBody"
Dim sourceSheet As Worksheet
Set sourceSheet = ActiveSheet
Dim arrHolidays As Variant, iDay As Variant
arrHolidays = Application.Transpose(Worksheets("Hold").Range("a:a").Value) 'Add all your holidays on Holidays worksheet
For Each iDay In arrHolidays
If Date = iDay Then Exit Sub 'exit this sub if date is a holiday
Next
On Error Resume Next
ThisWorkbook.RefreshAll
Worksheets("Sheet1").Activate
'Creating references to Application and MailItem Objects of Outlook
Dim outApp As Outlook.Application
Dim outMail As Outlook.MailItem
'Creating variable to hold values of different items of mail
Dim sendTo, MailBody As String
Dim lstRow As Long
ThisWorkbook.Sheets("Sheet1").Activate
'Getting last row of containing email id.
lstRow = Cells(Rows.Count, 2).End(xlUp).Row
Dim rng As Range
Set rng = Range("B2:B" & lstRow)
'initializing outlook object to access its features
Set outApp = New Outlook.Application
On Error GoTo cleanup 'to handle any error during creation of object.
For Each i In Range("b2:b100")
MailBody = "Please see the following attendance event logged in SharePoint for " & i.Offset(0, -1) & "." & vbCr & vbCr & "Date of Absence " & " : " & i.Offset(0, 2) & vbCr & "Reason for Absence " & " : " & i.Offset(0, 3) & vbCr & "Ticket Entered on" & " : " & i.Offset(0, 4) & vbCr & "Created By" & " : " & i.Offset(0, 5) & vbCr & "Notes" & " : " & i.Offset(0, 6) & vbCr & vbCr & "Please reach out to DLWESTCCWALKERRETENTIONREPORTING#charter.com, if you have any questions."
For Each cell In rng
sendTo = Range(cell.Address).Offset(0, 0).Value2 & ";" & Range(cell.Address).Offset(0, 1).Value2
Subj = "Attendance Callout Event Notification"
Msg = MailBody
On Error Resume Next 'to hand any error during creation of below object
Set outMail = outApp.CreateItem(0)
'Writing and sending mail in new mail
With outMail
.To = sendTo
.Body = Msg
.Subject = Subj
.Display '
.Send
End With
On Error GoTo 0 'To clean any error captured earlier
Set outMail = Nothing 'nullifying outmail object for next mail
Next cell 'loop ends
cleanup: 'freeing all objects created
Set outApp = Nothing
Application.ScreenUpdating = True
Application.ScreenUpdating = True
Next
End Sub

Sending Emails from Excel - No Errors but no Output

I am currently working on a macro that should create an email with variable recipients and details within the body of the email depending on input into the relevant row on the worksheet. It should generate an email per row where 'To do' is present in column P.
I currently have a sub coded with everything I think I need and when I run the macro no errors appear, unfortunately it does not open any template emails as intended either.
I'll admit that my VBA is basic at best but any assistance with the below would be great.
Sub Sendmail()
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Dim ClientEmail As Range
Dim PlannerName As String
Dim Salutation As Range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
On Error GoTo cleanup
For Each cell In Columns("F").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value = "Planner1 Initials" And _
LCase(Cells(cell.Row, "P").Value) = "To do" Then
Set ClientEmail = LCase(Cells(cell.Row, "H").Value)
PlannerName = "Planner1 Name"
Set Salutation = LCase(Cells(cell.Row, "D").Value)
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "Planner1#email.com"
.Subject = "Annual Review"
.Body = "send email to" & vbNewLine & vbNewLine & _
"Dear" & xClientSaluation & vbNewLine & vbNewLine & _
"body" & vbNewLine & _
"Best wishes" & vbNewLine & vbNewLine & _
"" & PlannerName
.Display
End With
ElseIf cell.Value = "Planner2 Initials" And _
LCase(Cells(cell.Row, "P").Value) = "To do" Then
Set ClientEmail = LCase(Cells(cell.Row, "H").Value)
PlannerName = "Planner2 Name"
Set Salutation = LCase(Cells(cell.Row, "D").Value)
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "Planner2#email.com"
.Subject = "Annual Review"
.Body = "send email to" & vbNewLine & vbNewLine & _
"Dear" & xClientSaluation & vbNewLine & vbNewLine & _
"body" & vbNewLine & _
"Best wishes" & vbNewLine & vbNewLine & _
"" & PlannerName
.Display
End With
ElseIf cell.Value = "Planner3 Initials" And _
LCase(Cells(cell.Row, "P").Value) = "To do" Then
Set ClientEmail = LCase(Cells(cell.Row, "H").Value)
PlannerName = "Planner3 Name"
Set Salutation = LCase(Cells(cell.Row, "D").Value)
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "Planner3#email.com"
.Subject = "Annual Review"
.Body = "send email to" & vbNewLine & vbNewLine & _
"Dear" & xClientSaluation & vbNewLine & vbNewLine & _
"Body " & vbNewLine & _
"Best wishes" & vbNewLine & vbNewLine & _
"" & PlannerName
.Display
End With
End If
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Appreciate that you likely don't need to repeat for each different set of initials as I have done above but was struggling to set a range without an object error.
The data held in the worksheet columns for context
F = Client Owner Initials
P = If an email needs to be sent, input either No, To Do, Yes or n/a
D = Client's salutation
Thanks,
BIG TWON
Thanks to Krib below, I am now getting Object required error on the following line, I imagine this will repeat throughout:
Set ClientEmail = LCase(Cells(cell.Row, "H").Value)
I think I can see three issues:
LCase(Cells(cell.Row, "P").Value) = "To do" Then
LCase will be seeing "to do", not "To do" so your main block(s) will never run.
Change them to:
LCase(Cells(cell.Row, "P").Value) = "to do" Then
Also, as per your recent update, the line:
Set ClientEmail = LCase(Cells(cell.Row, "H").Value)
Is trying to load the .Value of a cell into ClientEmail
Unfortunately, you have declared it a Range:
Dim ClientEmail As Range
From the looks of your code, you should be declaring it As String. But remember, you don't Set strings. You just load to them e.g:
ClientEmail = LCase(Cells(cell.Row, "H").Value)
Further to above point, you also do:
Dim Salutation As Range
and
Set Salutation = LCase(Cells(cell.Row, "D").Value)
Which should be:
Dim Salutation As String
and..
Salutation = LCase(Cells(cell.Row, "D").Value)
So to wrap up..
Your declarations should look like this:
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Dim ClientEmail As String
Dim PlannerName As String
Dim Salutation As String
Your IF statement(s) should look like this (change PlannerX each time):
If cell.Value = "Planner1 Initials" And LCase(Cells(cell.Row, "P").Value) = "to do" Then
And your variable settings should look like this (again, change PlannerX each time):
ClientEmail = LCase(Cells(cell.Row, "H").Value)
PlannerName = "Planner1 Name"
Salutation = LCase(Cells(cell.Row, "D").Value)
Maybe this will help you out...
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
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)
https://www.rondebruin.nl/win/s1/outlook/amail6.htm

Send bulk mail using Excel VBA

Was working on a project which will be sending bulk mail to different people if the conditions are met.
Conditions :
Column U contains the final status (Open or WIP) (will not send if Closed no matter if current date is larger)
Column Q contains Closure date. Which when compared to current date, if less then automatic shooting mails to people.
I had tried to do with for loop but its giving shooting 4 mails with same To and CC. And not going to the next row to compare.
Thank you in advance.
Code as below:
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim StrBody As String
Dim x As Variant
Dim arr1 As Variant
Dim i As Long, r As Long
On Error Resume Next
arr1 = Worksheets("Data").Range("Q2:Q" & Range("Q" & Rows.Count).End(xlUp).row).Value
i = 1
For Each x In arr1
For r = 1 To 2
If x < Now() Then
If Sheets("Data").Worksheets("Data").Cells(i, "U").Value = "Open" Then
Set rng = Nothing
On Error Resume Next
'Only the visible cells in the selection
Set rng = Selection.SpecialCells(xlCellTypeVisible)
'You can also use a fixed range if you want
Set rng = Sheets("Checklist").Range("A2:B25").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
If Worksheets("Data").Cells(i, "C").Value = "Operation_Support" And Worksheets("Data").Cells(i, "E").Value = "Quality_Assurance" Then
StrBody = "Hi," & "<br>" & _
.To = "a"
.CC = "b"
.BCC = ""
.Subject = ""
.HTMLBody = StrBody & RangetoHTML(rng)
.Attachments.Add ActiveWorkbook.FullName
' You can add other files by uncommenting the following line.
'.Attachments.Add ("C:\test.txt")
.Display
'.Send
ElseIf Worksheets("Data").Cells(i, "C").Value = "Operation_Support" And Worksheets("Data").Cells(i, "E").Value = "Analytics" Then
StrBody = "Hi," & "<br>" & _
"PFB the process details which requires your attention." & "<br>" & _
"The review for this process has crossed over due." & "<br>" & _
"Please ask the process owner to review the Process Manuals and Maps." & "<br><br><br>"
.To = "c"
.CC = "d"
.BCC = ""
.Subject = "Process Manual and Maps Review is Overdue"
.HTMLBody = StrBody & RangetoHTML(rng)
.Attachments.Add ActiveWorkbook.FullName
' You can add other files by uncommenting the following line.
'.Attachments.Add ("C:\test.txt")
.Display
'.Send
End If
End With
i = i + 1
Exit For
End If
End If
Next r
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
Next x
End Sub
Solved: This will solve the problem above.
Sub Data_RoundedRectangle1_Click()
Dim OutApp As Object
Dim OutMail As Object
Dim rng As Range
For i = 2 To Cells(Rows.Count, 1).End(xlUp).row
If Cells(i, 21).Value = "Open" And Cells(i, 17).Value <= Now() Then
Set rng = Nothing
On Error Resume Next
'Only the visible cells in the selection
Set rng = Selection.SpecialCells(xlCellTypeVisible)
'You can also use a fixed range if you want
Set rng = Sheets("Data").Range("C1:V5").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
If Cells(i, 3).Value = "Operation_Support" And Cells(i, 5).Value = "Quality_Assurance" Then
StrBody = "Hi," & "<br>" & _
"PFB the process details which requires your attention." & "<br>" & _
"The review for this process has crossed overdue." & "<br>" & _
"Please ask the process owner to review the Process Manuals and Maps." & "<br><br><br>"
.To = "a"
.CC = "b"
.BCC = ""
.Subject = ""
.HTMLBody = StrBody & RangetoHTML(rng)
.Attachments.Add ActiveWorkbook.FullName
' You can add other files by uncommenting the following line.
'.Attachments.Add ("C:\test.txt")
.Display
'.Send
ElseIf Cells(i, 3).Value = "Operation_Support" And Cells(i, 5).Value = "Analytics" Then
StrBody = "Hi," & "<br>" & _
"PFB the process details which requires your attention." & "<br>" & _
"The review for this process has crossed over due." & "<br>" & _
"Please ask the process owner to review the Process Manuals and Maps." & "<br><br><br>"
.To = "c"
.CC = "s"
.BCC = ""
.Subject = ""
.HTMLBody = StrBody & RangetoHTML(rng)
.Attachments.Add ActiveWorkbook.FullName
' You can add other files by uncommenting the following line.
'.Attachments.Add ("C:\test.txt")
.Display
'.Send
End If
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End If
Next i
End Sub

Userform variables to E-mail

I have a Userform which has 3 buttons on it and based on the click the respective text needs to be inserted in the body of the email, for this e-mail the To, CC, Subject, will be taken from Listview box in Sheet1 which inturn extracts the values stored in Sheet2 and paste it in To, CC, Subject of the email.
When i paste the code in the buttonclick () command the variables are not getting passed from the maincode to the userform code where it shows the To, CC and Subject as blanks.
Here's the code:
Sub Worksheet_Activate()
Dim rngCell As Range
ListView41.ListItems.Clear
For Each rngCell In Worksheets("MFRs Contacts").Range("A2:A400")
If Not rngCell = Empty Then
With ListView41.ListItems.Add(, , rngCell.Value)
.ListSubItems.Add , , rngCell.Offset(0, 1).Value
.ListSubItems.Add , , rngCell.Offset(0, 2).Value
End With
End If
Next rngCell
End Sub
Sub ListView41_DblClick()
Dim strName As String
Dim strEmail As String
Dim strEmail1 As String
Dim OutApp As Object
Dim OutMail As Object
Dim Singlepart As String
Dim SigString As String
Dim Signature As String
Dim strbody As String
Dim SigFilename
strName = ListView41.SelectedItem.Text
strEmail = ListView41.SelectedItem.ListSubItems(1).Text
strEmail1 = ListView41.SelectedItem.ListSubItems(2).Text
check = MsgBox("Send e-mail, To : " & strName & " - " & strEmail & "?" & vbNewLine & _
"CC : " & strEmail1, vbYesNo)
If check <> vbYes Then Exit Sub
Singlepart = MsgBox("For Single Part or Multiple Parts ? " & vbNewLine & vbNewLine & _
"Single Part = Yes" & vbNewLine & _
"Multiple Parts = No", vbYesNo)
If Singlepart = vbYes Then
' For Single Part Numbers
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = "<H3><B>Dear Customer Ron de Bruin</B></H3>" & _
"Please visit this website to download the new version.<br>" & _
"Let me know if you have problems.<br>" & _
"Ron's Excel Page" & _
"<br><br><B>Thank you</B>"
'Signature of User
SigString = Environ("appdata") & _
"\Microsoft\Signatures\Rohith UTAS.htm"
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
On Error Resume Next
Userform1.Show
'With Outlook
With OutMail
.Display
.To = strEmail
.CC = strEmail1
.BCC = ""
.Subject = strName & "_Request for Product Information"
.HTMLBody = strbody & vbNewLine & Signature
.Display 'or .Display if you want the user to view e-mail and send it manually
End With
Else
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Can you please help me on this.
Your variables you need to access on your form (I'm assuming strName, strEmail, and strEmail1) only have scope in Sub ListView41_DblClick(). If you need to use them in your form, you'll have to pass them as parameters (my preferred way to do it) or give them global scope.
A UserForm is a class, so you can give it properties like any other class - i.e. in UserForm1:
Private mEmail As String
Public Property Let Email(inputVal As String)
mEmail = inputVal
End Property
Public Property Get Email() As String
Email = mEmail
End Property
Then you would call it like any other object:
Dim nameless_form As UserForm1
Set nameless_form = New UserForm1
nameless_form.Email = strEmail
nameless_form.Show

Create mail with text in body

The first part of the code will not create the email ever since I added the strBody line and all.
I got the code from Ron de Bruin's site and added some things to it to adjust it for my needs.
Sub Send_Row()
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
'Don't forget to copy the function RangetoHTML in the module.
'Working in Excel 2000-2013
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Dim rng As Range
Dim Ash As Worksheet
Dim StrBody As String
Set Ash = ActiveSheet
On Error GoTo cleanup
Set OutApp = CreateObject("Outlook.Application")
StrBody = "Hello " & cel.Offset(, -1) & "<br>" & "<br>" & _
"We regret to inform you that there was an issue with the January interface file and your elections were not" & "<br>" & _
"processed correctly. In order to rectify this situation, we will issue new logs " & "<br>" & _
"you will not experience a big hit to time:" & "<br>" & "<br>" & _
"Please Check Proposed Adjustment Schedule below" & "<br>" & _
"Please contact ." & "<br>" & "<br>" & _
"Again, our sincere apologies for the mishaps with the interface file and any inconvenience this may have caused you." & "<br><br><br>"
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
For Each cell In Ash.Columns("B").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" _
And LCase(cell.Offset(0, 1).Value) = "yes" Then
'Change the filter range and filter Field if needed
'It will filter on Column B now (mail addresses)
Ash.Range("A1:J200").AutoFilter Field:=2, Criteria1:=cell.Value
With Ash.AutoFilter.Range
On Error Resume Next
Set rng = .SpecialCells(xlCellTypeVisible)
On Error GoTo 0
End With
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = cel.Offset(0, -1).Value
.Subject = "Benefits Deductions"
.HTMLBody = StrBody & RangetoHTML(rng)
.Display 'Or use .Send
End With
On Error GoTo 0
Set OutMail = Nothing
Ash.AutoFilterMode = False
End If
Next cell
cleanup:
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
On the first line of the StrBody = ..., you use a variable named cel, which seems to be undefined, this is probably what is throwing your program off.