Create Outlook appointment in specific Calendar from Excel - excel

I am trying to create three Outlook appointments in a specific (shared) calendar.
The events will be all-day events. I want the dates for the current row to be added to the calendar. All three dates will be in the same row on the spreadsheet.
The code creates the appointment but the for loop is not working. The only event that is created is the last date.
Sub Makeapt()
Set myOutlook = CreateObject("Outlook.Application")
Set myApt = myOutlook.createitem(1)
Dim i As Integer
For i = 3 To 5
myApt.Subject = Cells(ActiveCell.Row, 1).Value
myApt.Start = Cells(ActiveCell.Row, i).Value
myApt.Save
Next i
End Sub
I solved the problem. Appt still goes to the default calendar, but that is actually preferable.
Sub Makeapt()
Dim warning
warning = MsgBox("You are about to create Outlook appointments for subject #" & Cells(ActiveCell.Row, 3) & ". Is that right?", vbOKCancel)
If warning = vbCancel Then Exit Sub
Set myOutlook = CreateObject("Outlook.Application")
Set ID = Cells(ActiveCell.Row, 3)
Dim i As Integer
For i = 7 To 9
Set myApt = myOutlook.createitem(1)
myApt.Subject = "Subject #" & ID
myApt.Start = Cells(ActiveCell.Row, i).Value
myApt.Save
Next i
End Sub

Dmitry nailed it for how to create an appointment/meeting in a shared calendar from Excel. His post was a big help to me as it seems there are not any very good answers to how to create an appointment on a shared calendar. I looked all over numerous forums to get answers and came up with very little. Based on his answer, I was able to get it working. Below is an example script I put together. This is a somewhat stripped-down version of what I am using for my needs, but I did test this example and it works. Just make sure the Outlook library is selected in the Excel VBA editor's Tools->References menu item.
Sub SendInvitationAsUser()
Rcpts = "user#test.com; user2#test.com, etc#test.com" ' These can be in other formats that Outlook understands like display name.
Subject = "Meeting sent from shared calendar"
' Creates Outlook instance
Set OutApp = CreateObject("Outlook.Application")
Dim myNamespace As Outlook.Namespace
Dim myRecipient As Outlook.Recipient
Dim objfolder As Outlook.Folder
Set myNamespace = OutApp.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("Smith, John Q") 'The invite will come from this user's mailbox
myRecipient.Resolve
If myRecipient.Resolved Then
Set objfolder = myNamespace.GetSharedDefaultFolder(myRecipient, olFolderCalendar) 'Sets folder where appt will be created
Else
ok = MsgBox("Unable to resolve the name of the sender.", vbCritical, "Error")
Exit Sub
End If
Set OutlookAppt = objfolder.Items.Add(olAppointmentItem) 'Creates appointment in shared calendar
' Edit Outlook appointment, convert to meeting invitation by adding recipients.
With OutlookAppt
.MeetingStatus = olMeeting
.Subject = Subject
.Start = #1/1/2018 8:00:00 AM#
.End = #1/1/2018 9:00:00 AM#
.Location = "Conference Room 1"
.RequiredAttendees = Rcpts
End With
'Use Word to do fancy formatting of body text. Example below is basic but a lot of formatting via VBA is possible.
Set WordApp = CreateObject("Word.Application")
Set WordDoc = WordApp.Documents.Add
Set DocSelection = WordApp.Selection
WordApp.Visible = True
WordDoc.Activate ' You want to see the window, right?
DocSelection.Font.Name = "Arial" ' Everything is Arial.
DocSelection.Font.Size = "10" ' Everything is size 10.
DocSelection.ParagraphFormat.SpaceAfter = "0" ' No line spacing.
DocSelection.ParagraphFormat.SpaceBefore = "0" ' No line spacing.
DocSelection.TypeText ("Please plan to attend my meeting.")
WordDoc.Content.Copy
OutlookAppt.Display
Set TargetApptDoc = OutlookAppt.GetInspector.WordEditor
TargetApptDoc.Range(0, 0).Paste
WordDoc.Close savechanges:=False
WordApp.Quit
End Sub

