Copying shared Calendar Appointments from outlook into Excel with VBA

RobP

Well-known Member
Joined
May 8, 2008
Messages
654
Office Version
  1. 365
Platform
  1. Windows
Hi all,

I am using Office 365 Pro Plus build 1912 (but it also ran on build 1902 or 1904 before I upgraded recently).
My macro is written to interrogate my own, and shared calendars with me from outlook - and bring the appointments into Excel in a list.

It works beautifully on my own machine - I can grab data from each calendar in turn. However, when I pass my excel file to a colleague for him (actually tried 2 different people) to run the macro on his machine (same build config etc.) - it runs into problems.

The code appears to execute as expected (in that it takes some time to grab this years and last years data), and then completes once its done, without displaying any of the data. We are currently remote, so I've not tried stepping through the code on their machines to see what its doing yet - but on the face of it - it appears to be running correctly - just not fetching the Outlook Calendar data.

I have set the Outlook Object reference (16.0) in the developer/Tools/References on their machines accordingly.

Can I ask, Are there any other settings that I need to have done on their machines in order for this to function ?

I've been using macros on my machines for a long time - so wondered if I'd set something some time ago that I'd forgotten about recently.... I'll paste a section of my code here, just for reference.

VBA Code:
Option Explicit
Public R As Long
Public SelectedCalendar As String
' ********************************************************************************
' *   Interrogate Outlook calendars for all external meetings & populate
' *   Excel database with attendees coming down the columns for each appt.
' **********************************************************************************

Sub outlook_calendaritemsexport()

Dim C As Long, i As Long,  lrow As Long
Dim appt_id As Long,  append_row As Long
Dim data_array() As Variant, start_time As Variant

Dim myfol As Outlook.Folder
Dim ons As Outlook.Namespace
Dim o As Outlook.Application
Dim myapt As Outlook.AppointmentItem
Dim myrpnt As Outlook.Recipient
Dim oEU As Object

Set o = New Outlook.Application
Set ons = o.GetNamespace("MAPI")

start_time = Now()

Sheets("Data").Activate

'Show UserForm here. UserForm is a simple box with names of shared calendars, which gets stored into "SelectedCalendar" upon selection. R is also set to 5 (start row on my sheet), or last row after current data
UserForm1.Show

'Setup 'Subroutine to Setup column widths / colors etc

append_row = R 'use this to know where to append the new data onto screen for an appended search.. R comes from UserForm.

Dim myRecipient As Outlook.Recipient

'selected in the userform ComboBox list
If SelectedCalendar = "Select Calendar" Then 'nobody selected, so operate on your own calendar
    Set myfol = ons.GetDefaultFolder(olFolderCalendar) 'Set this to work on own folder
Else
    Set myRecipient = ons.CreateRecipient(SelectedCalendar)
    myRecipient.Resolve

    If myRecipient.Resolved Then
            Set myfol = ons.GetSharedDefaultFolder(myRecipient, olFolderCalendar)
        Else
            MsgBox ("Calendar Issue, Program Halted")
            End  'end if calendar not resolved
    End If
End If

Range("A4:N4").Value = Array("DATE", "CUSTOMER", "SUBJECT", "LOCATION", "CUSTOMER TYPE or DISTRIBUTOR MEETING", "FACE To FACE / TEAMS", "DISTRIBUTOR Or ALONE", "DISTRIBUTOR VISIT TYPE", "CUSTOMER ATTENDEES", "DISTRIBUTOR ATTENDEES", "OUR ATTENDEES", "REQUIRED ATTENDEES", "CALENDAR OWNER", "MEET ID")

'check calendar has some items inside / is shared

On Error GoTo ErrorHandler

lrow = 0 'array row start)
ReDim Preserve data_array(1 To 14, lrow) '(be aware the array is transposed, as ReDim Preserve only works on last dimension)

'***  GET THIS DYNAMICALLY FROM LAST ROW OF DATA (comes from userform button) in case of New, or Appended data search *****
If R = 5 Then
    appt_id = 1 'set first appointment ID number
Else
    appt_id = Cells(R - 1, 14).Value + 1
End If


R = 0 ' now reset R as first row in array

