I need to send reminders 7 days before a certain deadline.
With help I managed to create this code:
Private Sub Workbook_Activate()
Dim i As Long
Dim OutApp, OutMail As Object
Dim strto, strcc, strbcc, strsub, strbody As String
Set OutApp = CreateObject("Outlook.Application")
OutApp.Session.Logon
Set OutMail = OutApp.CreateItem(0)
For i = 2 To Range("e65536").End(xlUp).Row
If Cells(i, 9) <> "Y" Then
If Cells(i, 5) - 7 < Date Then
strto = Cells(i, 7).Value 'email address
strsub = Cells(i, 1).Value & " " & Cells(i, 2).Value & " compleanno il " & Cells(i, 5).Value 'email subject
strbody = "Il compleanno di " & Cells(i, 1).Value & " " & Cells(i, 2).Value & " sarà il " & Cells(i, 5).Value & vbNewLine 'email body
With OutMail
.To = strto
.Subject = strsub
.Body = strbody
.Send
End With
Cells(i, 8) = "Mail Sent " & Now()
Cells(i, 9) = "Y"
End If
End If
Next
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
I have to start it manually every day because even if the deadline is updated the macro doesn't restart by itself.
I tried replacing Sub Workbook_Activate() with Sub Workbook_SelectionChange(ByVal Target As Range).
Related
I am trying to create a macro to send automated reminders.
I am sending below the two macros:
Sub Auto_Open()
Dim vResp As Variant, dTime As Date
vResp = MsgBox("Inviare email ora?", vbYesNo)
If vResp = 6 Then 'YES
Call EmailReminder
ElseIf vResp = 7 Then 'NO
dTime = CDate(InputBox("Send email at:", , Time + TimeValue("00:00:10")))
Do Until Time = dTime 'OR = #8:00:00 AM#
DoEvents
Loop
Call EmailReminder
End If
End Sub
Sub EmailReminder()
Dim oOL As Outlook.Application, oMail As Outlook.MailItem, oNS As Outlook.Namespace
Dim oMapi As Outlook.MAPIFolder, oExpl As Outlook.Explorer
Dim sBody As String, dDate As Date
Dim oWS As Worksheet, r As Long, i As Long, sStart As String
Set oWS = Foglio1
Set oOL = New Outlook.Application
Set oExpl = oOL.ActiveExplorer
If TypeName(oExpl) = "Nothing" Then
Set oNS = oOL.GetNamespace("MAPI")
Set oMapi = oNS.GetDefaultFolder(olFolderInbox)
Set oExpl = oMapi.GetExplorer
End If
With oWS.Range("E1")
r = .CurrentRegion.Rows.Count
For i = 1 To r
dDate = .Cells(i, 1)
sBody = "Oggi è il compleanno di" & .Cells(i, 2) & dDate & .Cells(i, -4) & " " & .Cells(i, -3) & vbCrLf & "Facciamo i nostri auguri!"
If Date = dDate Or Date = Int(dDate) Then ' Use INT to eliminate time info
Set oMail = oOL.CreateItem(oIMailItem)
With oMail
.Recipients.Add "umberto.roselli#openfiber.it" 'Indirizzo ricevente
.Subject = "Nuovo compleanno oggi:" & .Cells(i, -4) & " " & .Cells(i, -3) & .Body = sBody: .Send
End With
End If
Next i
End With
MsgBox "Messaggio email inviato correttamente!"
End Sub
I keep getting, however, on the second macro the error Run-Time 13: Type not matching but it doesn't give me any indication where the error is.
Can you help me out?
Thank you very much in advance
Fyi
Private Sub Workbook_Open()
Dim i As Long
Dim OutApp, OutMail As Object
Dim strto, strcc, strbcc, strsub, strbody As String
Set OutApp = CreateObject("Outlook.Application")
OutApp.Session.Logon
Set OutMail = OutApp.CreateItem(0)
For i = 2 To Range("e65536").End(xlUp).Row
If Cells(i, 8) <> "Y" Then
If Cells(i, 5) - 7 < Date Then
strto = Cells(i, 7).Value 'email address
strsub = Cells(i, 1).Value & " " & Cells(i, 2).Value & " compleanno il " & Cells(i, 5).Value 'email subject
strbody = "Il compleanno di " & Cells(i, 1).Value & " " & Cells(i, 2).Value & " sarà il " & Cells(i, 5).Value & vbNewLine 'email body
With OutMail
.To = strto
.Subject = strsub
.Body = strbody
.Send
End With
Cells(i, 8) = "Mail Sent " & Now()
Cells(i, 9) = "Y"
End If
End If
Next
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
I need help with the code to send emails only once a day.
When the file is opened, the code is set to automatically send emails and is based on due date. However, this file can be opened multiple times throughout the course of the day. I need it to only send an email once a day (1st time the file is opened) but I can't figure how to correctly code it.
For i = 2 To lRow
If Cells(i, 8).Value <> "Completed" Then
If Cells(i, 2) <> "" Then
toDate = Replace(Cells(i, 5), ".", "/")
If Left(Cells(i, 18), 5) <> "Mail" And toDate - Date <= 7 Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
toList = Cells(i, 7)
eSubject = "ACTION ITEM - " & Cells(i, 3) & " is due on " & Cells(i, 5)
eBody = "NOTICE for " & Cells(i, 6) & vbCrLf & vbCrLf & "This is a reminder that you have task(s) that are due or ones that are past due. Please complete your tasks as soon as possible, then notify the Quality Administrator when the task is complete."
On Error Resume Next
With OutMail
.To = toList
.CC = ""
.BCC = ""
.Subject = eSubject
.Body = eBody
.bodyformat = 1
'.Display
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
Cells(i, 9) = "Mail Sent " & Date + Time
End If
End If
End If
Next i
Like this:
For i = 2 To lRow
If Cells(i, 8).Value <> "Completed" And _
Cells(i, 2) <> "" And _
Cells(i, 9) <> Date Then
'send the mail
Cells(i, 9) = Date '<<< store the date sent
End If
Next i
The following code works to send emails 7 days on or before the past due date but in order for it to run, it needs to be assigned to a button within Excel. When the file is opened, I want it to run the code automatically and send emails to those that have upcoming or overdue tasks. It needs to stop sending emails where tasks have been marked "Completed".
Sub eMail()
Dim lRow As Integer
Dim i As Integer
Dim toDate As Date
Dim toList As String
Dim eSubject As String
Dim eBody As String
With Application
.ScreenUpdating = False
.EnableEvents = False
.DisplayAlerts = False
End With
Sheets(1).Select
lRow = Cells(Rows.Count, 5).End(xlUp).Row
Set OutApp = CreateObject("Outlook.Application")
For i = 2 To lRow
If Cells(i, 5) <> "" Then
toDate = Replace(Cells(i, 5), ".", "/")
If Left(Cells(i, 18), 5) <> "Mail" And toDate - Date <= 7 Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
toList = Cells(i, 7)
eSubject = "ACTION ITEM - " & Cells(i, 3) & " is due on " & Cells(i, 5)
eBody = "NOTICE for " & Cells(i, 6) & vbCrLf & vbCrLf & "You have task(s)coming due or ones that are past due. Please complete your tasks as soon as possible, then notify the Quality Administrator when the task is complete."
On Error Resume Next
With OutMail
.To = toList
.CC = ""
.BCC = ""
.Subject = eSubject
.Body = eBody
.bodyformat = 1
'.Display
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
Cells(i, 9) = "Mail Sent " & Date + Time
End If
End If
Next i
ActiveWorkbook.Save
With Application
.ScreenUpdating = True
.EnableEvents = True
.DisplayAlerts = True
End With
End Sub
inside of your loop, put an if statement... fix the cell reference:
For i = 2 To lRow
If Cells(i,1).value <> "Completed" Then 'could also use Not Cells(i,1).value = "Completed"
'all of your regular code
End If
Next i
Edit1:
Update to use your code:
For i = 2 To lRow
If Cells(i,1).value <> "Completed" Then 'OPEN IT HERE
If Cells(i, 5) <> "" Then
toDate = Replace(Cells(i, 5), ".", "/")
If Left(Cells(i, 18), 5) <> "Mail" And toDate - Date <= 7 Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
toList = Cells(i, 7)
eSubject = "ACTION ITEM - " & Cells(i, 3) & " is due on " & Cells(i, 5)
eBody = "NOTICE for " & Cells(i, 6) & vbCrLf & vbCrLf & "You have task(s)coming due or ones that are past due. Please complete your tasks as soon as possible, then notify the Quality Administrator when the task is complete."
On Error Resume Next
With OutMail
.To = toList
.CC = ""
.BCC = ""
.Subject = eSubject
.Body = eBody
.bodyformat = 1
'.Display
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
Cells(i, 9) = "Mail Sent " & Date + Time
End If
End If
End If 'CLOSE IT HERE
Next i
A second way of doing it, with your existing If statement:
For i = 2 To lRow
If Cells(i, 5) <> "" Or Cells(i,1).value <> "Completed" Then
toDate = Replace(Cells(i, 5), ".", "/")
If Left(Cells(i, 18), 5) <> "Mail" And toDate - Date <= 7 Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
toList = Cells(i, 7)
eSubject = "ACTION ITEM - " & Cells(i, 3) & " is due on " & Cells(i, 5)
eBody = "NOTICE for " & Cells(i, 6) & vbCrLf & vbCrLf & "You have task(s)coming due or ones that are past due. Please complete your tasks as soon as possible, then notify the Quality Administrator when the task is complete."
On Error Resume Next
With OutMail
.To = toList
.CC = ""
.BCC = ""
.Subject = eSubject
.Body = eBody
.bodyformat = 1
'.Display
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
Cells(i, 9) = "Mail Sent " & Date + Time
End If
End If
Next i
I need to send an email with Excel with two conditions.
Cell D2 must be >= 1
Cell E2 must be ="".
I've the first condition done, but not the second one
The code is:
'PRAZO Etapa 4
Public Sub EnviarEmailEt4()
Dim OutApp As Object
Dim OutMail As Object
Dim Body As String
Worksheets("Incidentes2019").Select
Range("D4").Select
Do While ActiveCell.Value <> ""
If ActiveCell >= 1 And ActiveCell.Offset(0, 1) = "" And InStr(2, Cells(ActiveCell.Row, 10), "#") > 0 Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = Cells(ActiveCell.Row, 10).Value
.CC = Cells(ActiveCell.Row, 11).Value
.BCC = ""
.Subject = Cells(ActiveCell.Row, 3).Value
If (ActiveCell = 1) Or (ActiveCell = 2) Then
.Body = "ALERTA PRAZO ETAPA 4!!" & vbNewLine & vbNewLine & "Nº GQE " & Cells(ActiveCell.Row, 2).Value & " - " & Cells(ActiveCell.Row, 3).Value
ElseIf (ActiveCell >= 3) Then
.Body = "ULTRAPASSADO PRAZO ETAPA 4!!" & vbNewLine & vbNewLine & "Nº GQE " & Cells(ActiveCell.Row, 2).Value & " - " & Cells(ActiveCell.Row, 3).Value
End If
.Send 'Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
MsgBox "Alerta Etapa 4 enviado - " & Format(Now, "HH:MM") & vbNewLine & Cells(ActiveCell.Row, 3).Value
End If
Cells(ActiveCell.Row + 1, ActiveCell.Column).Select
Loop
End Sub
Try this, you can check in a loop outside the mail procedure if the cells meet your criteria, if so then you send the mail:
Option Explicit
Sub SendingMails()
Dim ws As Worksheet 'always declare worksheets and workbooks to avoid using select
Dim SendTo As String, SendSubject As String, FirstData As String, SecondData As String 'here, variables for the items to fill on your mail
Dim LastRow As Long, i As Long 'Here you have the lastrow of the worksheet and another variable for a loop
Set ws = ThisWorkbook.Sheets("Sheet1") 'Change Sheet1 for the name of the sheet where you keep the data
With ws
LastRow = .Cells(.Rows.Count, 4).End(xlUp).Row 'this will check the last row with data on the column 4 (D)
For i = 2 To LastRow 'starting from row 2 to the last one with data
If .Cells(i, 4) >= 1 And .Cells(i, 5) <> vbNullString Then 'here you check if column D cell has 1 or higher and if column E cell is empty
SendTo = .Cells(i, 10)
SendSubject = .Cells(i, 3)
FirstData = .Cells(i, 2)
SecondData = .Cells(i, 3)
Call EnviarEmailEt4(SendTo, SendSubject, FirstData, SecondData)
End If
Next i
End With
End Sub
Sub EnviarEmailEt4(SendTo As String, SendSubject As String, FirstData As String, SecondData As String)
'as you can see above, i've declared variables inside the procedure which will be taken from the previous one
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = SendTo
.CC = ""
.BCC = ""
.Subject = SendSubject
.Body = "ALERTA FIM DE PRAZO ETAPA 4!!" & vbNewLine & vbNewLine & "Nº GQE " & FirstData & " - " & SecondData
'.Attachments.Add ActiveWorkbook.FullName 'Anexar este ficheiro
'.Attachments.Add ("") 'Anexar outro ficheiro
.send 'Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
MsgBox " Alerta Et4 enviado - " & Format(Now, "HH:MM") 'I Would avoid alerting in each loop if there are lots of mails
End Sub
You can select cell on the right (like pressing the arrow in excel) using Range.offset() property. Try to change your IF statement to the following:
If ActiveCell >= 1 And ActiveCell.Offset(0, 1) <> "" Then
EDIT:
in response to the change in your question: here is a working approach to set mailbody based on the activecell value:
If (ActiveCell = 1) Or (ActiveCell = 2) Then
MailBody = "ALERTA PRAZO ETAPA 4!!" & vbNewLine & vbNewLine & "Nº GQE " & Cells(ActiveCell.Row, 2).Value & " - " & Cells(ActiveCell.Row, 3).Value
ElseIf (ActiveCell >= 3) Then
MailBody = "ULTRAPASSADO PRAZO ETAPA 4!!" & vbNewLine & vbNewLine & "Nº GQE " & Cells(ActiveCell.Row, 2).Value & " - " & Cells(ActiveCell.Row, 3).Value
End If
I have a vba code which generates a outlook email, populates with required To, CC, Subject and Body when i change a particular column in excel. And when the email is sent my status column updates to 'Closed' and Email Sent Flag column updates to '1'.
But the problem is when i click on close instes on Send on my email( which was generated and auto populated) even then my status and Email sent flag column gets updated with Closed and 1 respectively. Below is my code.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim xOutApp As Object
Dim xMailItem As Object
Dim xMailBody As String
Dim html As String
Dim intR As String
Dim ccStr As String
Dim Signature As String
Dim html1 As String
'Dim itmevt As New CMailItemEvents
'Dim tsp As String
lRow = Cells(Rows.Count, 17).End(xlUp).Row
lRow1 = ThisWorkbook.Sheets("Validation Lists").Cells(Rows.Count, 4).End(xlUp).Row
html = "<br>" & ("Hi,") & ("Please spare some time to provide feedback for our service. This will help us to serve you better for upcoming services.") & "<br>"
For i = 2 To lRow1
ccStr = ";" & ThisWorkbook.Sheets("Validation Lists").Cells(i, "D").Value & ccStr
Next i
For i = 1 To lRow
If (Cells(i, "Q").Value = "Closed") And (Cells(i, "R").Value <> "1") Then
intR = MsgBox("Do you want to send a feedback for " & Cells(i, "B") & "Viz." & Cells(i, "C").Value & " to " & Cells(i, "C") & "?", vbQuestion + vbYesNo)
If intR = vbYes Then
Set xOutApp = CreateObject("Outlook.Application")
Set xMailItem = xOutApp.CreateItem(0)
With xMailItem
.To = Cells(i, "I").Value
.CC = ccStr
.display
Signature = .HTMLBody
.Subject = "Feedback for " & Cells(i, "B").Value & " viz. " & Cells(i, "C").Value
.HTMLBody = html & "This request was assited by " & Cells(i, "K").Value & "<br><br>" & Signature
'.dispaly
'.Send
End With
Cells(i, "R").Value = "1"
Set xRgSel = Nothing
Set xOutApp = Nothing
Set xMailItem = Nothing
On Error Resume Next
End If
If intR = vbNo Then Cells(i, "Q").Value = "In Progress"
End If
Next i
End Sub
You have to check if the message has been sent.
There exists a boolean message property named Sent.
Untested but could work:
Loop until .Sent is True.
With xMailItem
.To = Cells(i, "I").Value
.CC = ccStr
.display
Signature = .HTMLBody
.Subject = "Feedback for " & Cells(i, "B").Value & " viz. " & Cells(i, "C").Value
.HTMLBody = html & "This request was assited by " & Cells(i, "K").Value & "<br><br>" & Signature
Do Until .Sent = True
DoEvents
Loop
End With