If you want a shared calendar, create a recipient object using Application.CreateRecipient, open the shared calendar using Application.Session.GetSharedDefaultFolder, create an appointment using MAPIFolder.Items.Add.

Related

Bulk send Emails based on VBA Filtered Table from Excel

I frequently have to send out emails to various contractors to check in on the statuses of the projects I have bid with them. Currently I have to enter the name of each Rep in reference cell and then execute the macro but I deal with dozens of reps. I would like to be able to send an bulk email blast out to all the reps whose projects are still "Open" with one macro instead of having to change the reps name each time. Also, I tried to use the automatic .send function but cannot get it to work and I would hope to not have to keep using the .display for this situation for obvious reasons.
Sub EmailGCs_1()
'Declare Outlook Variables
Dim oLookApp As Outlook.Application
Dim oLookItm As Outlook.MailItem
Dim oLookIns As Outlook.Inspector
'Declare Word Variables
Dim oWrdDoc As Word.Document
Dim oWrdRng As Word.Range
Dim oWrdTble As Word.Table
'Declare Excel Variables
Dim ExcTbl As ListObject
On Error Resume Next
'Get The Active instance of Outlook, if there is one.
Set oLookApp = GetObject(, "Outlook. Application")
'If ther is no active instance create one
If Err.Number = 429 Then
'Create a new instance
Set oLookApp = New Outlook.Application
End If
'Create a new Email
Set oLookItm = oLookApp.CreateItem(olMailItem)
'Create a refernce to the table
Set Exltbl = ActiveSheet.ListOjects(1)
With oLookItm
'Basic Info
.To = Range("D2").Value
.Subject = "Various Project Statuses"
'Display Email
.Display
'Get The Inspector
Set oLookIns = .GetInspector
'Get the Word Editor
Set oWrdDoc = oLookIns.WordEditor
'Filter Table to Distro
ActiveSheet.Range("Table1").AutoFilter field:=6, Criteria1:=Cells(1, 6).Value
'Hide Columns
Range("G:R").EntireColumn.Hidden = True
'Copy Items
Worksheets(1).ListObjects("Table1").Range.Copy
oWrdDoc.Range(1, 2).Paste
'Greeting Text
MsgText = Split(Range("F1").Value, " ")(0) & "," & vbNewLine & "Can you please let me know the statuses of the projects below." & vbNewLine
oWrdDoc.Range.InsertBefore Text:=MsgText
'Clearing out filter and selection
ActiveSheet.ListObjects(1).AutoFilter.ShowAllData
Application.CutCopyMode = False
Range("G:R").EntireColumn.Hidden = False
End With
Set oLookItm = Nothing
Set oLookApp = Nothing
Application.ScreenUpdating = True
End Sub
The Send method is not safe and the Outlook object model may trigger security prompts or give errors when Outlook is automated from an external application. Possible workarounds are listed below:
Create a COM add-in which deals with a safe Application instance which doesn't trigger security prompts.
Use a low-level code on which Outlook is built on and which doesn't have security riggers onboard. Or may also consider any other third-party wrappers around that API, for example, Redemption.
Use a third-party components for suppressing Outlook security warnings. See Security Manager for Microsoft Outlook for more information.
Use group policy objects for setting up machines.
Install any AV software with latest updates.
Here is one way to loop through a list.
Source: Sending Email to a List of Recipients Using Excel and Outlook
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Sub EmailGCs_2()
' Early binding requires reference to Microsoft Outlook XX.X Object Library
' Declare Outlook variables
Dim oLookApp As Outlook.Application
Dim oLookItm As Outlook.MailItem
Dim iCounter As Long
'Application.ScreenUpdating = False
'There can only be one instance of Outlook
' GetObject is not needed.
' The problematic On Error Resume Next can be dropped
Set oLookApp = New Outlook.Application
'Subsequent errors would have been bypassed
' due to the missing On Error GoTo 0
'If there are any errors you can fix them now.
'Assumes a list of email addresses in column D starting at cell D2
' https://learn.microsoft.com/en-us/office/vba/excel/concepts/working-with-other-applications/sending-email-to-a-list-of-recipients-using-excel-and-outlook
'Debug.Print WorksheetFunction.CountA(Columns(4)) + 1
For iCounter = 2 To WorksheetFunction.CountA(Columns(4)) + 1
'Debug.Print iCounter
'Create a new Email
Set oLookItm = oLookApp.CreateItem(olMailItem)
With oLookItm
'Basic Info
.To = Cells(iCounter, 4).Value
.Subject = "Various Project Statuses"
'Display Email
.Display
End With
Set oLookItm = Nothing
Next
Set oLookItm = Nothing
Set oLookApp = Nothing
Application.ScreenUpdating = True
Debug.Print "Done."
End Sub