For Each myapt In myfol.Items 'check each calendar Appointment) Then
  
    'Year(Now())   Year(Now())-1  this year last year
  If InStr(myapt.Start, Year(Now())) > 0 Or InStr(myapt.Start, (Year(Now())) - 1) > 0 Then ' if appt is this year/last year
  
   
    data_array(1, R) = myapt.Start
   
    data_array(3, R) = myapt.Subject
   
    data_array(4, R) = myapt.Location
    
    data_array(12, R) = LCase(myapt.RequiredAttendees)
 
    data_array(13, R) = SelectedCalendar
 
    data_array(14, R) = appt_id
    
    appt_id = appt_id + 1 ' update appointment ID code

     ReDim Preserve data_array(1 To 14, R + 1) 

     R = R + 1 
 End If 'End Appt year checking

Next 'Calendar Appointment

Set o = Nothing
Set ons = Nothing
Set myfol = Nothing
Set myapt = Nothing
Set myrpnt = Nothing

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True

'store data on screen
Range(Cells(append_row, 1), Cells(append_row + UBound(data_array, 2), 14)) = TransposeArray(data_array) 'function to transpose data back into rows due to RedimPreserve operating across only


MsgBox ("start : " & start_time & "  finish : " & Now())

Erase data_array


End

ErrorHandler:
    MsgBox ("Calendar Not Shared")
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.EnableEvents = True
    End

End Sub
 
Hi Rob,

Thanks I will give that whirl.
Your help is much appreciated.

Cheers,
Michael.
 
Upvote 0

Excel Facts

Formula for Yesterday
Name Manager, New Name. Yesterday =TODAY()-1. OK. Then, use =YESTERDAY in any cell. Tomorrow could be =TODAY()+1.
Hi Rob,

That worked great but for some reason it is not pulling all the data from the calendar.
Trying to validate but missing loads of records.

Thanks,
Michael.
 
Upvote 0
Well I might have worked something out but not sure how to get around it.
My missing data, we have added a recurring event for 5mins every day so every days is visible in the pivot data.
The export is reading only the first appointment and not the subsequent appointments.
On all calendars.
 
Upvote 0
Hi Michael,
I had some time over the weekend, so played a little with it to get recurring appointments also. I highlighted the code changes in Orange below from my original post.
I renamed one of the objects (myfol) to allappointments for ease of reading, and changed the main loop from an if to a While/Wend

Hope its okay for you to try out.
cheers
Rob

VBA Code:
Option Explicit
Public R As Long
Public SelectedCalendar As String
' ********************************************************************************
' *   Interrogate Outlook calendars for all external meetings & populate
' *   Excel database with attendees coming down the columns for each appt.
' **********************************************************************************

Sub outlook_calendaritemsexport()

Dim C As Long, i As Long,  lrow As Long
Dim appt_id As Long,  append_row As Long
Dim data_array() As Variant, start_time As Variant
[COLOR=rgb(243, 121, 52)]Dim datestart As Date
Dim dateend As Date[/COLOR]

Dim [COLOR=rgb(243, 121, 52)]allappointments[/COLOR] As Outlook.Folder
Dim ons As Outlook.Namespace
Dim o As Outlook.Application
Dim myapt As Outlook.AppointmentItem
Dim myrpnt As Outlook.Recipient
Dim oEU As Object

Set o = New Outlook.Application
Set ons = o.GetNamespace("MAPI")

start_time = Now()

Sheets("Data").Activate

'Show UserForm here. UserForm is a simple box with names of shared calendars, which gets stored into "SelectedCalendar" upon selection. R is also set to 5 (start row on my sheet), or last row after current data
UserForm1.Show

'Setup 'Subroutine to Setup column widths / colors etc

append_row = R 'use this to know where to append the new data onto screen for an appended search.. R comes from UserForm.

Dim myRecipient As Outlook.Recipient

'selected in the userform ComboBox list
If SelectedCalendar = "Select Calendar" Then 'nobody selected, so operate on your own calendar
    Set [COLOR=rgb(243, 121, 52)]allappointments[/COLOR] = ons.GetDefaultFolder(olFolderCalendar)[COLOR=rgb(243, 121, 52)].Items[/COLOR] 'Set this to work on own folder
Else
    Set myRecipient = ons.CreateRecipient(SelectedCalendar)
    myRecipient.Resolve

    If myRecipient.Resolved Then
            Set[COLOR=rgb(243, 121, 52)] allappointments[/COLOR] = ons.GetSharedDefaultFolder(myRecipient, olFolderCalendar)[COLOR=rgb(243, 121, 52)].Items[/COLOR]
        Else
            MsgBox ("Calendar Issue, Program Halted")
            End  'end if calendar not resolved
    End If
End If

[COLOR=rgb(243, 121, 52)]allappointments.Sort "Start", [Ascending]
allappointments.IncludeRecurrences = True[/COLOR]

