0
votes

I am trying to address a list of clients by their name when I send them meeting invitations. Clients must not see other invitees. I have tried several approaches: add clients one-by-one as a Resource, changing meeting notes text each time, forwarding the meeting as an iCalendar item, no luck.

Objective:

  • Simulate the Forward behavior of an Outlook Meeting. enter image description here enter image description here

  • Change all attendees from Required to Resource(I can do this)

I have done a lot of research and could not find a way to forward a meeting that simulates the user interface version.

Background information:

  • I have created a Zoom meetings appointment of which I know the location URL
  • I can successfully access this appointment as an Outlook.AppointmentItem using Restrict
  • I cannot add the list of clients directly as Resource because then I cannot customize each invite
  • I cannot use AppointmentItem.ForwardAsVcal as that forwards the meeting as an attachment and does not occupy calendar space for the client (also I believe it looks unprofessional)
  • I have failed to use MeetingItem.Forward because my object is an Outlook.AppointmentItem
  • I have successfully added new clients using Recipients.Add and .Type = olResource
  • I have successfully modified meeting notes using AppointmentItem.GetInspector().WordEditor.Range.FormattedText but this causes previous invites to be canceled and updates text in the invitation so everyone sees the last invite

Code:

Accessing the item successfully

Private Function getMeeting() As Outlook.AppointmentItem
    Dim settingsWS As Worksheet
    Set settingsWS = ThisWorkbook.Sheets("Settings")
    
    Dim meetingStart As Date, meetingEnd As Date
    meetingStart = settingsWS.Cells(2, 1).Value 'start time
    
    Dim locationString As String
    locationString = settingsWS.Cells(2, 2).Value 'location url
    
    Dim oCalendar As Outlook.Folder
    Dim oItems As Outlook.Items
    
    Dim strRestriction As String
    daStart = Format(meetingStart, "mm/dd/yyyy hh:mm AMPM")
    daEnd = DateAdd("h", 2, daStart)
    daEnd = Format(daEnd, "mm/dd/yyyy hh:mm AMPM")
    strRestriction = "[Start] >= '" & daStart & "' AND [End] <= '" & daEnd & "'"
    strRestriction = strRestriction & " AND [Location] = '" & locationString & "'"
    
    Set oCalendar = GetNamespace("MAPI").GetDefaultFolder(olFolderCalendar)
    Set oItems = oCalendar.Items.Restrict(strRestriction)
    
    Set getMeeting = oItems(1)
    
End Function

My failed forwarding trials:

Private Sub sendInvites(oAppt As Outlook.AppointmentItem)
    Dim oMail As Outlook.MailItem, oAtt As Outlook.Recipient, embeddedInvitation As OLEObject
    
    Dim industryWS As Worksheet
    Set industryWS = ThisWorkbook.ActiveSheet
    
    Dim attendeeRange As Range
    Set attendeeRange = industryWS.Cells(3, 1).CurrentRegion 'list of clients
    
    Dim attendeeCompany As String, attendeeEmail As String
    Dim attendeeName As String, attendeePrefix As String
    
    Dim attendeeCount As Long, attendeeIndex As Long
    attendeeCount = attendeeRange.Rows.Count - 1
    For attendeeIndex = 1 To attendeeCount
        attendeeCompany = attendeeRange.Cells(attendeeIndex + 1, 1).Value
        attendeeEmail = attendeeRange.Cells(attendeeIndex + 1, 2).Value
        attendeeName = attendeeRange.Cells(attendeeIndex + 1, 4).Value
        attendeePrefix = attendeeRange.Cells(attendeeIndex + 1, 5).Value
        Application.StatusBar = "Sending invites (" & CStr(attendeeIndex) & "/" & CStr(attendeeCount) & ") " & attendeeEmail
        
        Set oMail = Outlook.Application.CreateItem(olMailItem)
        'Set oMail = oAppt.ForwardAsVcal
        oMail.To = attendeeEmail
        
        oMail.BodyFormat = olFormatHTML
        oMail.HTMLBody = getInvitationBody(attendeeName, attendeePrefix) & oMail.HTMLBody 'return invitation mailbody as HTML
        'Dim fsd As MeetingItem
        'fsd.Forward
        'Set oAtt = oAppt.Recipients.Add(attendeeEmail)
        'oAtt.Type = olResource

        'oAppt.GetInspector().WordEditor.Range.FormattedText.Delete
        'oMail.GetInspector().WordEditor.Range.FormattedText.Copy
        'oAppt.GetInspector().WordEditor.Range.FormattedText.Paste
        'oMail.Close False
        'oAppt.ForwardAsVcal
        'oAppt.Display
        'oAppt.Send
        oMail.Send
        
        Application.StatusBar = "Saving invites (" & CStr(attendeeIndex) & "/" & CStr(attendeeCount) & ") " & attendeeEmail
        'saveInvite oAppt, industryWS, attendeeRange
        DoEvents
    Next attendeeIndex
End Sub
1

1 Answers

0
votes

I solved it after hours of trying.

My initial instinct was to loop through items in the olFolderCalendar since in the UI we access the meeting forward through the calendar, but objects in the calendar are Outlook.AppointmentItem rather than Outlook.MeetingItem which can be forwarded.

The solution is to send the meeting to yourself (or anyone in your organization) so that a copy of the meeting invitation is in your olFolderSentMail. Items in the olFolderSentMail are Outlook.MeetingItem, which can be forwarded. Unless you send it to someone thou, the meeting will not enter your olFolderSentMail.

We can filter our olFolderSentMail by using Restrict and location (URL) of the meeting. Once we have the Outlook.MeetingItem we can create a new Outlook.MeetingItem by calling MeetingItem.Forward on our existing meeting in our olFolderSentMail. Once we have the new Outlook.MeetingItem we can add clients to it as olResource. This will send a customized, otherwise invisible invitation to the client without notifying other clients.

One point of warning before I end this answer: My first approach was to loop in reverse through my olFolderSentMail so as not to loop over to many items and to save time, however keep in mind that everytime you forward the meeting, the new invitation ends up at the top of the olFolderSentMail, so if in reverse, you will be forwarding the forwarded invitation. When using the Restrict approach, you can simply use the first item, which should be your original invitation to yourself.