Tracking Replies to Outlook Emails

I am trying to create a list on excel to track which of my selected sent outlook emails (moved to a particular sub folder, "Test") have been replied. For emails which have not been replied, I would like to send a reminder email after a few days. Would it be possible to create an outlook VBA macro to do this?
Currently, my VBA code is only able to pull selected email details in a tracking file.
I know that to track conversations, the PR_CONVERSATION_INDEX should be used, but am not sure how to incorporate it into my code below.
Sub List_Email_Info()
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim i As Long ' Row tracker
Dim arrHeader As Variant
Dim olNS As NameSpace
Dim olSentFolder As MAPIFolder
Dim olItems As Items
Dim olMailItem As MailItem
Dim olRecipients As Outlook.Recipients
arrHeader = Array("Date Created", "Subject", "Recipient's Name")
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
Set xlWB = xlApp.Workbooks.Add
Set olNS = GetNamespace("MAPI")
Set olSentFolder = olNS.GetDefaultFolder(olFolderSentMail).Folders("test")
Set olItems = olSentFolder.Items
i = 1
On Error Resume Next
xlWB.Worksheets(1).Range("A1").Resize(1, UBound(arrHeader) + 1).Value = arrHeader
For Each olMailItem In olItems
xlWB.Worksheets(1).Cells(i + 1, "A").Value = olItems(i).CreationTime
xlWB.Worksheets(1).Cells(i + 1, "B").Value = olItems(i).Subject
xlWB.Worksheets(1).Cells(i + 1, "C").Value = olItems(i).To
i = i + 1
Next olMailItem
xlWB.Worksheets(1).Cells.EntireColumn.AutoFit
MsgBox "Export complete.", vbInformation
Set xlWB = Nothing
Set xlApp = Nothing
Set olItems = Nothing
Set olSentFolder = Nothing
Would appreciate any help on this!
==========================================================================
Current code is adapted from: https://learndataanalysis.org/pull-outlook-emails-detail-into-excel-using-vba/
As this is not a programming service where ready to run code is served, I'd suggest you do like this:
When an email is received and moved, you set a calendar appointment in VBA when to send the reminder if no reply has been received.
https://learn.microsoft.com/en-us/office/vba/outlook/how-to/items-folders-and-stores/create-an-appointment-as-a-meeting-on-the-calendar
You also set a trigger for it in VBA and let the action be to resend the email:
Use calendar appointment in outlook to trigger VBA macro
If a reply is received you delete that particular calendar time:
https://learn.microsoft.com/en-us/office/vba/api/outlook.appointmentitem.delete
Otherwise the calendar trigger will send the email reminder.
To do it this way uses built-in resources in Outlook so you don't have to write them yourself.

How to create a hyperlink in an Outlook appointment?