Range("A4:N4").Value = Array("DATE", "CUSTOMER", "SUBJECT", "LOCATION", "CUSTOMER TYPE or DISTRIBUTOR MEETING", "FACE To FACE / TEAMS", "DISTRIBUTOR Or ALONE", "DISTRIBUTOR VISIT TYPE", "CUSTOMER ATTENDEES", "DISTRIBUTOR ATTENDEES", "OUR ATTENDEES", "REQUIRED ATTENDEES", "CALENDAR OWNER", "MEET ID")

'check calendar has some items inside / is shared

On Error GoTo ErrorHandler

lrow = 0 'array row start)
ReDim Preserve data_array(1 To 14, lrow) '(be aware the array is transposed, as ReDim Preserve only works on last dimension)

'***  GET THIS DYNAMICALLY FROM LAST ROW OF DATA (comes from userform button) in case of New, or Appended data search *****
If R = 5 Then
    appt_id = 1 'set first appointment ID number
Else
    appt_id = Cells(R - 1, 14).Value + 1
End If


R = 0 ' now reset R as first row in array

[COLOR=rgb(243, 121, 52)]dateend = VBA.Format(Now, "Short Date")[/COLOR] ' end date is today - so get dates right up to today.
[COLOR=rgb(243, 121, 52)]datestart = VBA.Format("01/01/" & (Year(Now()) - 1) & " 21:30", "Short Date")[/COLOR] 'sets start date to be Jan 1st last year (time was 21:30 - just random..) (but you can set it to be whatever you want.)

