So far i have got working a macro to send out emails to everyone in my excel list and it works fine except i need to add a couple more things to it:
1, Send the email to people ONLY if the date in Cells(r, 4).Value is between Today + 7 days and Today + 14 days otherwise skip that row.
2, If email has been sent change value of Cells(r, 20).Value from "False" to "True"
3, Skip rows were Cells(r, 20).Value is "True"
Heres how it loos so far:
Sub SetupAppointmentList()
' adds a list of appontments to the Calendar in Outlook
Dim olApp As Outlook.Application
Dim olAppItem As Outlook.AppointmentItem
Dim r As Long
DeleteNotices ' deletes previous test appointments
On Error Resume Next
Set olApp = GetObject("", "Outlook.Application")
On Error GoTo 0
If olApp Is Nothing Then
On Error Resume Next
Set olApp = CreateObject("Outlook.Application")
On Error GoTo 0
If olApp Is Nothing Then
MsgBox "Outlook is not available!"
Exit Sub
End If
End If
r = 10 ' first row with data in
While Len(Cells(r, 1).Formula) > 0
Set olAppItem = olApp.CreateItem(olAppointmentItem)
With olAppItem
.MeetingStatus = olMeeting
' set default appointment values
.Start = Now
.End = Now
.Subject = "No subject"
.Location = ""
.Body = ""
.ReminderSet = True
On Error Resume Next
.Recipients.Add Cells(r, 3).Value
.Recipients.ResolveAll
.Start = Cells(r, 4).Value + Cells(r, 5).Value
.End = Cells(r, 4).Value + Cells(r, 6).Value
.Subject = "Interview"
.Location = Cells(r, 13).Value + ", " + Cells(r, 14).Value
.Body = "Hi.... Blah Blah Blah"
.ReminderMinutesBeforeStart = 30
.Categories = "Notice"
On Error GoTo 0
.Save
.Display
'.Send
End With
r = r + 1
Wend
Set olAppItem = Nothing
Set olApp = Nothing
End Sub
Hope you can Help, Thanks in advance!
Rather than write the code for you here's what you do:
Get the content of Cells(r, 4) and use CDate to convert it to a date. Compare it to your start and end dates and if its in the range, continue.
Get content of (r, 20) and use CBool to get the bool value. Check and if OK continue.
After sending the email, just set Cells(r, 20) = true
Try that and see how it goes.
Related
I have code that works fine in all aspects, but I can not find a way to create a hyperlink in an Outlook appointment. The address is placed in column H in Excel, and I want to use VBA to export it to a certain calendar. Any help would greatly be appriciated.
My code is as follows:
Sub Appointments()
Const olAppointmentItem As Long = 1
Dim OLApp As Object
Dim OLNS As Object
Dim OLAppointment As Object
Dim miCalendario As Object
Dim r As Long
On Error Resume Next
Set OLApp = GetObject(, "Outlook.Application")
If OLApp Is Nothing Then Set OLApp = CreateObject("Outlook.Application")
On Error GoTo 0
If Not OLApp Is Nothing Then
Set OLNS = OLApp.GetNamespace("MAPI")
OLNS.Logon "Outlook"
b = 1
r = 2
Dim mysub, myStart, myEnd, mydes, myallday
While Len(Cells(r, 5).Text) <> 0
mysub = Cells(r, 7)
If Not Cells(r, 13).Value = 0 Then
mysub = mysub & "(s. " & Cells(r, 13).Value & ")" & vbCrLf
End If
'& ", " & Cells(r, 3)
myStart = DateValue(Cells(r, 1).Value) + Cells(r, 2).Value
myEnd = DateValue(Cells(r, 1).Value) + Cells(r, 3).Value
mydes = ""
Set miCalendario = OLApp.Session.GetDefaultFolder(9).Folders(ActiveSheet.Name)
Set OLAppointment = miCalendario.Items.Add(olAppointmentItem)
Dim olItems As Items
Dim olApptItem As Outlook.AppointmentItem
Set olItems = miCalendario.Items
Set olApptItem = miCalendario.Items.GetFirst
'add appointments
On Error Resume Next
With OLAppointment
.Subject = mysub
.Start = myStart
.End = myEnd
.Body = mydes
If Not Cells(r, 1).Value = 0 Then
If Not Cells(r, 8).Value = 0 Then
mydes = mydes & Cells(1, 8).Value & " - " & Cells(r, 8).Value & vbCrLf
End If
.Body = mydes
End If
.Location = Cells(r, 4).Value .Save
End With
r = r + 1
b = b + 1
Wend
Set OLAppointment = Nothing
Set OLNS = Nothing
Set OLApp = Nothing
End If
End Sub
You need to use .HTMLBody insted .Body
.HTMLbody = "link_Mask"
I hope it'll help
I am looking to send meeting invitations for each row in a worksheet.
I am able to create an item that when displayed shows as an appointment, not a meeting request that can be sent to others. I need to click on "Invite Attendees" in Outlook and then the email addresses display and I can send but it would take a lot of time if I have more than a few rows.
This seems to be a common problem as I found this question in other forums but none have a solution that worked for me.
Sub SendAction()
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
For Each cell In Worksheets("Action Log").Range("H5:H50").Cells
Set OutMail = OutApp.CreateItem(1)
If cell.Value Like "*#*" Then 'try with less conditions first
With OutMail
.MeetingStatus = olMeeting
.RequiredAttendees = Cells(cell.Row, "H").Value
.Subject = Cells(cell.Row, "I").Value
.Body = Cells(cell.Row, "I").Value
.Start = Cells(cell.Row, "E").Value & " " & TimeValue("8:00 AM")
.Location = "Your Office"
.Duration = 15 ' 15 minute meeting
.BusyStatus = 0 ' set as free
.ReminderSet = True 'reminder set
.ReminderMinutesBeforeStart = "20160" 'reminder 2 weeks before
.display
End With
Cells(cell.Row, "K").Value = "sent"
Set OutMail = Nothing
End If
Next cell
Application.ScreenUpdating = True
End Sub
Here is one alternative I tried but it did not fix the issue:
Application.Wait DateAdd("s", 2, Now) 'waiting for 2 sec to let OL window to display.
SendKeys "%s", True 'Sending Mail.
Set olApt = Nothing
MsgBox "Invite Sent", vbInformation
Source: https://excel-buzz.blogspot.com/2015/03/automation-sending-invitation-to.html
Another alternative is to change .Display to .Save but the .Send function won't work either way and I would then need to open the meeting request from my draft messages in Outlook.
Try this?
Sub SendAction()
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
For Each cell In Worksheets("Action Log").Range("H5:H50").Cells
Set OutMail = OutApp.CreateItem(1)
If cell.Value Like "*#*" Then 'try with less conditions first
With OutMail
.MeetingStatus = olMeeting
.RequiredAttendees = Cells(cell.Row, "H").Value
.RequiredAttendees.Type = olRequired
.Subject = Cells(cell.Row, "I").Value
.Body = Cells(cell.Row, "I").Value
.Start = Cells(cell.Row, "E").Value & " " & TimeValue("8:00 AM")
.Location = "Your Office"
.Duration = 15 ' 15 minute meeting
.BusyStatus = 0 ' set as free
.ReminderSet = True 'reminder set
.ReminderMinutesBeforeStart = "20160" 'reminder 2 weeks before
.display
.send
End With
Cells(cell.Row, "K").Value = "sent"
Set OutMail = Nothing
End If
Next cell
Application.ScreenUpdating = True
End Sub
I realized the issue. The cell I was linking to for the emails contained a formula instead of the email address text. Once I changed the email addresses to text instead of a formula my VBA worked perfectly.
I had the same problem as the OP but rather than resort to send keys I used the inspector to access the Invite Attendees ribbon command. Here are excerpts from the code:
Dim oApp As Object
Dim OutMail As Object
Dim oCommandBar As Object 'Office.CommandBars
Dim oInsp As Object 'Outlook.inspector
Set outMail = oApp.CreateItem(1)
'then these in the loop to get access to the ribbon:
Set oInsp = OutMail.GetInspector
Set oCommandBar = oInsp.CommandBars
'Show the mail item
outMail.display
'Press the Invite attendees ribbon item
oCommandBar.ExecuteMso ("InviteAttendees")
This should be straight-forward but I somehow can't get it right. I am trying to set-up an automatic email blast from Excel. I have followed step by step the instructions from other posts here, with no success. This is a dummy example I've created, for the sake of simplicity.
I would like to:
send emails to everybody in the list
conditionally replace certain keywords in the body
populate a column with the delivery status for each email (sent/failed)
My current code sends the email only to the first person in the list. I've used my personal email address for testing purposes. I wonder if sending the emails to the same address could be the issue. If anybody can provide some guidance, would be much appreciated!
Sub SendMail()
Dim EmailSent, EmailFailed, i As Integer
Dim StatusSent, StatusFailed As String
Dim olApp As Outlook.Application
Set olApp = CreateObject("Outlook.Application")
Dim olMail As Outlook.MailItem
Set olMail = olApp.CreateItem(olMailItem)
EmailSent = 0
EmailFailed = 0
StatusFailed = "failed"
StatusSent = "sent"
i = 1
Do
DoEvents
With olMail
.To = Cells(i, 1).Value
.Subject = "test"
.CC = ""
.BCC = ""
.Importance = olImportanceHigh
.BodyFormat = olFormatHTML
.HTMLBody = Cells(i, 2).Value
If Cells(i, 3) = 1 Then
.HTMLBody = VBA.Replace(olMail.HTMLBody, "replace_me", Cells(i, 4))
Else
.HTMLBody = VBA.Replace(olMail.HTMLBody, "replace_me", Cells(i, 5))
End If
.send
End With
On Error Resume Next
olMail.send
If Err Then
EmailFailed = EmailFailed + 1
ActiveSheet.Cells(i, 6).Value = StatusFailed 'change status from pending to failed
Else
EmailSent = EmailSent + 1
ActiveSheet.Cells(i, 6).Value = StatusSent 'change status from pending to sent
End If
i = i + 1
Loop Until i = Range(Range("A1"), Range("A1").End(xlDown)).Count
If EmailSent = 0 Then
MsgBox Prompt:="Emails could not be sent"
Else
MsgBox Prompt:="Sent emails: " & EmailSent & vbNewLine _
& "Failed emails: " & EmailFailed
End If
On Error GoTo 0
Set olApp = Nothing
Set olMail = Nothing
End Sub
You're missing two crucial lines in your Do loop:
Set olMail = olApp.CreateItem(olMailItem)
and at the end:
Set olMail = Nothing
Try this instead:
Sub SendMail()
Dim EmailSent, EmailFailed, i As Integer
Dim StatusSent, StatusFailed As String
Dim olApp As Outlook.Application
Set olApp = CreateObject("Outlook.Application")
Dim olMail As Outlook.MailItem
EmailSent = 0
EmailFailed = 0
StatusFailed = "failed"
StatusSent = "sent"
i = 1
Do
DoEvents
Set olMail = olApp.CreateItem(olMailItem)
With olMail
.To = Cells(i, 1).Value
.Subject = "test"
.CC = ""
.BCC = ""
.Importance = olImportanceHigh
.BodyFormat = olFormatHTML
.HTMLBody = Cells(i, 2).Value
If Cells(i, 3) = 1 Then
.HTMLBody = VBA.Replace(olMail.HTMLBody, "replace_me", Cells(i, 4))
Else
.HTMLBody = VBA.Replace(olMail.HTMLBody, "replace_me", Cells(i, 5))
End If
.send
End With
On Error Resume Next
olMail.send
If Err Then
EmailFailed = EmailFailed + 1
ActiveSheet.Cells(i, 6).Value = StatusFailed 'change status from pending to failed
Else
EmailSent = EmailSent + 1
ActiveSheet.Cells(i, 6).Value = StatusSent 'change status from pending to sent
End If
Set olMail = Nothing
i = i + 1
Loop Until i = Range(Range("A1"), Range("A1").End(xlDown)).Count
If EmailSent = 0 Then
MsgBox Prompt:="Emails could not be sent"
Else
MsgBox Prompt:="Sent emails: " & EmailSent & vbNewLine _
& "Failed emails: " & EmailFailed
End If
On Error GoTo 0
Set olApp = Nothing
End Sub
The code successfully sends the first email, but I am encountering an error on the second.
[Run-time error '-2147221238 (8004010a)': The item has been moved or deleted].
My goal is to use the button to automatically send reminder emails based on the criteria from the IF statements. The debug references the .To = Recipient line.
Private Sub CommandButton1_Click()
Dim objOutlook As Object
Dim objEmail As Object
Dim Row As Integer
Dim Recipient As String
Dim Requestor As String
Dim CQID As String
Dim lastRow As Long
Set objOutlook = CreateObject("Outlook.Application")
Set objEmail = objOutlook.CreateItem(olMailItem)
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
With objEmail
For Row = 2 To lastRow
If Cells(Row, 12).Value = "10" And IsEmpty(Cells(Row, 13).Value) = True Then 'Prepares and sends email after 10 days and no reminder has already been sent. The second constraint is to prevent multiple emails from being sent if the button is pressed multiple times in the day.
Recipient = Cells(Row, 14).Value
Requestor = Cells(Row, 15).Value
CQID = Cells(Row, 1).Value
.To = Recipient '<---Debug reference
.CC = Requestor
.Subject = "Update Requested for " & CQID
.Body = "Please send us an update on " & CQID
'.Display
.Send
Cells(Row, 13).Value = "1st Reminder Sent" 'Prepares constraint for second reminder
End If
If Cells(Row, 12).Value = "15" And Cells(Row, 13).Value = "1st Reminder Sent" Then
Recipient = Cells(Row, 14).Value
Requestor = Cells(Row, 15).Value
.To = Recipient
.CC = Requestor
.Subject = "Update Requested for " & CQID
.Body = "Please send us an update on " & CQID
'.Display
.Send
Cells(Row, 13).Value = "2nd Reminder Sent"
End If
Next Row
End With
Set objEmail = Nothing
Set objOutlook = Nothing
End Sub
Any help with the direct issue or suggestions for general improvements are greatly appreciated.
No need for second set objEmail to Creates a new Outlook item, simply move it inside your loop
Dim Row As Long
For Row = 2 To lastRow
Dim objEmail As Object
Set objEmail = objOutlook.CreateItem(0)
Also its very impotent to specify the workbook or worksheet in the code when referencing Cells(Row
Example
Option Explicit
Private Sub CommandButton1_Click()
Dim objOutlook As Object
Set objOutlook = CreateObject("Outlook.Application")
Dim Sht As Worksheet
Set Sht = ThisWorkbook.Worksheets("Sheet1")
With Sht
Dim lastRow As Long
lastRow = .Cells(Rows.Count, 1).End(xlUp).Row
Dim Row As Long
For Row = 2 To lastRow
Dim objEmail As Object
Set objEmail = objOutlook.CreateItem(0)
If Sht.Cells(Row, 12).Value = "10" And _
IsEmpty(Sht.Cells(Row, 13).Value) = True Then
Dim Recipient As String
Dim Requestor As String
Dim CQID As String
With objEmail
Recipient = Sht.Cells(Row, 14).Value
Requestor = Sht.Cells(Row, 15).Value
CQID = Sht.Cells(Row, 1).Value
.To = Recipient
.CC = Requestor
.Subject = "Update Requested for "
.Body = "Please send us an update on "
.Display
' .Send
Sht.Cells(Row, 13).Value = "1st Reminder Sent"
End With '<-email
Else
If Sht.Cells(Row, 12).Value = "15" And _
Sht.Cells(Row, 13).Value = "1st Reminder Sent" Then
With objEmail
Recipient = Sht.Cells(Row, 14).Value
Requestor = Sht.Cells(Row, 15).Value
.To = Recipient
.CC = Requestor
.Subject = "Update Requested for " & CQID
.Body = "Please send us an update on " & CQID
.Display
' .Send
Sht.Cells(Row, 13).Value = "2nd Reminder Sent"
End With '<-email
End If
End If
Next Row
End With '<-sht
Set objEmail = Nothing
Set objOutlook = Nothing
End Sub
See fully qualified examples
Below is code I have written to automate sending meeting invites.
The code picks content from cells in sheet: Final_List.
I have highlighted where I'm getting an error when I try get the recipient address from Excel
Application -defined or object - defined error.
Dim outlookApp As Outlook.Application
Dim outlookmeet As AppointmentItem
Dim myRequiredAttendee As Recipient
Dim sh As Worksheet
Dim RowCount As Long
RowCount = 2
'row 1 has headers
With Worksheets("Final_List")
Do While IsEmpty(Cells(RowCount, 1).Value) = False
Set outlookApp = CreateObject("Outlook.Application")
Set outlookmeet = outlookApp.CreateItem(olAppointmentItem)
With outlookmeet
.MeetingStatus = olMeeting
.Subject = Cells(RowCount, 1).Value & " - " & Cells(RowCount, 2).Value
.Location = Cells(RowCount, 3).Value
.Start = Cells(RowCount, 5).Value
.Duration = Cells(RowCount, 7).Value
'getting errors on this line
.Recipients.Add (Cells(RowCount, 6).Value)
.Recipients.ResolveAll
.Body = Cells(RowCount, 4).Value
.Send
End With
RowCount = RowCount + 1
Loop
End With
Set outlookmeet = Nothing
Set outlookApp = Nothing
MsgBox "All invites sent!"
The AppointmentItem object doesn't have a Recipient property. Compare MSDN library
I got this solution:
Sub ScheduleMeeting()
Dim outlookApp As Outlook.Application
Dim outlookmeet As Outlook.AppointmentItem
Dim RowCount As Long
Dim Name1 As Variant
RowCount = 2
'row 1 has headers
Worksheets("MeetingInvite").Activate
With Worksheets("MeetingInvite")
Do While IsEmpty(Cells(RowCount, 1).Value) = False
Set outlookApp = CreateObject("Outlook.Application")
Set outlookmeet = outlookApp.CreateItem(olAppointmentItem)
With outlookmeet
.MeetingStatus = olMeeting
.Subject = Cells(RowCount, 1).Value
.Location = Cells(RowCount, 2).Value
.Start = Cells(RowCount, 4).Value
.Duration = Cells(RowCount, 6).Value
.RequiredAttendees = Cells(RowCount, 5).Value
.Body = Cells(RowCount, 3).Value
.Display
End With
RowCount = RowCount + 1
Loop
End With
Set outlookmeet = Nothing
Set outlookApp = Nothing
'MsgBox "All invites sent!"
End Sub