I am trying to add a formatted value, from Excel to an appointment in Outlook, based on:
HTMLBody Workaround For OlAppointment Object?
I get the following error:
"Run-time error '287': Application-defined or object-defined error"
I also need to create a hyperlink in an appointment, using link in one cell and text I want to be visible in another.
Sub MakeApptWithRangeBody()
Dim olApp As Outlook.Application
Dim olApt As Outlook.AppointmentItem
Const wdPASTERTF As Long = 1
Set olApp = Outlook.Application
Set olApt = olApp.CreateItem(olAppointmentItem)
With olApt
.Start = Now + 1
.End = Now + 1.2
.Subject = "Test Appointment"
.Location = 18
'Sheet1.ListObjects(1).Range.Copy
ThisWorkbook.Worksheets("Sheet1").Range("D2").Copy
.Display
.GetInspector.WordEditor.Windows(1).Selection.PasteAndFormat wdPASTERTF
End With
End Sub
I think you are getting this error because of security settings in Outlook which is generally controlled by the IT Administrators in any organization if you are using an official Outlook Email account
you could try below
.Body = ThisWorkbook.Worksheets("Sheet1").Range("D2").Value
in place of
ThisWorkbook.Worksheets("Sheet1").Range("D2").Copy
and remove the below line
.GetInspector.WordEditor.Windows(1).Selection.PasteAndFormat wdPASTERTF
You also need to activate the "Microsoft Word Object Library" in the references. Outlook is using Word as editor and this line of code
.GetInspector.WordEditor.Windows(1).Selection.PasteAndFormat wdPASTERTF
is using Word VBA code (in the editor). So you need the Word reference too not only the one for Outlook.
To create a hyperlink you can check the Hyperlinks.Add method which should work (not tested):
With olApt
.Start = Now + 1
.End = Now + 1.2
.Subject = "Test Appointment"
.Location = 18
'Sheet1.ListObjects(1).Range.Copy
ThisWorkbook.Worksheets("Sheet1").Range("D2").Copy
.Display
Dim Sel As Object
Set Sel = .GetInspector.WordEditor.Windows(1).Selection
Sel.PasteAndFormat wdPASTERTF
Sel.Hyperlinks.Add Anchor:=Sel.Range, Address:="http:\\www.microsoft.com"
End With

MailItem.Send in VBA not functioning since Office 365 upgrade