[COLOR=rgb(243, 121, 52)]Set myapt = allappointments.Find("[Start] >= """ & datestart & """ and [Start] <= """ & dateend & """")[/COLOR]
  
[COLOR=rgb(243, 121, 52)] While TypeName(myapt) <> "Nothing"[/COLOR]
  
   
    data_array(1, R) = myapt.Start  
    data_array(3, R) = myapt.Subject   
    data_array(4, R) = myapt.Location    
    data_array(12, R) = LCase(myapt.RequiredAttendees) 
    data_array(13, R) = SelectedCalendar 
    data_array(14, R) = appt_id    
    appt_id = appt_id + 1 ' update appointment ID code

     ReDim Preserve data_array(1 To 14, R + 1) 

     R = R + 1 

[COLOR=rgb(243, 121, 52)]Set myapt = allappointments.FindNext
 
 Wend [/COLOR][COLOR=rgb(0, 0, 0)]'next Calendar Apt[/COLOR]

Set o = Nothing
Set ons = Nothing
Set[COLOR=rgb(243, 121, 52)] allappointments[/COLOR] = Nothing
Set myapt = Nothing
Set myrpnt = Nothing

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True

'store data on screen
Range(Cells(append_row, 1), Cells(append_row + UBound(data_array, 2), 14)) = TransposeArray(data_array) 'function to transpose data back into rows due to RedimPreserve operating across only


MsgBox ("start : " & start_time & "  finish : " & Now())

Erase data_array


End

ErrorHandler:
    MsgBox ("Calendar Not Shared")
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.EnableEvents = True
    End

End Sub
 
Upvote 0
sorry, its added COLOR TAGS around every part I highlighted in Orange .. please delete these tags, as they are not part of the code.
Rob
 
Upvote 0
cleaned up a little - changes are highlighted as '********* AMENDED ********* from my original post.
Rob

VBA Code:
Option Explicit
Public R As Long
Public SelectedCalendar As String
' ********************************************************************************
' *   Interrogate Outlook calendars for all external meetings & populate
' *   Excel database with attendees coming down the columns for each appt.
' **********************************************************************************

Sub outlook_calendaritemsexport()

Dim C As Long, i As Long,  lrow As Long
Dim appt_id As Long,  append_row As Long
Dim data_array() As Variant, start_time As Variant
Dim datestart As Date '********* AMENDED *********
Dim dateend As Date '********* AMENDED *********

Dim allappointments As Outlook.Folder '********* AMENDED *********
Dim ons As Outlook.Namespace
Dim o As Outlook.Application
Dim myapt As Outlook.AppointmentItem
Dim myrpnt As Outlook.Recipient
Dim oEU As Object

Set o = New Outlook.Application
Set ons = o.GetNamespace("MAPI")

start_time = Now()

Sheets("Data").Activate

'Show UserForm here. UserForm is a simple box with names of shared calendars, which gets stored into "SelectedCalendar" upon selection. R is also set to 5 (start row on my sheet), or last row after current data
UserForm1.Show

'Setup 'Subroutine to Setup column widths / colors etc

append_row = R 'use this to know where to append the new data onto screen for an appended search.. R comes from UserForm.

Dim myRecipient As Outlook.Recipient

'selected in the userform ComboBox list
If SelectedCalendar = "Select Calendar" Then 'nobody selected, so operate on your own calendar
    Set allappointments = ons.GetDefaultFolder(olFolderCalendar).Items 'Set this to work on own folder  ********* AMENDED *********
Else
    Set myRecipient = ons.CreateRecipient(SelectedCalendar)
    myRecipient.Resolve

    If myRecipient.Resolved Then
            Set allappointments = ons.GetSharedDefaultFolder(myRecipient, olFolderCalendar).Items '********* AMENDED *********
        Else
            MsgBox ("Calendar Issue, Program Halted")
            End  'end if calendar not resolved
    End If
End If

allappointments.Sort "Start", [Ascending]  '********* AMENDED *********
allappointments.IncludeRecurrences = True   '********* AMENDED *********

Range("A4:N4").Value = Array("DATE", "CUSTOMER", "SUBJECT", "LOCATION", "CUSTOMER TYPE or DISTRIBUTOR MEETING", "FACE To FACE / TEAMS", "DISTRIBUTOR Or ALONE", "DISTRIBUTOR VISIT TYPE", "CUSTOMER ATTENDEES", "DISTRIBUTOR ATTENDEES", "OUR ATTENDEES", "REQUIRED ATTENDEES", "CALENDAR OWNER", "MEET ID")

'check calendar has some items inside / is shared

On Error GoTo ErrorHandler

lrow = 0 'array row start)
ReDim Preserve data_array(1 To 14, lrow) '(be aware the array is transposed, as ReDim Preserve only works on last dimension)

'***  GET THIS DYNAMICALLY FROM LAST ROW OF DATA (comes from userform button) in case of New, or Appended data search *****
If R = 5 Then
    appt_id = 1 'set first appointment ID number
Else
    appt_id = Cells(R - 1, 14).Value + 1
End If


R = 0 ' now reset R as first row in array

dateend = VBA.Format(Now, "Short Date") ' end date is today - so get dates right up to today. ********* AMENDED *********
datestart = VBA.Format("01/01/" & (Year(Now()) - 1) & " 21:30", "Short Date") 'sets start date to be Jan 1st last year (time was 21:30 - just random..) (but you can set it to be whatever you want.)

Set myapt = allappointments.Find("[Start] >= """ & datestart & """ and [Start] <= """ & dateend & """") '********* AMENDED *********
  
While TypeName(myapt) <> "Nothing" '********* AMENDED *********
  
   
    data_array(1, R) = myapt.Start  
    data_array(3, R) = myapt.Subject   
    data_array(4, R) = myapt.Location    
    data_array(12, R) = LCase(myapt.RequiredAttendees) 
    data_array(13, R) = SelectedCalendar 
    data_array(14, R) = appt_id    
    appt_id = appt_id + 1 ' update appointment ID code

     ReDim Preserve data_array(1 To 14, R + 1) 

     R = R + 1 

Set myapt = allappointments.FindNext '********* AMENDED *********
 
 Wend 'next Calendar Apt ********* AMENDED *********

Set o = Nothing
Set ons = Nothing
Set allappointments = Nothing '********* AMENDED *********
Set myapt = Nothing
Set myrpnt = Nothing

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True

'store data on screen
Range(Cells(append_row, 1), Cells(append_row + UBound(data_array, 2), 14)) = TransposeArray(data_array) 'function to transpose data back into rows due to RedimPreserve operating across only


MsgBox ("start : " & start_time & "  finish : " & Now())

Erase data_array


End

ErrorHandler:
    MsgBox ("Calendar Not Shared")
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    Application.EnableEvents = True
    End

End Sub
 
Upvote 0
Awesome I will give this a kick around today, I've had to leave it since last week.
I have been looking at your link from last week and it kept falling over so this is great thanks.
Fingers crossed.

Thanks again Michael.
 
Upvote 0
So close but doesn't like below.
 

Attachments

  • typemismatch13.JPG
    typemismatch13.JPG
    68.9 KB · Views: 9
Upvote 0
did you have this line changed in your declarations :

Dim allappointments As Outlook.Items ?

(rather than an Outlook.Folder ).. looks like I missed to change "Folder" to .Items.. my apologies from above..
 
Upvote 0

Forum statistics

Threads
1,214,944
Messages
6,122,392
Members
449,081
Latest member
JAMES KECULAH

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top