We send out a lot of spreadsheets around the organisation, in order to automate this as much as possible we wrote some code to send this automatically and allow us to still put body text in.
This particular Script picks information up from our Finance System (SAP) dumps it into Excel and emails it to the user, it loops through a number times downloading and emailing different data each time.
This works fine on our old windows 7 (Office 2010) machines but some of us have been given new Windows 10 (Office 365) machines to pilot.
The code runs without any error messages but when it gets to .Send it jumps straight to End Sub and does not send the email.
I have tried EmailItem.Display and you can see the email being populated and then just stays visible on the desktop as it loops through the rest of the emails.
Any ideas on how to get round this? I could use the application.send function but I like to have the ability to add custom text into the email body.
Thanks :)
Sub EmailData()
Dim OL As Object
Dim EmailItem As Object
Dim y As Long
Dim TempChar As String
Dim Bodytext As String
Dim Flds As Variant
Dim EmailText As Range
Application.DisplayAlerts = False
Application.ScreenUpdating = False
'Email Download to nursery
Set OL = CreateObject("Outlook.Application")
Set EmailItem = OL.Createitem(OLMailItem)
'Check File Name is correct
Filename = Range("A1") & ".xls"
For y = 1 To Len(Filename)
TempChar = Mid(Filename, y, 1)
Select Case TempChar
Case Is = "/", "\", "*", "?", """", "<", ">", "|"
Case Else
SaveName = SaveName & TempChar
End Select
Next y
ActiveSheet.Cells.Copy
Workbooks.Add
Selection.PasteSpecial Paste:=xlValues
Selection.PasteSpecial Paste:=xlFormats
With ActiveWindow
.DisplayGridlines = False
.DisplayZeros = False
End With
Range("A1:S38").Select
Selection.Locked = True
Selection.FormulaHidden = False
Set EmailText = ActiveSheet.Range("AB1:AB5").SpecialCells(xlCellTypeVisible)
ActiveSheet.Protect ("keepsafe")
ActiveWorkbook.SaveAs Networkpath & "\" & SaveName, , "", , True
ActiveWorkbook.ChangeFileAccess xlReadOnly
EmailItem.display
'On Error Resume Next
With EmailItem
.To = "Daston#blahblah.uk"
'.To = Range("AA1")
.CC = ""
.BCC = ""
.Subject = Filename
.HTMLBody = RangetoHTML(EmailText)
.Attachments.Add ActiveWorkbook.FullName
.send
End With
Application.Wait (Now + TimeValue("0:00:02"))
Kill Networkpath & "\" & SaveName
ActiveWorkbook.Close False
Set OL = Nothing
Set EmailItem = Nothing
End Sub
This describes how, in certain situations, you may "make the object model fully functional".
NameSpace.Logon Method (Outlook)
"first, instantiate the Outlook Application object, then reference a default folder such as the Inbox. This has the side effect of initializing MAPI to use the default profile and to make the object model fully functional."
Sub InitializeMAPI ()
' Start Outlook.
Dim olApp As Outlook.Application
Set olApp = CreateObject("Outlook.Application")
' Get a session object.
Dim olNs As Outlook.NameSpace
Set olNs = olApp.GetNamespace("MAPI")
' Create an instance of the Inbox folder.
' If Outlook is not already running, this has the side
' effect of initializing MAPI.
Dim mailFolder As Outlook.Folder
Set mailFolder = olNs.GetDefaultFolder(olFolderInbox)
' Continue to use the object model to automate Outlook.
End Sub
For security purposes, the HTMLBody, HTMLEditor, Body and WordEditor properties all are subject to address-information security prompts because the body of a message often contains the sender's or other people's e-mail addresses.
HKCU\Software\Policies\Microsoft\office\16.0\outlook\security\
promptoomaddressbookaccess
promptoomaddressinformationaccess
https://support.microsoft.com/en-za/help/926512/information-for-administrators-about-e-mail-security-settings-in-outlo
The most probable cause is Outlook Security.
You can find the security configurations in HKCU\Software\Policies\Microsoft\office\16.0\outlook\security
(change 16.0 to your office version)
Change promptoomsend to 2 (or ask your system administrator), restart Outlook and try again.
More info https://support.microsoft.com/en-za/help/926512/information-for-administrators-about-e-mail-security-settings-in-outlo

Add CC and BCC with Mail Merge

I am trying to add the cc function to a mail merge. In other words, I not only need to personalize the emails to different email addresses. I would also like each email to be include a CC that shows the same email to multiple recipients.
Example: the same email to John Doe can be automatically cc'd to his manager.
I tried adding , and ; as well as merging two cells in excel with the addresses and got errors.
I also read an article that shows how to send attachments to multiple recipients and modified it to make the cc work. See article below.
http://word.mvps.org/FAQs/MailMerge/MergeWithAttachments.htm
The code I came up with is shown below. It allowed me to cc, however, it only goes through with the first row of emails and none of the rest. Also the body of the message does not show up.
Any pointers?
Sub emailmergewithattachments()
'Global Config Variables
Dim saveSent As Boolean, displayMsg As Boolean, attachBCC As Boolean
saveSent = True 'Saves a copy of the messages into the senders "sent" box
displayMsg = False 'Pulls up a copy of all messages to be sent - WARNING, do not use on long lists!
attachBCC = False 'Adds third column data into the BCC field. Will throw error if this column does not exist.
Dim Source As Document, Maillist As Document, TempDoc As Document
Dim Datarange As Range
Dim i As Long, j As Long
Dim bStarted As Boolean
Dim oOutlookApp As Outlook.Application
'Dim oOutlookApp As Application
Dim oItem As Outlook.MailItem
'Dim oItem As MailMessage
Dim mysubject As String, message As String, title As String
Set Source = ActiveDocument
' Check if Outlook is running. If it is not, start Outlook
On Error Resume Next
Set oOutlookApp = GetObject(, "Outlook.Application")
If Err <> 0 Then
Set oOutlookApp = CreateObject("Outlook.Application")
bStarted = True
End If
' Open the catalog mailmerge document
With Dialogs(wdDialogFileOpen)
.Show
End With
Set Maillist = ActiveDocument
' Show an input box asking the user for the subject to be inserted into the email messages
message = "Enter the subject to be used for each email message." ' Set prompt.
title = " Email Subject Input" ' Set title.
' Display message, title
mysubject = InputBox(message, title)
' Iterate through the Sections of the Source document and the rows of the catalog mailmerge document,
' extracting the information to be included in each email.
For j = 0 To Source.Sections.Count - 1
Set oItem = oOutlookApp.CreateItem(olMailItem)
' modification begins here
With oItem
.Subject = mysubject
.body = ActiveDocument.Content
.Body = Source.Sections(j).Range.Text
Set Datarange = Maillist.Tables(1).Cell(j, 1).Range
Datarange.End = Datarange.End - 1
.To = Datarange
Set Datarange = Maillist.Tables(1).Cell(j, 2).Range
Datarange.End = Datarange.End - 1
.CC = Datarange
If attachBCC Then
Set Datarange = Maillist.Tables(1).Cell(j, 3).Range
Datarange.End = Datarange.End - 1
.CC = Datarange
End If
For i = 2 To Maillist.Tables(1).Columns.Count
Set Datarange = Maillist.Tables(1).Cell(j, i).Range
Datarange.End = Datarange.End - 1
.Attachments.Add Trim(Datarange.Text), olByValue, 1
Next i
If displayMsg Then
.Display
End If
If saveSent Then
.SaveSentMessageFolder = mpf
End If
.Send
End With
Set oItem = Nothing
Next j
Maillist.Close wdDoNotSaveChanges
' Close Outlook if it was started by this macro.
If bStarted Then
oOutlookApp.Quit
End If
MsgBox Source.Sections.Count - 1 & " messages have been sent."
'Clean up
Set oOutlookApp = Nothing
End Sub
Firstly, I'd separate out your email code, and the code for iterating your spreadsheet.
Here's my take on the email code for outlook (be sure to setup references->outlook object model, as I've used early biding)
Sub SendMessage(recipients As Variant, subject As String, body As String, Optional ccRecips As Variant, Optional bccRecips As Variant, Optional DisplayMsg As Boolean, Optional AttachmentPath As Variant)
Dim objOutlook As Outlook.Application
Dim objOutlookMsg As Outlook.MailItem
Dim objOutlookRecip As Outlook.Recipient
Dim objOutlookAttach As Outlook.Attachment
Dim item As Variant
' Create the Outlook session.
On Error Resume Next
Set objOutlook = GetObject(, "Outlook.Application")
If Err <> 0 Then
Set objOutlook = CreateObject("Outlook.Application")
End If
On error goto 0
' Create the message.
Set objOutlookMsg = objOutlook.CreateItem(olMailItem)
With objOutlookMsg
' Add the To recipient(s) to the message.
For Each item In recipients
Set objOutlookRecip = .recipients.Add(item)
objOutlookRecip.Type = olTo
Next
' Add the CC recipient(s) to the message.
If Not IsMissing(ccRecips) Then
For Each item In ccRecips
Set objOutlookRecip = .recipients.Add(item)
objOutlookRecip.Type = olTo
Next
End If
' Add the BCC recipient(s) to the message.
If Not IsMissing(bccRecips) Then
For Each item In bccRecips
Set objOutlookRecip = .recipients.Add(item)
objOutlookRecip.Type = olBCC
Next
End If
' Set the Subject, Body, and Importance of the message.
.subject = subject
.body = body 'this can also be HTML, which is great if you want to improve the look of your email, but you must change the format to match
' Add attachments to the message.
If Not IsMissing(AttachmentPath) Then
Set objOutlookAttach = .Attachments.Add(AttachmentPath)
End If
' Resolve each Recipient's name -this may not be necessary if you have fully qualified addresses.
For Each objOutlookRecip In .recipients
objOutlookRecip.Resolve
Next
' Should we display the message before sending?
If DisplayMsg Then
.Display
Else
.Save
.Send
End If
End With
Set objOutlook = Nothing
End Sub
A note: Recipients, CC's and BCC's are expecting arrays of values, which may also only be a single value. This means we can probably send it a raw range, or we can load that range into an array, and send it that.
Now that we've built a nice generic way of sending emails (which is handily re-usable) we can think about the logic of the thing we've got sending emails. I've built the below email, but I havn't spent a lot of time on it (or tested it, as it's quite specific to your tables). I believe it should be very close though.
On writing this, I think you'll see the main trick for editing your own however - the key was splitting the text in the CC cell, by the delimiter you are using. This creates an array of addresses, which you can then iterate over and add to the recipient, CC or BCC.
Sub DocumentSuperMailSenderMagicHopefully()
Dim Source As Document, Maillist As Document, TempDoc As Document
Dim mysubject As String, message As String, title As String
Dim datarange As Range 'word range I'm guessing...
Dim body As String
Dim recips As Variant
Dim ccs As Variant
Dim bccs As Variant
Dim j As Integer
Dim attachs As Variant
Set Source = ActiveDocument
With Dialogs(wdDialogFileOpen) 'Hey, I'm not sure what this does, but I'm leaving it there.
.Show
End With
Set Maillist = ActiveDocument
' Show an input box asking the user for the subject to be inserted into the email messages
message = "Enter the subject to be used for each email message." ' Set prompt.
title = " Email Subject Input" ' Set title.
' Display message, title
mysubject = InputBox(message, title)
' Iterate through the Sections of the Source document and the rows of the catalog mailmerge document,
' extracting the information to be included in each email.
'IMPORTANT: This assumes your email addresses in the table are separated with commas!
For j = 0 To Source.Sections.Count - 1
body = Source.Sections(j).Range.Text
'get to recipients from tables col 1 (I'd prefer this in excel, it's tables are much better!)
Set datarange = Maillist.tables(1).Cell(j, 1).Range
datarange.End = datarange.End - 1
recips = Split(datarange.Text)
'CC's
Set datarange = Maillist.tables(1).Cell(j, 2).Range
datarange.End = datarange.End - 1
ccs = Split(datarange.Text)
'BCC's
Set datarange = Maillist.tables(1).Cell(j, 3).Range
datarange.End = datarange.End - 1
bccs = Split(datarange.Text)
'Attachments array, should be paths, handled by the mail app, in an array
ReDim attachs(Maillist.tables(1).Columns.Count - 3) 'minus 2 because you start i at 2 and minus one more for option base 0
For i = 2 To Maillist.tables(1).Columns.Count
Set datarange = Maillist.tables(1).Cell(j, i).Range
datarange.End = datarange.End - 1
attachs(i) = Trim(datarange.Text)
Next i
'call the mail sender
SendMessage recips, subject, body, ccs, bccs, False, attachs
Next j
Maillist.Close wdDoNotSaveChanges
MsgBox Source.Sections.Count - 1 & " messages have been sent."
End Sub
This has turned into a longer post than I was expecting. Good luck with the project!
I had the same issue not being able to CC using the mail merge from Excel, and also wanted to use the BCC field and have subjects that are variable for each email), and didn't find a good tool either, so I built my own tool and have just released it for others to benefit from. Let me know if that solves your issue too: http://emailmerge.cc/
It doesn't handle attachments yet, but I've planned to add that soon.
EDIT: EmailMerge.cc now also handles attachments, high/low priority, read receipts [unfortunately some people still want those ;) ]
I hope this is useful to you, my intent is not to to spam SO ;)

Resources