I put this solution together for Allen, who had seen my post demonstrating how to export Outlook messages to Excel and asked if I could create a similar macro to export appointments. Allen went on to explain that his organization uses a shared calendar and that periodically he would like to export its contents to Excel. For each appointment, Allen wants to export the organizer (i.e. the person that added the appointment to the calendar), when the appointment was added, the appointment’s subject, when it starts, and who was invited. To make it a little easier for Allen, I broke “who was invited” down into two groups: required and optional attendees. The solution itself is nearly identical to the one I used to export messages.
Instructions.
Follow these instructions to add the code to Outlook.
- Start Outlook
- Press ALT + F11 to open the Visual Basic Editor
- If not already expanded, expand Microsoft Office Outlook Objects
- If not already expanded, expand Modules
- Select an existing module (e.g. Module1) by double-clicking on it or create a new module by right-clicking Modules and selecting Insert → Module.
- Copy the code from the code snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
- Click the diskette icon on the toolbar to save the changes
- Close the VB Editor
Sub ExportAppointmentsToExcel() Const SCRIPT_NAME = "Export Appointments to Excel" Dim olkFld As Object, _ olkLst As Object, _ olkApt As Object, _ excApp As Object, _ excWkb As Object, _ excWks As Object, _ lngRow As Long, _ intCnt As Integer Set olkFld = Application.ActiveExplorer.CurrentFolder If olkFld.DefaultItemType = olAppointmentItem Then strFilename = InputBox("Enter a filename (including path) to save the exported appointments to.", SCRIPT_NAME) If strFilename <> "" Then Set excApp = CreateObject("Excel.Application") Set excWkb = excApp.Workbooks.Add() Set excWks = excWkb.Worksheets(1) 'Write Excel Column Headers With excWks .Cells(1, 1) = "Organizer" .Cells(1, 2) = "Created" .Cells(1, 3) = "Subject" .Cells(1, 4) = "Start" .Cells(1, 5) = "Required" .Cells(1, 6) = "Optional" End With lngRow = 2 Set olkLst = olkFld.Items olkLst.Sort "[Start]" olkLst.IncludeRecurrences = True 'Write appointments to spreadsheet For Each olkApt In Application.ActiveExplorer.CurrentFolder.Items 'Only export appointments If olkApt.Class = olAppointment Then 'Add a row for each field in the message you want to export excWks.Cells(lngRow, 1) = olkApt.Organizer excWks.Cells(lngRow, 2) = olkApt.CreationTime excWks.Cells(lngRow, 3) = olkApt.Subject excWks.Cells(lngRow, 4) = olkApt.Start excWks.Cells(lngRow, 5) = olkApt.RequiredAttendees excWks.Cells(lngRow, 6) = olkApt.OptionalAttendees lngRow = lngRow + 1 intCnt = intCnt + 1 End If Next excWks.Columns("A:F").AutoFit excWkb.SaveAs strFilename excWkb.Close MsgBox "Process complete. A total of " & intCnt & " appointments were exported.", vbInformation + vbOKOnly, SCRIPT_NAME End If Else MsgBox "Operation cancelled. The selected folder is not a calendar. You must select a calendar for this macro to work.", vbCritical + vbOKOnly, SCRIPT_NAME End If Set excWks = Nothing Set excWkb = Nothing Set excApp = Nothing Set olkApt = Nothing Set olkLst = Nothing Set olkFld = Nothing End Sub
Using the Code.
- With Outlook open select a calendar.
- Run the macro.
- When prompted, enter a filename to save the export to. You can cancel the export by leaving the file name blank.
- The macro will display a dialog-box when it’s finished. The dialog-box includes a count of the number of appointments exported.
Revisions.
1 | 2 | 3 | 4 |
Revision 1.
This revision is for Oradev, who asked for two changes to the original script. First, Oradev wants to be able to export appointments falling within a date range. To accomplish this, I’ve added a dialog-box that prompts for the date range. Second, Oradev needs a different set of data from each appointment. Where the original code exports organizer, date created, subject start time, and attendees, this version exports category, subject, start date, end date, start time, end time, the length of the appointment in hours, and attendees. The export is sorted by category and the appointment length column is summed.
Oradev will use the instructions from the original post to add the code to Outlook.
Sub ExportAppointmentsToExcel() Const SCRIPT_NAME = "Export Appointments to Excel (Rev 1)" Const xlAscending = 1 Const xlYes = 1 Dim olkFld As Object, _ olkLst As Object, _ olkRes As Object, _ olkApt As Object, _ olkRec As Object, _ excApp As Object, _ excWkb As Object, _ excWks As Object, _ lngRow As Long, _ lngCnt As Long, _ strFil As String, _ strLst As String, _ strDat As String, _ datBeg As Date, _ datEnd As Date, _ arrTmp As Variant Set olkFld = Application.ActiveExplorer.CurrentFolder If olkFld.DefaultItemType = olAppointmentItem Then strDat = InputBox("Enter the date range of the appointments to export in the form ""mm/dd/yyyy to mm/dd/yyyy""", SCRIPT_NAME, Date & " to " & Date) arrTmp = Split(strDat, "to") datBeg = IIf(IsDate(arrTmp(0)), arrTmp(0), Date) & " 12:00am" datEnd = IIf(IsDate(arrTmp(1)), arrTmp(1), Date) & " 11:59pm" strFil = InputBox("Enter a filename (including path) to save the exported appointments to.", SCRIPT_NAME) If strFil <> "" Then Set excApp = CreateObject("Excel.Application") Set excWkb = excApp.Workbooks.Add() Set excWks = excWkb.Worksheets(1) 'Write Excel Column Headers With excWks .Cells(1, 1) = "Category" .Cells(1, 2) = "Subject" .Cells(1, 3) = "Starting Date" .Cells(1, 4) = "Ending Date" .Cells(1, 5) = "Start Time" .Cells(1, 6) = "End Time" .Cells(1, 7) = "Hours" .Cells(1, 8) = "Attendees" End With lngRow = 2 Set olkLst = olkFld.Items olkLst.Sort "[Start]" olkLst.IncludeRecurrences = True Set olkRes = olkLst.Restrict("[Start] >= '" & Format(datBeg, "ddddd h:nn AMPM") & "' AND [Start] <= '" & Format(datEnd, "ddddd h:nn AMPM") & "'") 'Write appointments to spreadsheet For Each olkApt In olkRes 'Only export appointments If olkApt.Class = olAppointment Then strLst = "" For Each olkRec In olkApt.Recipients strLst = strLst & olkRec.Name & ", " Next If strLst <> "" Then strLst = Left(strLst, Len(strLst) - 2) 'Add a row for each field in the message you want to export excWks.Cells(lngRow, 1) = olkApt.Categories excWks.Cells(lngRow, 2) = olkApt.Subject excWks.Cells(lngRow, 3) = Format(olkApt.Start, "mm/dd/yyyy") excWks.Cells(lngRow, 4) = Format(olkApt.End, "mm/dd/yyyy") excWks.Cells(lngRow, 5) = Format(olkApt.Start, "hh:nn ampm") excWks.Cells(lngRow, 6) = Format(olkApt.End, "hh:nn ampm") excWks.Cells(lngRow, 7) = DateDiff("n", olkApt.Start, olkApt.End) / 60 excWks.Cells(lngRow, 7).NumberFormat = "0.00" excWks.Cells(lngRow, 8) = strLst lngRow = lngRow + 1 lngCnt = lngCnt + 1 End If Next excWks.Columns("A:H").AutoFit excWks.Range("A1:H" & lngRow - 1).Sort Key1:="Category", Order1:=xlAscending, Header:=xlYes excWks.Cells(lngRow, 7) = "=sum(G2:G" & lngRow - 1 & ")" excWkb.SaveAs strFil excWkb.Close MsgBox "Process complete. A total of " & lngCnt & " appointments were exported.", vbInformation + vbOKOnly, SCRIPT_NAME End If Else MsgBox "Operation cancelled. The selected folder is not a calendar. You must select a calendar for this macro to work.", vbCritical + vbOKOnly, SCRIPT_NAME End If Set excWks = Nothing Set excWkb = Nothing Set excApp = Nothing Set olkApt = Nothing Set olkLst = Nothing Set olkFld = Nothing End Sub
Revision 2.
This revision is for Kimberly. Kimberly asked for a version based on revision 1, with a few changes. Specifically
- Export a fixed list of calendars
- Include the name of the calendar with each exported appointment
- Export to a fixed file name rather than having to enter the file name each time
Kimberly will use the instructions from the original post to add the code to Outlook.
Sub ExportAppointmentsToExcel() 'On the next line, edit the list of calendars you want to export. Each entry is the path to a calendar. Entries are separated by a comma. Const CAL_LIST = "Calendar1,Calendar2" 'On the next line, edit the path to and name of the Excel spreadsheet to export to Const EXCEL_FILE = "c:\users\david\documents\testarea\kimberly.xlsx" Const SCRIPT_NAME = "Export Appointments to Excel (Rev 2)" Const xlAscending = 1 Const xlYes = 1 Dim olkFld As Object, _ olkLst As Object, _ olkRes As Object, _ olkApt As Object, _ olkRec As Object, _ excApp As Object, _ excWkb As Object, _ excWks As Object, _ lngRow As Long, _ lngCnt As Long, _ strFil As String, _ strLst As String, _ strDat As String, _ datBeg As Date, _ datEnd As Date, _ arrTmp As Variant, _ arrCal As Variant, _ varCal As Variant strDat = InputBox("Enter the date range of the appointments to export in the form ""mm/dd/yyyy to mm/dd/yyyy""", SCRIPT_NAME, Date & " to " & Date) arrTmp = Split(strDat, "to") datBeg = IIf(IsDate(arrTmp(0)), arrTmp(0), Date) & " 12:00am" datEnd = IIf(IsDate(arrTmp(1)), arrTmp(1), Date) & " 11:59pm" Set excApp = CreateObject("Excel.Application") Set excWkb = excApp.Workbooks.Add() Set excWks = excWkb.Worksheets(1) 'Write Excel Column Headers With excWks .Cells(1, 1) = "Calendar" .Cells(1, 2) = "Category" .Cells(1, 3) = "Subject" .Cells(1, 4) = "Starting Date" .Cells(1, 5) = "Ending Date" .Cells(1, 6) = "Start Time" .Cells(1, 7) = "End Time" .Cells(1, 8) = "Hours" .Cells(1, 9) = "Attendees" End With lngRow = 2 arrCal = Split(CAL_LIST, ",") For Each varCal In arrCal Set olkFld = OpenOutlookFolder(CStr(varCal)) If TypeName(olkFld) <> "Nothing" Then If olkFld.DefaultItemType = olAppointmentItem Then Set olkLst = olkFld.Items olkLst.Sort "[Start]" olkLst.IncludeRecurrences = True Set olkRes = olkLst.Restrict("[Start] >= '" & Format(datBeg, "ddddd h:nn AMPM") & "' AND [Start] <= '" & Format(datEnd, "ddddd h:nn AMPM") & "'") 'Write appointments to spreadsheet For Each olkApt In olkRes 'Only export appointments If olkApt.Class = olAppointment Then strLst = "" For Each olkRec In olkApt.Recipients strLst = strLst & olkRec.Name & ", " Next If strLst <> "" Then strLst = Left(strLst, Len(strLst) - 2) 'Add a row for each field in the message you want to export excWks.Cells(lngRow, 1) = olkFld.FolderPath excWks.Cells(lngRow, 2) = olkApt.Categories excWks.Cells(lngRow, 3) = olkApt.Subject excWks.Cells(lngRow, 4) = Format(olkApt.Start, "mm/dd/yyyy") excWks.Cells(lngRow, 5) = Format(olkApt.End, "mm/dd/yyyy") excWks.Cells(lngRow, 6) = Format(olkApt.Start, "hh:nn ampm") excWks.Cells(lngRow, 7) = Format(olkApt.End, "hh:nn ampm") excWks.Cells(lngRow, 8) = DateDiff("n", olkApt.Start, olkApt.End) / 60 excWks.Cells(lngRow, 8).NumberFormat = "0.00" excWks.Cells(lngRow, 9) = strLst lngRow = lngRow + 1 lngCnt = lngCnt + 1 End If Next Else MsgBox "Operation cancelled. The selected folder is not a calendar. You must select a calendar for this macro to work.", vbCritical + vbOKOnly, SCRIPT_NAME End If Else MsgBox "I could not find a folder named " & varCal & ". Folder skipped. I will continue processing the remaining folders.", vbExclamation + vbOKOnly, SCRIPT_NAME End If Next excWks.Columns("A:I").AutoFit excWks.Range("A1:I" & lngRow - 1).Sort Key1:="Category", Order1:=xlAscending, Header:=xlYes excWks.Cells(lngRow, 8) = "=sum(H2:H" & lngRow - 1 & ")" excWkb.SaveAs EXCEL_FILE excWkb.Close MsgBox "Process complete. I exported a total of " & lngCnt & " appointments were exported.", vbInformation + vbOKOnly, SCRIPT_NAME Set excWks = Nothing Set excWkb = Nothing Set excApp = Nothing Set olkApt = Nothing Set olkLst = Nothing Set olkFld = Nothing End Sub Private Function OpenOutlookFolder(strFolderPath As String) As Outlook.MAPIFolder ' Purpose: Opens an Outlook folder from a folder path. ' Written: 4/24/2009 ' Author: David Lee ' Outlook: All versions Dim arrFolders As Variant, _ varFolder As Variant, _ bolBeyondRoot As Boolean On Error Resume Next If strFolderPath = "" Then Set OpenOutlookFolder = Nothing Else Do While Left(strFolderPath, 1) = "\" strFolderPath = Right(strFolderPath, Len(strFolderPath) - 1) Loop arrFolders = Split(strFolderPath, "\") For Each varFolder In arrFolders Select Case bolBeyondRoot Case False Set OpenOutlookFolder = Outlook.Session.Folders(varFolder) bolBeyondRoot = True Case True Set OpenOutlookFolder = OpenOutlookFolder.Folders(varFolder) End Select If Err.Number <> 0 Then Set OpenOutlookFolder = Nothing Exit For End If Next End If On Error GoTo 0 End Function
This revision requires a list of calendars to export. The list must be composed of the paths to the calendars Kimberly wants to export. In case Kimberly is not familiar with how Outlook folder paths work, here’s an explanation.
A folder path in Outlook is essentially the same as a folder path in the file system. The one difference being that Outlook folder paths do not include a drive letter. The path to a folder is a list of all the folders from the root to the target folder with each folder name separated from the preceding folder name by a backslash (i.e. \). Consider the following folder structure:
Mailbox - Doe, John - Calendar - Inbox - Tasks Personal Folders + Marketing + Proposals + Reviews + Projects + Project 1 + Project 2
The path to “Inbox” is “Mailbox – Doe, John\Inbox”.
The path to “Reviews” is “Personal Folders\Marketing\Reviews”.
The path to “Project 1” is “Personal Folders\Projects\Project 1”.
Revision 3.
This revision is for Phil at LightSpeed Fitness. Phil asked for a version that limits the export to only those appointments with a certain word or phrase in the subject line.
Phil will use the instructions from the original post to add the code to Outlook.
Sub ExportAppointmentsToExcel() Const SCRIPT_NAME = "Export Appointments to Excel (Rev 3)" Dim olkFld As Object, _ olkLst As Object, _ olkApt As Object, _ excApp As Object, _ excWkb As Object, _ excWks As Object, _ lngRow As Long, _ lngCnt As Long, _ strFil As String, _ strFlt As String Set olkFld = Application.ActiveExplorer.CurrentFolder If olkFld.DefaultItemType = olAppointmentItem Then strFil = InputBox("Enter a filename (including path) to save the exported appointments to.", SCRIPT_NAME) If strFil <> "" Then strFlt = InputBox("Enter the string to search the subject for.", SCRIPT_NAME) If strFlt <> "" Then Set excApp = CreateObject("Excel.Application") Set excWkb = excApp.Workbooks.Add() Set excWks = excWkb.Worksheets(1) 'Write Excel Column Headers With excWks .Cells(1, 1) = "Subject" .Cells(1, 2) = "Location" .Cells(1, 3) = "Start Date" .Cells(1, 4) = "End Date" .Cells(1, 5) = "Start Time" .Cells(1, 6) = "End Time" .Cells(1, 7) = "Duration (Minutes)" End With lngRow = 2 Set olkLst = olkFld.Items olkLst.Sort "[Start]" olkLst.IncludeRecurrences = True Set olkRes = olkLst.Restrict("@SQL=" & Chr(34) & "http://schemas.microsoft.com/mapi/proptag/0x0037001E" & Chr(34) & " ci_phrasematch " & "'" & strFlt & "'") 'Write appointments to spreadsheet For Each olkApt In olkRes 'Only export appointments If olkApt.Class = olAppointment Then 'Add a row for each field in the message you want to export excWks.Cells(lngRow, 1) = olkApt.Subject excWks.Cells(lngRow, 2) = olkApt.Location excWks.Cells(lngRow, 3) = Format(olkApt.Start, "mm/dd/yyyy") excWks.Cells(lngRow, 4) = Format(olkApt.End, "mm/dd/yyyy") excWks.Cells(lngRow, 5) = Format(olkApt.Start, "hh:nn AMPM") excWks.Cells(lngRow, 6) = Format(olkApt.End, "hh:nn AMPM") excWks.Cells(lngRow, 7) = olkApt.Duration lngRow = lngRow + 1 lngCnt = lngCnt + 1 End If Next excWks.Columns("A:G").AutoFit excWkb.SaveAs strFil excWkb.Close MsgBox "Process complete. A total of " & lngCnt & " appointments were exported.", vbInformation + vbOKOnly, SCRIPT_NAME Else MsgBox "Operation cancelled. You must enter a search term for this macro to work.", vbCritical + vbOKOnly, SCRIPT_NAME End If Else MsgBox "Operation cancelled. You must enter a filename and path to save the exported appointments to.", vbCritical + vbOKOnly, SCRIPT_NAME End If Else MsgBox "Operation cancelled. The selected folder is not a calendar. You must select a calendar for this macro to work.", vbCritical + vbOKOnly, SCRIPT_NAME End If Set excWks = Nothing Set excWkb = Nothing Set excApp = Nothing Set olkApt = Nothing Set olkLst = Nothing Set olkFld = Nothing End Sub
Revision 4.
I created this revision for a reader named Julien. Julien asked for a version that
- Is triggered by adding an appointment to a calendar
- Exports to an existing workbook (the solution should overwrite the workbook each time)
- Exports from the current date forward
- Only exports appointments belonging to a specified category
This version implements all four of those features. In addition to exporting each time Julien adds an item belonging to the triggering category, it will also export when he edits an item belonging to the category. Unfortunately, the code cannot detect when Julien deletes an item belonging to the category. To handle that, I’m giving Julien a way to manually run the export. If he deletes an item belonging to the category, then he can run the export himself. He’ll do that by running the ManualExport macro.
One caveat. This version only monitors the default calendar. If Julien needs to monitor some other calendar, then I’ll need to modify the code.
The code comes in two parts. This is part #1. Follow these instructions to add this part of the code to Outlook.
- Start Outlook
- Press ALT + F11 to open the Visual Basic Editor
- If not already expanded, expand Microsoft Office Outlook Objects
- Right-click on Class Modules, select Insert → Module
- In the Properties panel click on Name and enter clsCalendarMonitor
- Copy the code from the code snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
- Edit the code as needed. I included a comment where changes are needed or allowed.
- Click the diskette icon on the toolbar to save the changes
'On the next line, edit the number of calendar days to export starting with today Const DAYS_TO_INCLUDE = 90 'On the next line, edit the path to the workbook the solution is to update Const WORKBOOK_PATH = "c:\users\david\documents\testarea\julien.xlsx" 'On the next line, edit the name of the category to key on. The solution will only export appointments that have this category applied. Const CAT_NAME = "Testing" Const SCRIPT_NAME = "Export Appointments to Excel (Rev 4)" Private WithEvents olkFld As Outlook.Items Private Sub Class_Initialize() Set olkFld = Session.GetDefaultFolder(olFolderCalendar).Items End Sub Private Sub Class_Terminate() Set olkFld = Nothing End Sub Private Sub olkFld_ItemAdd(ByVal Item As Object) If InStr(1, Item.Categories, CAT_NAME) > 0 Then ExportAppointmentsToExcel End If End Sub Private Sub olkFld_ItemChange(ByVal Item As Object) If InStr(1, Item.Categories, CAT_NAME) > 0 Then ExportAppointmentsToExcel End If End Sub Public Sub ExportAppointmentsToExcel() Dim olkLst As Object, _ olkRes As Object, _ olkApt As Object, _ excApp As Object, _ excWkb As Object, _ excWks As Object, _ lngRow As Long Set excApp = CreateObject("Excel.Application") Set excWkb = excApp.Workbooks.Open(WORKBOOK_PATH) Set excWks = excWkb.Worksheets(1) excWks.Range("A2:I" & excWks.UsedRange.rows.Count).rows.Delete lngRow = 2 Set olkLst = olkFld olkLst.Sort "[Start]" olkLst.IncludeRecurrences = True Set olkRes = olkLst.Restrict("[Start] >= '" & VBA.Format(Now, "ddddd h:nn AMPM") & "' AND [Start] <= '" & VBA.Format(DateAdd("d", DAYS_TO_INCLUDE, Now), "ddddd h:nn AMPM") & "'") 'Write appointments to spreadsheet For Each olkApt In olkRes 'Only export appointments If olkApt.Class = olAppointment Then If InStr(1, olkApt.Categories, CAT_NAME) > 0 Then 'Add a row for each field in the message you want to export excWks.Cells(lngRow, 1) = olkApt.Categories excWks.Cells(lngRow, 2) = olkApt.Subject excWks.Cells(lngRow, 3) = olkApt.Organizer excWks.Cells(lngRow, 4) = VBA.Format(olkApt.Start, "Short Date") excWks.Cells(lngRow, 5) = VBA.Format(olkApt.End, "Short Date") excWks.Cells(lngRow, 6) = VBA.Format(olkApt.Start, "Long Time") excWks.Cells(lngRow, 7) = VBA.Format(olkApt.End, "Long Time") excWks.Cells(lngRow, 8) = olkApt.RequiredAttendees excWks.Cells(lngRow, 9) = olkApt.OptionalAttendees lngRow = lngRow + 1 lngCnt = lngCnt + 1 End If End If DoEvents Next excWks.Columns("A:I").AutoFit excWkb.Close True Set excWks = Nothing Set excWkb = Nothing Set excApp = Nothing Set olkApt = Nothing Set olkLst = Nothing End Sub
This is part #2 of the code. Follow these instructions to add this portion of the code to Outlook.
- If not already expanded, expand Microsoft Office Outlook Objects and click on ThisOutlookSession
- Copy the code from the code snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
- Click the diskette icon on the toolbar to save the changes
- Close the VB Editor
- Click File and select Options
- When the Outlook Options dialog appears click Trust Center then click the Trust Center Settings button
- Click Macro Settings
- Select either of the two bottom settings (i.e. “Notifications for all macros” or “Enable all macros (not recommended; potentially dangerous code can run)”. The choice of which to choose is up to you. If you select “Notifications”, then you’ll be prompted at times to enable macros. If you pick “Enable all” then there’s a chance that a malicious macro could run. It’s a question of how much risk you want to assume.
- Click Ok until the dialog-boxes have all closed
- Close Outlook
- Start Outlook. If Outlook displays a dialog-box warning that ThisOutlookSession contains macros and asking if you want to allow them to run, say yes.
Dim objCM As clsCalendarMonitor Private Sub Application_Quit() Set objCM = Nothing End Sub Private Sub Application_Startup() Set objCM = New clsCalendarMonitor End Sub Sub ManualExport() objCM.ExportAppointmentsToExcel End Sub
Sir, this code is awesome, it does what has been missing for me, i.e. expanding recurring events. I have spent the last three days trying to find it, and finally asked Google the right question, plus I got away from SharePoint and MS Access and started for Outlook to do it, which helped me find the code here, which, again is awesome.
Ultimately, I will import the data into an Access database which is used for rendering scheduling reports, for further analysis. In order to support this, I need ONLY those appointments with recurrence set, I can’t seem to reference that field appropriately. Also, is there a “key” field or numerical value unique to each main appointment that could be returned?
Respectfully,
Jonathan French
Hi, Jonathan.
Thanks!
Appointment items have a property called IsRecurring which indicates whether the appointment is a recurring item or not. You can eliminate the non-recurring appointments with a test like
I’m not aware of a key field that points to the mater appointment in a series. All the items in the series should share the same ConversationIndex value and GlobalAppointmentID value (if you’re using Outlook 2013 or later). You can identify the master appointment by testing what type of item is its parent. Something like
If the item is one of the recurrences, then TypeName will return “AppointmentItem”.
Firstly can I start by thanking you for pulling this together, making it much easier for me to at least partly carry out the task I have been given – thank you.
Secondly can I ask for advice regarding the Start Date/End Date – I have this code running, and when prompted for the dates I can input them, but the extract still contains dates outside of these? Its no hardship it just means the extraction is slow (due to the large volume of entries) and requires some post export manipulation. Any ideas on a solution would be greatly appreciated.
Thirdly I would like to extract information from custom forms that are built into the appointment and I am all at sea with this one – I have searched for where the information might be saved, and looked for the names of the controls but currently I have no solution – again any assistance would be greatly appreciated.
Regards
Andrew.
Hi, Andrew.
You’re welcome.
Which version of the code are you using?
What does “custom forms” mean in this context? Do you mean a custom Outlook form? If so, how is it “built into the appointment”? If not, please explain what type of form you’re talking about.
Apologies for being a little vague – I was using the second version you posted (Revision 1) and all appears well to start with. I get the message box requesting dates and input the dates that define the period I want information from – however the export to Excel contains all entries for the past 4 years and not those specific to the current financial/reporting year?
With regard to the ‘custom forms’ these are custom fields added to additional pages within the appointment. The template appointment has been edited to capture these fields, however I am unable to retrieve the saved information. The template has been saved to the calendar folder of the shared mailbox with the imaginative title ‘Part VII Contact Form v4’ (not my naming convention I have inherited this).
I have been looking for some script that might loop through the custom controls retrieving their name and then the contents – though anything would be a great help.
Thanks again – Andrew.
Good morning, Andrew.
I just ran Rev 1 on my computer and the date filter worked properly. Have you made any changes to the code? Are you entering the date in the correct format (i.e. mm/dd/yyyy)?
To get the values of the custom controls we have to add code that reads the user-defined properties the controls are connected to. Open the custom form in the form editor and switch to the “All Fields” tab. There you’ll see a list of the user-defined fields in the form. For each user-defined field you’ll have to add this line of code to the macro.
where x is the column you want the value to appear in
user-defined-property-name is the name of one of the user-defined properties in the form
David,
I am not sure if you got my reply (posted last week?)
In response to your questions I have the second version (1st revision) working, but the start/end dates don’t seem to be working for me – this isn’t the end of the world it must be said.
The custom form, however, is a much more pressing task – the form has been created within the appointment (p.2 and p.3) and has a number of fields without any code in the background. the form itself is entitled ‘PartVII contact form v4’ and is saved in the ‘calendar’ folder of a shared mailbox. The controls on the form have the names ‘TextBox1’ etc but field names such as ‘Surname’.
Any assistance would be appreciated.
Hi, Andrew.
I saw your comment. Comment don’t become visible until I approve them, which I don’t normally do until I’m ready to respond. That allows me to keep track of which ones I haven’t replied to yet. Apologies if I seem to be taking a long time. I respond as time and energy permit.
David,
Please accept my apologies – I was beginning to think I hadn’t responded and genuinely questioned myself as there was nothing in the thread to indicate my post was pending etc.
No worries, Andrew. I just wanted you to know why I hadn’t replied yet.
David,
Again can I thank you for taking the time out to investigate and provide a response. I have added the line(s) of code as suggested and unfortunately I am getting a Run-time Error 91 Object variable or With block variable not set – I have checked the references and both Outlook and Excel Object Libraries are checked and I am reaching the limits of my understanding of vba sadly.
Regards
Andrew
Andrew,
Please post the code as it is now. Or email it to me in a .txt file.
Hello, Hopefully this site is still reviewed…I was wondering if you can help update this code to allow for data from a table inserted into a meeting to be pulled.
I manage a shared calendar that sets meetings and inside of that invite is a two column table (below)
control number: 5454696
Employee name: abcdefg
Reason: Nursing
There are also notes (always in red font) in the body of the e-mail, though not required exporting these as well would be helpful.
If not can I also export sentences from the body that may include a specified keyword such as “representation?”
Please advise and thanks in advance for any help!
Hi, Gigi.
Is the data in an actual HTML table, or just in tabular form?
It is in tabular form, can you also add the option to select start and end date?
Gigi,
Do you know what separates the columns in the table? Is it spaces, tabs, or something else?
David, a noble thank you for all your contributions. Just learning Outlook VBAs and these are true gems. Based on your code was trying to export durations of Outlook calendar events which had a UserInput keyword X in either the title or location fields and split the results in 3x sheets (current month, previous month and month before the previous month)
https://codepad.co/snippet/A8VyUaoV
The excel gets created but my code gets stuck at identifying the current folder, do your wizard eyes see where the issue relies? And please set up a PayPal donation button so I can at least offer you a coffee =)
Hi, Juho.
Thanks! I am a coffee lover, addict really, so I’ll definitely think about the donate button.
There are a couple of problems, both a result of the code running from Excel instead of from Outlook. It’s okay to run this from Excel, but doing so means making some changes to the code.
With this code in place, change any Outlook reference to “Application” to olkApp. For example, olkApp.Session.GetDefaultFolder.
Hi David, thank you for the wise words! I did try to write the original code to be run from outlook, but still quite the beginner in this. I edited the code per your suggestions https://codepad.co/snippet/A8VyUaoV and activated the respective object library from excel, it now gives me error “variable not set” so I still probably need to revise the code. Would it be easier for me to edit the code to be run from outlook instead? For others reading this, I recommend checking out the Lynda.com VBA tutorials for self-study
Juho,
What line is the error on now?
Hi David, thanks for responding!
It’s tabular form.
Hi David,
It boggles my mind how easy you make it all sound; I am sure everyone must be very grateful.
Would you be so kind and post another Revision? I need to pull data from two operative’s Outlook diary into multiple Excel work sheets (one for each operative for each month of the year).
I need the subject, date, start time, finish time to be pointed to set columns on the Excel sheet.
If this is at all possible I would greatly appreciate your response.
Thank you very much in advance!
Kind regards,
Reka
Hi, Reka.
I can help with this. Do you want all the sheets in the same workbook or in different workbooks (e.g. one workbook for each operative)? Do you want to export the entire calendar every time or do you want to limit the export to a date range each time?
Great post! Thank you so much! Does anyone know, if there is a way to get Alias or SMTP Address of the organizer, instead of just the display name of the organizer (retrieved via AppointmentItem.organizer)? Any help will be greatly appreciated.
Hi, Ronu.
Thanks!
First, add this code to the code in the post.
Now, to get the organizer’s address instead of their name, change this line
to
Hi, David,
This worked like a charm. Thank you so much! You the man!
I have another question for you. I want to exclude (do not want to export) the cancelled meetings. Do you know, if there is a way I can achieve it?
I truly appreciate your efforts!
Ronu
Hi, Ronu.
You’re welcome!
Cancelled meetings are normally removed from the calendar. Why would a cancelled meeting still be there?
Hi, David,
Thank you for your prompt responses.
I believe, the cancelled meetings are removed automatically if the auto attendant (auto-processing of meeting requests) is enabled on the mailbox. Else, one has to open the cancellation meeting notice received from the meeting’s organizer, and click “Remove from Calendar”.
Hi, Ronu.
There are two ways to accomplish this. First, you can add an IF … THEN statement that checks the value of each item’s MeetingStatus property. If that property is not equal to olMeetingCanceled, then process it. Otherwise, ignore it. Something like this
Hi, David,
Cool. Thank you so much. Let me try it. Again, I truly appreciate your prompt responses and great help!
Hi, David,
I hope you are doing well.
FYI, I tried “If olkApt.MeetingStatus olMeetingCanceled Then (to try to get rid of cancelled meetings), without luck. I will try again and see if I can figure out what I am missing where.
I have another question for you. For the Const CAL_LIST, the name of multiple mailboxes needs to be separated by a comma. This works great if you do not have a comma in the display name of the mailbox, but presents a challenge if you have a comma in the display name. As a workaround, I have added the mailboxes as secondary accounts to the Outlook profile (instead of typical auto-mapping or adding additional mailbox(s) under Advanced tab in Outlook profile), so that the email address of the mailbox is shows in Outlook, instead of it’s display name. I wonder if there is a better way to handle it.
Thank you,
Ronu
Hi, Ronu.
Since that didn’t eliminate the cancelled meetings, then are you sure they’re actually cancelled? Is it possible that the organizer just marked them as cancelled without actually cancelling them?
You don’t have to use a comma as the separator for CAL_LIST. You can use some other character, you just need to change this line
to reflect the character you switch to. For example, if you switch to using the vertical bar (i.e. |) as the separator, then you’d change that line to
Hi, David,
Thank you for the response.
In my test case, I sent a test invite from mailbox A to mailbox B. Accepted the invite in mailbox B. Then opened mailbox A and cancelled the meeting. Then I ran the macro (with the modification you suggested) in mailbox B and got the cancelled invite in the export. Actually, a cancelled meeting will not get removed from the recipient’s mailbox until you open the cancellation notification that’s received, and hit remove from Calendar.
Your separator solution worked like a charm. Thank you so much!
Any idea, how to add a message such as “Processing…” or something while the macro is being run? Just to let the user know that it’s being run.
I truly appreciate your hard word!
Ronu
Hi, Ronu.
I could add code that displays a standard message-box to let the user know the macro is running, but there are a couple of problems with doing that. First, the message-box might appear behind another window. Not much point in a notification the user can’t see. If instead I force the message-box to appear in the foreground, then the macro will stop working until the user clears it. Another approach is to use a user-form. The code would display the user-form when the macro begins running and will clear it when the macro finishes. That’s a better approach but it adds an additional form object that would have to be added to any computer using the solution. Since the user has to take action to run the macro and the macro tells the user when it’s finished, shouldn’t the user already know that the macro is running in the intervening time? If so, then is there really a need for a visual reminder that the macro is running?
HI David, thanks for your hard work on this topic. Revision 1 has proven to be invaluable for me as I have been tasked with creating some analytics surrounding meeting room utilization at my organization. I have heavily modified Rev 1 to pull meeting records from 26 shared meeting room calendars, but what is causing me problems are recurring appointments.
While the code will get recurring appointments, every instance of the appointment will have the same start and end dates. For instance, a meeting that is recurring weekly from May 1st to December 31st will show up 35 times, as it should, all with the same start and end dates, which is should not. What I need is to see the meeting happening on May 1st, then May 8th, 15th, etc.
I have searched high and low for code to get the actual start and end dates of an instance of the appointment rather than the entire set and I have found nothing that works. Do you know any code I could use to solve this problem?
Hi, Kevin.
You’re welcome!
Each iteration of a recurring appointment has its own start and end dates. When I run the code here that’s what I get in the spreadsheet, a different start and end for each iteration. Can you share your modified code with me? If so, perhaps I can figure out what’s going on.
I wanted to follow up and say that I solved my issue with the recurring dates. It still doesn’t make sense to me why it was happening, but if I grab the organizer field AFTER I get the other fields (subject, start, end, creationTime), then I got the correct start and end dates for each instance of the recurring appointment. The same issue seems to happen if I grabbed the list of attendees before the start and end columns.
Hi, Kevin.
How odd. Thanks for sharing this information.
Thanks for your great work!
I think i have the same Problem as <> posted earlier, he got always 0 appointments. nevertheless he commented that he found the solution… “I was able to find the solution, it is working, a little messy but it works.”. Do you know how he did it?
I would like to extract the appointments of our Meeting room on a specific date. The Meeting room is listed in our Companys outlook adress book, like other People are.
Could you please help me?
Hi, MT.
You’re welcome!
No, I’ve no idea what he did to solve the problem he was having. Which version of the code are you trying to use, where is the calendar you’re trying to export (i.e. is it a calendar in your mailbox, someone else’s mailbox, or in a public folder), and what version of Outlook are you using?
Thanks for your reply.
I used the version “Export Appointments to Excel (Rev 1)”. Now it works with one calendar (other Person or room)… but when i mark more then one, just the appointments from the first one are exported.
i think the calendar is in someone else’s mailbox? (not quite sure about that)
I’m using outlook 2016
Hi David,
I like Yours solution esp.Revision 2. It’s work. But I need to use this for the Calendar Gruope whoch I have in my Outlook/calendar. Is it possible? Which path it vwill be in this case? I tryed but nothibg Accept. Actually I need this information from all Room in Our organisation (Exchange 2013).
Thank you
Best regards
Elena
Hi David,
I like this solution esp Revision 2. It’s work. Bui I need to use this for en Calendar Groupe which I have in my calendar. Is it possible? Which path it must be in this case? Actually I need collect information from all Room in Exchange environment. Is it possible?
Tnahk you.
Best regards Elena
David- This post is excellent!!! I can’t thank you enough as your contributions as open source is truly commendable.
I started looking to analyze my time spent in meetings over the last few months as i started facing Bandwidth concerns. It has been ages since i had my hands active on VBA macros and landing your page seriously brought an instant smile! Thank you!
Could you please help me with specific syntax for the below, while i explain why i need them alongside?
1. read the outlook appointments as ‘Accepted’ or ‘Tentative’…there is high likelihood that i havent attended the ‘Tentative’ ones if still exist in my calendar. So, i would like to ignore them from my analysis
2. help me read from the attendees list, to classify as few (individual ids of internal employees), many (invite sent to a Distribution list that appear as @xx), client (that involve mail ids that doesnt look as internal (last name, first name)
3. how do i have read the user mail using the macro than asking the user to enter. In my case, while i could see my name as ‘s, kathiravan’, I would prefer this be read automatically by the code while exporting these from outlook…this will help me analyze if i’m ‘Required’ or ‘Optional’
Thanks.
KT
Hi, KT.
Thank you for those very kind comments.
David,
I am not sure if my last message went through. I still would prefer a report that automates to add new data to the spreadsheet, but I haven’t been able to figure out how to do that.
This is my most recent code. I tried to add a column for color category to the macro, but I keep getting a 438 error. I think I might be using the wrong reference property or enumeration. Is it possible that I cannot access this through VBA because I do not have editorial access to the calendar? It is a shared folder and I have view only permission.
Sub ExportAppointmentsToExcel()
Const SCRIPT_NAME = “Export Appointments to Excel”
Const xlAscending = 1
Const xlYes = 1
Dim olkFld As Object, _
olkLst As Object, _
olkRes As Object, _
olkApt As Object, _
olkRec As Object, _
excApp As Object, _
excWkb As Object, _
excWks As Object, _
lngRow As Long, _
lngCnt As Long, _
strFil As String, _
strLst As String, _
strDat As String, _
datBeg As Date, _
datEnd As Date, _
arrTmp As Variant
Set olkFld = Application.ActiveExplorer.CurrentFolder
If olkFld.DefaultItemType = olAppointmentItem Then
strDat = InputBox(“Enter the date range of the appointments to export in the form “”mm/dd/yyyy to mm/dd/yyyy”””, SCRIPT_NAME, Date & ” to ” & Date)
arrTmp = Split(strDat, “to”)
datBeg = IIf(IsDate(arrTmp(0)), arrTmp(0), Date) & ” 12:00am”
datEnd = IIf(IsDate(arrTmp(1)), arrTmp(1), Date) & ” 11:59pm”
strFil = InputBox(“Express Calendar.xls”, SCRIPT_NAME)
If strFil “” Then
Set excApp = CreateObject(“Excel.Application”)
Set excWkb = excApp.Workbooks.Add()
Set excWks = excWkb.Worksheets(1)
‘Write Excel Column Headers
With excWks
.Cells(1, 1) = “Category”
.Cells(1, 2) = “Organizer”
.Cells(1, 3) = “Created”
.Cells(1, 4) = “Subject”
.Cells(1, 5) = “Location”
.Cells(1, 6) = “Start”
.Cells(1, 7) = “End”
.Cells(1, 8) = “Required”
.Cells(1, 9) = “Optional”
.Cells(1, 10) = “Recurring”
End With
lngRow = 2
Set olkLst = olkFld.Items
olkLst.Sort “[Start]”
olkLst.IncludeRecurrences = True
Set olkRes = olkLst.Restrict(“[Start] >= ‘” & Format(datBeg, “ddddd h:nn AMPM”) & “‘ AND [Start] <= '" & Format(datEnd, "ddddd h:nn AMPM") & "'")
'Write appointments to spreadsheet
For Each olkApt In olkRes
'Only export appointments
If olkApt.Class = olAppointment Then
strLst = ""
For Each olkRec In olkApt.Recipients
strLst = strLst & olkRec.Name & ", "
Next
If strLst “” Then strLst = Left(strLst, Len(strLst) – 2)
‘Add a row for each field in the message you want to export
excWks.Cells(lngRow, 1) = olkApt.olCategoryColorGreen
excWks.Cells(lngRow, 2) = olkApt.Organizer
excWks.Cells(lngRow, 3) = olkApt.CreationTime
excWks.Cells(lngRow, 4) = olkApt.Subject
excWks.Cells(lngRow, 5) = olkApt.Location
excWks.Cells(lngRow, 6) = olkApt.Start
excWks.Cells(lngRow, 7) = olkApt.End
excWks.Cells(lngRow, 8) = olkApt.RequiredAttendees
excWks.Cells(lngRow, 9) = olkApt.OptionalAttendees
excWks.Cells(lngRow, 10) = olkApt.IsRecurring
lngRow = lngRow + 1
intCnt = intCnt + 1
End If
Next
excWks.Columns(“A:I”).AutoFit
excWkb.SaveAs strFil
excWkb.Close
MsgBox “Process complete. A total of ” & intCnt & ” appointments were exported.”, vbInformation + vbOKOnly, SCRIPT_NAME
End If
Else
MsgBox “Operation cancelled. The selected folder is not a calendar. You must select a calendar for this macro to work.”, vbCritical + vbOKOnly, SCRIPT_NAME
End If
Set excWks = Nothing
Set excWkb = Nothing
Set excApp = Nothing
Set olkApt = Nothing
Set olkLst = Nothing
Set olkFld = Nothing
End Sub
Hi, Kristin.
Yes, I saw your other post. Posts don’t become visible until I approve them and I don’t normally do that until I’m ready to respond to the post.
To get the categories change this line
to
I am a real newbie at this! I currently using version 1 and modified it just a bit. I want it to update when I open the excel workbook instead of outlook and I want it to simply insert new rows for new data, rather than overwrite the file by running the macro through VBA with the calendar open. Can you help me achieve this?
Hi, Kristin.
Yes, I can help with this. Before doing so though, you need to decide on some sort of limit for the export. By “limit” I mean some condition that restricts the appointments being exported on each run. For example, you might want to limit the export to just those appointments that have a start date greater than the start dart of the last export. If you don’t establish a limit, then the solution is going to export every appointment on every run. If the target calendar has 1,000 appointments, then every time you open the spreadsheet it’s going to export those same 1,000 appointments. That doesn’t strike me as being very useful.
So, what I have done is I have created a file that I am overwriting, and then turned that excel file (Express Calendar.xls) into a dqy and then an odc file connection to another spreadsheet with a table (Data – Express Plan Review Calendar.xls) that will I plan to create pivots from for the analytics. Right now, the entire data set overwrites to the original file. Its not a bad way of doing it…. but I would rather use a simple odbc data connection that will populate the data directly to the workbook I will be working in (Data – Express Plan Review Calendar.xls).
I have added this code for the date range, but for some reason it is not pulling data past 5/24 when I ran the VBA this morning. I want the data to refresh with all old appointments and any new appointments out 4 weeks from today.
strDat = InputBox(“07/01/2014 to 06/01/2016″, SCRIPT_NAME, Date & ” to ” & Date)
arrTmp = Split(strDat, “to”)
datBeg = IIf(IsDate(arrTmp(0)), arrTmp(0), Date) & ” 12:00am”
datEnd = IIf(IsDate(arrTmp(1)), arrTmp(1), Date) & ” 11:59pm”
strFilename = InputBox(“Express Calendar.xls”, SCRIPT_NAME)
Hi, Kristin.
In your first post you mentioned wanting to “insert new rows for new data”. Are you saying that you’ve changed your mind and want to overwrite each time?
No. I have just developed work arounds so I can access the data. I also just realized that I need to include a column that shows categories. The events on the calendar are categorized by color which correlates with appointment types.
I’m just looking to export dates days with no appointment between 9:00 and 17:00 on a period of 2 months from the date excluding Saturdays and Sundays and send the result to the clipboard
Is that possible for you?
Thank you
Hi, deboyo.
How would you like the output formatted?
Hello,
Thank you for your reply
I would like a DD / MM / YYYY , followed by a carriage return all classified in ascending order
example:
28/04/2016
29/04/2016
02//042016
…..
cordially
Deboyo,
That’s all you want, the appointment date?
Hi, just poking my nose in as I follow this forum with interest.
deboyo wants the dates with NO appointments, hence there is nothing else to provide as they are empty periods.
Got it. Thanks.
Hi David,
Sorry for this late reply, but was really busy with my coding which is still not finished. I am making a new comment instead of replying in old comment.
I am sharing my almost final code which is combination of different codes from internet and yours.
Now I have a small issue with it, Everything is working good, but when I have freshly booting my computer and when I run the code the first time, it take like 5 minutes to get data and outlook stop to react.
I also see a small popup in task bar saying Outlook is trying to connect to exchange server etc….
But when I ran the 2nd time it take 1 second to bring all data. In both cases my Outlook was Open. I repeated the above scenario 100 times and it is always same.
I will appreciate if you could help debug my code and tell my a way to accelerate things. It is really annoying to have to wait 5 minutes just to pull data from outlook.
Thanks in advance
Here is the code (modified some part which were confidentials) :
Hi, JhonP.
There’s too much code missing for me to figure out what is going on. For example, the code references an object named Outlook on line 48, but I don’t see where that object is created. Line 59 builds what I assume is the filter you apply to the calendar, but I do not see a Find or Restrict applying it. Lines 85 and 89 suggest that there is an IF statement someone above them, but the only IF statement I see is on line 62 and it is a complete IF … THEN clause.
The above aside, my best guess is that the first run forcing Outlook to query the server. That run probably synchronizes the information to the local computer and all subsequent runs hit the copy on the local computer. Here is a test to try that might confirm my hypothesis. Open Outlook then open the public calendar. Do something on the calendar (for example open an item). Now run the code and see how long it takes. I am thinking that opening the calendar and doing something on it will force Outlook to read and cache the calendar. If it does, then the first run should be much faster.
Thanks for the tip, I will test it tomorrow as for now even after rebooting it is fast, I think it is just the first run of morning. So if the issue the synchronization, what should I do to make it quicker for 1st run ? anything to put in code ?
I don’t understand why there are missing parts in my post I just copy pasted, only thing I modified was calendar and company name.
Here is code again I hope this time you can get it in full, otherwise tell me how to share it
Sub GetApptsFromOutlook()
Dim SDate As Date
Dim EDate As Date
SDate = Format(Now, “yyyy/mm/dd”)
‘EDate = SDate + 1
Application.ScreenUpdating = False
Call GetCalData(SDate, SDate)
Application.ScreenUpdating = True
End Sub
Private Sub GetCalData(StartDate As Date, Optional EndDate As Date)
‘ ————————————————-
‘ Notes:
‘ If Outlook is not open, it still works, but much slower (~8 secs vs. 2 secs w/ Outlook open).
‘ Make sure to reference the Outlook object library before running the code
‘ End Date same as Start if you want to pull from only one day
‘ ————————————————-
Dim myCalItems As Object
Dim ItemstoCheck As Object
Dim ThisAppt As Object
Dim MyItem As Object
Dim StringToCheck As String
Dim MyBook As Workbook
Dim rngStart As Range
Dim NextRow As Long
Dim oNs As Namespace
Dim mpiFolder As MAPIFolder
Dim LastRow
Dim LastRow2
Worksheets(“Temp2”).Visible = True
Worksheets(“Temp2”).Activate
‘clean up
Cells.Select
Selection.Delete Shift:=xlUp
Range(“A1”).Select
On Error Resume Next
Set oNs = Outlook.GetNamespace(“MAPI”)
Set mpiFolder = oNs.GetDefaultFolder(olPublicFoldersAllPublicFolders)
Set mpiFolder = oNs.GetDefaultFolder(olPublicFoldersAllPublicFolders).Folders(“my company “).Folders(“Departement – Calendrier”)
Set myCalItems = mpiFolder.Items
With myCalItems
.Sort “[Start]”, False
.IncludeRecurrences = True
End With
StringToCheck = “[End] >= ” & Quote(StartDate & ” 00:01″) & ” AND [Start] 0 Then
‘ we found at least one appt
‘ check if there are actually any items in the collection, otherwise exit
If ItemstoCheck.Item(1) Is Nothing Then GoTo ExitProc
Set MyBook = ThisWorkbook
Set rngStart = Worksheets(“Temp2”).Range(“A1”)
With rngStart
.Offset(0, 2).Value = “End Time”
.Offset(0, 1).Value = “Start Time”
.Offset(0, 0).Value = “Subject”
End With
For Each MyItem In ItemstoCheck
Set ThisAppt = MyItem
NextRow = Range(“A” & Rows.count).End(xlUp).Row
With rngStart
.Offset(NextRow, 2).Value = Format(ThisAppt.End, “YYYY/MM/DD hh:mm”)
.Offset(NextRow, 1).Value = Format(ThisAppt.Start, “YYYY/MM/DD hh:mm”)
.Offset(NextRow, 0).Value = Trim(ThisAppt.Subject)
End With
Next MyItem
Else
MsgBox “There are no appointments or meetings during” & _
“the time you specified. Exiting now.”, vbCritical
Exit Sub
End If
ExitProc:
Set myCalItems = Nothing
Set ItemstoCheck = Nothing
Set rngStart = Nothing
Set ThisAppt = Nothing
Set oNs = Nothing
Set mpiFolder = Nothing
End Sub
Function Quote(MyText)
Quote = Chr(34) & MyText & Chr(34)
End Function
Hi, JhonP.
If the issue is synchronization, then there is no code-based solution, or none that I know of. Follow the steps in the this Microsoft article to make sure that you are caching the public folder in question to your computer. If the folder is being cached, then I don’t know of any way to speed up the synchronization process.
I checked it and the cache option is not active. So what can be the issue ?
Hi, John.
If Outlook isn’t using cached mode, then every read operation takes place across that network. That’s going to be slow. You should consider enabling cached mode if possible.
Hi David,
You code is awesome. I adopt it for a project I am working on and try to figure how to get this to work against a collection of PST files. I basically need to export calendar items from each of the PST files into an excel file.. I am a little fuzzy as to how to open PST files instead of outlook folder.
Thanks so much
Hi, Sakura.
Thank you!
For calendars in multiple PST files I recommend that you use Revision 2. It’s written to take a list of calendars and export each member in that list. The list of calendars is defined on line #3. For each calendar you need the path to the calendar. For calendars in a PST file that path would be something like “PSTFile\Calendar,PSTFile\Calendar” where “PSTFile” is the name of the PST file as it appears in Outlook.
Congratulations, David. This is a very useful post!
Although I’m just a beginner in the Visual Basic world, mainly in Excel, and not in Outlook, I’ve been trying to work from your code. But, as I’m a beginner, I’ve got stuck, and that’s why maybe I’m going to ask some easy questions. Excuseme for that, but I’d be very grateful if you could help me. To begin with, I would point these three main doubts:
1. What I need is to build a code mix of the previous you provided. I’d like to export several calendars appointments, shared only with read permission. Is that possible? I haven’t been able to identify what the folder path should be in this case. I have used version 1 with this kind of calendars and it works, so I guess it could be possible, but can’t find the proper path.
2. As I’m Spanish, the format of the dates is different (dd/mm/yyyy). I’d like to change this, because I’d like to use the feature of the Rev 1 to consider only the appointments falling within a date range, but the format is driving me mad: not only in the dialog-box caption, but also in the interpretation made from the original data (the results exported are not well-formated about the date). Could you help me on this?
3. On the other hand, I’d like to extract only certain appointments identified by a certain text String in the subject field.
All this information should be exported to the same excel file every time the macro is executed, rewritting the previous.
Could you help me with the code or at least give me any hint to keep on working on it?
Thank you very much in advance!
Hi, jajugon.
Thanks!
1. Are the appointments on another user’s calendar or are they on a calendar in a public folder?
2. I can change the date formatting.
3. That’s simple enough. All we need to do is add an “IF … THEN” statement to filter on the subject.
The code below takes care of items 2 and 3. Let me know the answer to my question about your first item and I’ll make the necessary adjustments to handle that too.
First of all, thank you very much.
Answering the first point, the appointments are on another user’s calendar, which was shared with read permission.
Willing to see if it works as I’d like 🙂
Thanks again.
Hi, jajugon.
Please select the other user’s calendar and then run the code. Let me know if that works. If it does, then we can optionally hard-code the path the other user’s calendar into the code so you don’t have to select it each time you run the script.
Great David! The code works!
I’ve had some problems about the permissions needed to execute it on a shared calendar by other user, but I finally got it! Thanks a lot!
As mentioned, I’d like to improve it selecting different calendars with a given path. Nevertheless, it would be more important to make the filter on the subject field no case sensitive. In fact I’d like to extract all the appointments whose subject field contains at least a certain text String.
I’ll keep on searching through the Internet, but any hint will be very helpful!
Thanks!
Hi, jajugon.
To make the subject field search case insensitive change line 54 of the code from
to
Great David. Thank you very much again.
Would you kindly tell me how to introduce the shared calendar path in the code?
Thanks in advance.
Hi, jajugon.
You need to make two changes to the existing code in order to hard code the path to the shared calendar into the solution. First, add this code to what you already have.
Second, change line 23 from
to
Replace “Path_to_shared_calendar” with the actual path to the shared calendar. If you aren’t familiar with Outlook folder paths, then the quickest way to get the folder path is to use the code below. Once you’ve added that code to Outlook, select the folder then run that macro. It will display the folder path in a dialog-box.
Thanks David.
I have followed your indications, but when executing the code to obtain the path to the shared calendar I obtain a huge string as:
“000000000BD9C1E9306442CEA56EDB2C1E4AB6E60C000000380000003800000036000000CD6BC6D801E5024AB98666A22076AA1047BFFBA458F59E4595A9AA82667EC0BE9D00000000000000DCA740C8C042101AB4B908002B2FE18201000000000000002F6F3D45786368616E6764C6162732F6F753D45786368616E”
When I try to do the same with my own calendar I obtain a reasonable path like:
“\\name.surname@domain.es\Calendar”
I’ve even tried to replace the “Path_to_shared_calendar” value with the huge string, but I get an error anyway,
Any idea?
Thanks!
Hi, jajugon.
This is a shared calendar in a another mailbox, right? Not one in a public folder?
That’s right. Any unsolvable problem?
Thanks!
No. Just want to make sure I have the facts right. Is it the default calendar in the other mailbox?
Yes!
Okay. We need to change line #23 again. Change it from
to
Hi,
Thanks for sharing these code and nice to see you adopt them with people requests 🙂
I hope you can help me too.
First thing, I want the code to be in Excel and not Outlook. Because I have a macro that is ran in Excel and I want to bring info from Outlook Calendar.
In one of My Excel sheet name Availabilty, I have name of people that are also in Global list of Outlook. When I run the macro in Excel I want the macro to bring for the TODAY date the schedule of each people in the list . Is this possible to do ?
Thanks
Hi, John.
You’re welcome!
Do you have access to everyone’s calendar in Outlook? You must have for this to work in the way you’ve described.
By access you mean if I can open calendar of person and see his/her schedule ? Yes I do have that.
Thanks in advance for your help 🙂
Ok we decided to have a Group Calendar in order to avoid giving access to everyone’s calendar to people who will run the Macro. So in this calendar we have schedule of each person. What I will need is bring info from this calendar called “Work Load” for Today date and put it in a Worksheet. Then I will do all other stuff by the Macro myself as data will be already in Excel. So no need to look for calendar of each person in Outlook anymore.
Thanks again for all your help 🙂
Hi, John.
Please try this version. It is written to run from Excel. Outlook must be open and the shared calendar selected before running this macro.
Thanks David, No matter what Calendar I select (even my own) it give message 0 appointment were exported. (I have a lot of appointments in my calendar for today)
Also isn’t there a way to give fix name for Calendar we want to extract data from ? As this will be use by multiple persons and Selecting manually will not be user friendly.
Hi, John.
The code definitely works. I just tested again by running it against my calendar and it exported all of today’s appointments. Tell me more about your setup. What version of Windows are you using? What version of Outlook?
Yes, we can hard-code the folder the solution is to export from into the code. Will the path be the same for every person or will it vary from one person to the next?
It is WIndows 7 Prof, Outlook and Excel 2010. Calendar is from Public folders, address seem to add my email address in it, so I believe with each user it will add their email address ?
But your code I tested on my own default non shared calendar and it still say 0 appointments.
I used the following code and it do bring all the data from my own default calendar
Private Sub Get_Appoinments()
Dim mybk As Workbook
Dim FolderCal As Outlook.Folder
Dim ItemsApt As Outlook.Items
Dim appt As Outlook.AppointmentItem
i = 1
Set mybk = ThisWorkbook
Set FolderCal = Outlook.Application.GetNamespace(“MAPI”).GetDefaultFolder(olFolderCalendar)
Set ItemsApt = FolderCal.Items
For Each appt In ItemsApt
mybk.Sheets(1).Cells(i, 1) = appt.Start
mybk.Sheets(1).Cells(i, 2) = appt.End
mybk.Sheets(1).Cells(i, 3) = appt.Subject
mybk.Sheets(1).Cells(i, 4) = appt.Location
mybk.Sheets(1).Cells(i, 5) = appt.Duration
mybk.Sheets(1).Cells(i, 6) = appt.Size
‘mybk.Sheets(1).Cells(i, 7) = appt.Body
i = i + 1
Next
MsgBox “OutLook Appointments Retrieved”
End Sub
Hi David.
I posted a reply yesterday but for some reason it is not showing up,
I am using Windows 7 Pro and Outlook and Excel 2010.
Also I used another code that bring data from my defaul calendar and it is working with no issue. But your code give message 0 appointement exported
here is the code that is wokring:
Private Sub Get_Appoinments()
Dim mybk As Workbook
Dim FolderCal As Outlook.Folder
Dim ItemsApt As Outlook.Items
Dim appt As Outlook.AppointmentItem
i = 1
Set mybk = ThisWorkbook
Set FolderCal = Outlook.Application.GetNamespace(“MAPI”).GetDefaultFolder(olFolderCalendar)
Set ItemsApt = FolderCal.Items
For Each appt In ItemsApt
mybk.Sheets(1).Cells(i, 1) = appt.Start
mybk.Sheets(1).Cells(i, 2) = appt.End
mybk.Sheets(1).Cells(i, 3) = appt.Subject
mybk.Sheets(1).Cells(i, 4) = appt.Location
mybk.Sheets(1).Cells(i, 5) = appt.Duration
mybk.Sheets(1).Cells(i, 6) = appt.Size
mybk.Sheets(1).Cells(i, 7) = appt.Body
i = i + 1
Next
MsgBox “OutLook Appointments Retrieved”
End Sub
Hi, John.
Replies don’t show up until I approve them. I don’t normally do that until I’m ready to respond.
Hi David,
After doing hours and hours of search on Google I was able to have a code that is working, it is mix of your code and some other stuff from internet. Right now the code is complete mess as I have been testing it, so I can’t share the code here right now.
I just have 1 issue that is making me pull my hair, as you are very good with VBA and Outlook I wonder if you can solve this issue then I willl do a cleanup of my code.
When I use .Restrict to limit my appointment to just TODAY date, it works but it do not bring the appointments that are on multiple days. For example there is an employee who is on holidays from 12th March to 24th March, which fell into Today date, but the code is not listing this appointment. I tested by adding more multiday appointments and it never bring these appointments.
Do you have any idea what to add to allow these appointment to be added in .Restrict too ?
Thanks a lot for all your help 🙂
Hi, John.
As I noted earlier, the code works perfectly for me. I don’t know why it’s not working on your computer. I’d be curious to see the version that is working so I can compare it to my version and see what the differences are.
Here are the two lines of code you need to add to include recurring appointments. These lines go immediately before the .Restrict command.
I was able to find the solution, it is working, a little messy but it works.
I will still be interested to see your code if you can post it.
Thanks again for all your help 🙂
Hi,
The functions on this page are excellent, I have am so close with a combination of a few of them. All I need to do is export all the items in approx 30 shared calendars. The one you did for Julien was close for me as I believe I need the line – Set olkFld = Session.GetFolderFromID(“String”).Items, as the folder name of the shared calendars is the long string of letters and numbers. The format it is exported into is not an issue, I just need to loop through all the calendars and export all the details.
Is this one an easy fix? i have tried all day and am so close!
Thanks 🙂
Hi, Gareth.
Are you sure about wanting to use Rev 4, the version I created for Julien? It’s designed to export appointments as they’re created. Doing that for 30 shared calendars may not work very well.
First of all, thank you very much.
Answering the first point, the appointments are on another user’s calendar, which was shared with read permission.
Willing to see if it works as I’d like 🙂
Thanks again.
Hi David, i found out that it was a shared calendar.
Now it works, i used the Rev1 and replaced these code:
<>
with
<>
Thanks again!
Hi, MT.
Glad it’s working for you.
Hi David,
Your code is very helpful. I used Revision 1, added a few columns and it’s working fine. Is it possible to add a column that indicates whether or not it is a recurring appointment?
The code is as follows:
Sub ExportAppointmentsToExcel()
Const SCRIPT_NAME = “Export Appointments to Excel (Rev 1)”
Const xlAscending = 1
Const xlYes = 1
Dim olkFld As Object, _
olkLst As Object, _
olkRes As Object, _
olkApt As Object, _
olkRec As Object, _
excApp As Object, _
excWkb As Object, _
excWks As Object, _
lngRow As Long, _
lngCnt As Long, _
strFil As String, _
strLst As String, _
strDat As String, _
datBeg As Date, _
datEnd As Date, _
arrTmp As Variant
Set olkFld = Application.ActiveExplorer.CurrentFolder
If olkFld.DefaultItemType = olAppointmentItem Then
strDat = InputBox(“Enter the date range of the appointments to export in the form “”mm/dd/yyyy to mm/dd/yyyy”””, SCRIPT_NAME, Date & ” to ” & Date)
arrTmp = Split(strDat, “to”)
datBeg = IIf(IsDate(arrTmp(0)), arrTmp(0), Date) & ” 12:00am”
datEnd = IIf(IsDate(arrTmp(1)), arrTmp(1), Date) & ” 11:59pm”
strFil = InputBox(“Enter a filename (including path) to save the exported appointments to.”, SCRIPT_NAME)
If strFil “” Then
Set excApp = CreateObject(“Excel.Application”)
Set excWkb = excApp.Workbooks.Add()
Set excWks = excWkb.Worksheets(1)
‘Write Excel Column Headers
With excWks
.Cells(1, 1) = “Organizer”
.Cells(1, 2) = “Created”
.Cells(1, 3) = “Subject”
.Cells(1, 4) = “Starting Date”
.Cells(1, 5) = “Ending Date”
.Cells(1, 6) = “Start Time”
.Cells(1, 7) = “End Time”
.Cells(1, 8) = “Hours”
.Cells(1, 9) = “Attendees”
End With
lngRow = 2
Set olkLst = olkFld.Items
olkLst.Sort “[Start]”
olkLst.IncludeRecurrences = True
Set olkRes = olkLst.Restrict(“[Start] >= ‘” & Format(datBeg, “ddddd h:nn AMPM”) & “‘ AND [Start] <= '" & Format(datEnd, "ddddd h:nn AMPM") & "'")
'Write appointments to spreadsheet
For Each olkApt In olkRes
'Only export appointments
If olkApt.Class = olAppointment Then
strLst = ""
For Each olkRec In olkApt.Recipients
strLst = strLst & olkRec.Name & ", "
Next
If strLst “” Then strLst = Left(strLst, Len(strLst) – 2)
‘Add a row for each field in the message you want to export
excWks.Cells(lngRow, 1) = olkApt.Organizer
excWks.Cells(lngRow, 2) = olkApt.CreationTime
excWks.Cells(lngRow, 3) = olkApt.Subject
excWks.Cells(lngRow, 4) = Format(olkApt.Start, “mm/dd/yyyy”)
excWks.Cells(lngRow, 5) = Format(olkApt.End, “mm/dd/yyyy”)
excWks.Cells(lngRow, 6) = Format(olkApt.Start, “hh:nn ampm”)
excWks.Cells(lngRow, 7) = Format(olkApt.End, “hh:nn ampm”)
excWks.Cells(lngRow, 8) = DateDiff(“n”, olkApt.Start, olkApt.End) / 60
excWks.Cells(lngRow, 8).NumberFormat = “0.00”
excWks.Cells(lngRow, 9) = strLst
lngRow = lngRow + 1
lngCnt = lngCnt + 1
End If
Next
excWks.Columns(“A:H”).AutoFit
excWks.Range(“A1:I” & lngRow – 1).Sort Key1:=”Organizer”, Order1:=xlAscending, Header:=xlYes
excWks.Cells(lngRow, 7) = “=sum(G2:G” & lngRow – 1 & “)”
excWkb.SaveAs strFil
excWkb.Close
MsgBox “Process complete. A total of ” & lngCnt & ” appointments were exported.”, vbInformation + vbOKOnly, SCRIPT_NAME
End If
Else
MsgBox “Operation cancelled. The selected folder is not a calendar. You must select a calendar for this macro to work.”, vbCritical + vbOKOnly, SCRIPT_NAME
End If
Set excWks = Nothing
Set excWkb = Nothing
Set excApp = Nothing
Set olkApt = Nothing
Set olkLst = Nothing
Set olkFld = Nothing
End Sub
Thanks!
Hi, YHL.
Yes, that’s possible. The property name you want is IsRecurring. For example
Hi David,
Great article indeed. It is not easy to find this topic so well described. At least for me this is the first one.
Could you please advise if it’s possible to download details from shared calendars by Microsoft Exchange? I was trying to get path of one (using your macro from last comments). I got a long numeric something, which doesn’t seem to be a path.
Unfortunately I’m not able to copy the calendars to my outlook, as there are some private items.
I just know the manual walk-around for this (changing view to a list and copy pasting to Excel).
Hope it has not been already discussed. I was trying to find the answer in comments, but I was not able to go through all of them.
Kind regards,
Wojtek
Hi, Wojtek.
When you say “shared calendars” do you mean a calendar in a public folder? If not, what does “shared calendars” mean in this context?
Hi David,
Exactly, I meant calendars in a public folder.
In the folder list view I am able to locate PublicFolder_Calendars in Public Folders, however when I click on it the message “Cannot display the folder” appears.
Nevertheless I can see all shared calendars in the Calendar view.
Is it possible to automatically export data from public calendars to Excel file?
Kind regards,
Wojtek
Hi, Wojtek.
Yes, the code will export from whatever calendar you have open when you run the macro.
Hi, Great Post. I am not sure If I am incorrectly trying to utilize your code or if it is an enhancement but whenever I am using the code the events with one occurrence work great; however, the recurring events only pull the first instance. Is that a user issue or an enhancement request?
Hi, Daniel.
Thanks!
Which version of the code are you using?
David,
Awsome information you posted. Thank you very much!! One question I had is that is it possible to export recurring calendar events to excel ?
Hi, Terry.
Thanks!
Yes. Assuming that you mean you want to export recurring events in addition to non-recurring events, then the code already does that. If instead you mean that you only want to export recurring events, then that’s possible too but I’ll need to make a change to the code to make that happen.
David,
Regarding my use of Revision 2….. I resolved the calendar path problem. It turns out I had to use a capital letter in Calendar when referencing it as part of the overall path…
I tested out Revision 2 and it works well. It would really be helpful, however, if I could have a few modifications to the output of information in the Excel spreadsheet, please. Specifically, I only need the following categories, in this order:
Subject
Start Date
Start Time
End Time
I attempted to make changes myself, but I quickly discovered that all the outputs are “intertwined,” so that if I eliminated one thing or changed the order, things fell apart.
Again, I would really appreciate your help on this, please. Thanks.
Greg
Hi, Greg.
This should do it. Only replace the ExportAppointmentsToExcel subroutine. Leave the rest of the code as is.
David,
I am attempting to use Revision #2 of this macro. The example you provide for the Outlook path format to enter into the macro for the folder does not work. I typed the following in the macro, with T102 being the name of the Outlook account/calendar:
“Mailbox – T102\Inbox”
I get the message that the macro cannot find a folder with that name. What am I missing? I appreciate your help. Thanks.
Hi, Greg.
Add this code to Outlook.
Once you’ve done that, select the target folder and run the DsiplayFolderPath macro. It will display the path to the currently selected folder. That’s the path to use in Revision #2.
Hi David,
Happy New Year!
I found all your posts on this thread to be very helpful – awesome stuff!
I’m actually currently putting one of the macros you posted here to good use but was wondering if you’d be able to help me make a few modifications to it. I already made a few tweaks to the code but got stuck when trying to add more functionalities to it and I’d appreciate any help I can get from you.
The code, which I’ll paste at the end of my message, reads my outlook calendar and exports all the appointments and their lengths into the correct column which is arranged by month and category of the appointment. Here are some other things I want it to do; let me know if any of the following is possible:
1) Each month column is currently split into 2 sub columns that indicate the category of the appointment, Call or In-Person Meeting. Is it possible to make the macro add 3 sub columns under each month that read “Call”, “Review” and “In-Person Meeting”?
2) The macro currently looks at the category of the appointment. If the appointment does not have a category assigned to it, the macro reads it as if it has the “Call” category assigned to it. I want the macro to consider a third category called “Review” and spit out the length of the appointment that has the category “Review” into the corresponding new sub column that I mentioned in #1 I want to add under each month. Can we do that? And the appointments that do not have a category I don’t mind if the macro continues to default it as a “Call”, you can leave that part as it is.
3) Can you make the macro spit out the category of the appointment into a separate column?
4) Each appointment in my outlook has an ID number at the end of the appointment’s name (the ‘subject’ field of the appointment). Can you make the macro spit out the ID number into a separate column? So, say the subject of the appointment reads, “Meeting in Chicago with Peter ID: 6778779”. I want the macro to read the subject and spit out everything after the colon into a separate column i.e. spit out “6778779”. I’d prefer, if possible, to have this column be the first column on the excel sheet right before the column that would have the name of the appointments.
5) When I run this macro, it prompts me to specify the date range that I would like the macro to export. Can you have the macro mention somewhere on the excel sheet the date range that I entered?
6) Some appointments on my calendar are reoccurring appointments. Currently, the macro reads a recurring appointment as if that appointment only occurred once – the first date in the series. So say I create a recurring appointment that would occur the third Monday of every month starting on December 21st. The macro only reads that as if it took place once on December 21st and would spit out the time of that appointment into the December column but not in every other month as it should since it’s recurring. Can you fix that and make the macro account for every time the recurring appointment actually appears on the calendar and not only the first time it occurs?
Apologies if this post is too overwhelming – I would really appreciate it if you let me know if this is all possible!
Thanks in advance, David!
Best,
Steve
Here’s the macro I’m using:
Sub ExportAppointmentsToExcel()
Const SCRIPT_NAME = “Export Appointments to Excel (Rev 1)”
Const xlAscending = 1
Const xlYes = 1
Dim olkFld As Object, _
olkLst As Object, _
olkRes As Object, _
olkApt As Object, _
excApp As Object, _
excWkb As Object, _
excWks As Object, _
lngRow As Long, _
lngCnt As Long, _
strFil As String, _
curCli As String, _
strDat As String, _
datBeg As Date, _
datEnd As Date, _
arrTmp As Variant, _
i As Long, _
callOrMeet As Integer, _
col As Long
Set olkFld = Application.ActiveExplorer.CurrentFolder
If olkFld.DefaultItemType = olAppointmentItem Then
strDat = InputBox(“Enter the date range of the appointments to export in the form “”mm/dd/yyyy to mm/dd/yyyy”””, SCRIPT_NAME, Date & ” to ” & Date)
arrTmp = Split(strDat, “to”)
datBeg = IIf(IsDate(arrTmp(0)), arrTmp(0), Date) & ” 12:00am”
datEnd = IIf(IsDate(arrTmp(1)), arrTmp(1), Date) & ” 11:59pm”
strFil = InputBox(“Enter a filename (including path) to save the exported appointments to.”, SCRIPT_NAME)
If strFil “” Then
Set excApp = CreateObject(“Excel.Application”)
Set excWkb = excApp.Workbooks.Add()
Set excWks = excWkb.Worksheets(1)
‘Write Excel Column Headers
With excWks
.Cells(1, 1) = “Client”
.Cells(1, 2) = “January”
.Cells(1, 4) = “February”
.Cells(1, 6) = “March”
.Cells(1, 8) = “April”
.Cells(1, 10) = “May”
.Cells(1, 12) = “June”
.Cells(1, 14) = “July”
.Cells(1, 16) = “August”
.Cells(1, 18) = “September”
.Cells(1, 20) = “October”
.Cells(1, 22) = “November”
.Cells(1, 24) = “December”
For i = 2 To 24 Step 2
.Range(.Cells(1, i), .Cells(1, i + 1)).Merge
.Cells(1, i).HorizontalAlignment = xlCenter
.Cells(2, i) = “Call”
.Cells(2, i + 1) = “In Person”
Next i
End With
lngRow = 2
Set olkLst = olkFld.Items
olkLst.Sort “[Subject]”
olkLst.IncludeRecurrences = True
Set olkRes = olkLst.Restrict(“[Start] >= ‘” & Format(datBeg, “ddddd h:nn AMPM”) & “‘ AND [Start] <= '" & Format(datEnd, "ddddd h:nn AMPM") & "'")
curCli = ""
'Write appointments to spreadsheet
For Each olkApt In olkRes
If olkApt.AllDayEvent True Then
‘Only export appointments
If olkApt.Class = olAppointment Then
If curCli olkApt.Subject Then
curCli = olkApt.Subject
lngRow = lngRow + 1
excWks.Cells(lngRow, 1) = olkApt.Subject
End If
callOrMeet = 0
If olkApt.Categories = “In-Person Meeting” Then callOrMeet = 1
col = Month(olkApt.Start) * 2 + callOrMeet
‘Add a row for each field in the message you want to export
If excWks.Cells(lngRow, col) = “” Then
excWks.Cells(lngRow, col) = DateDiff(“n”, olkApt.Start, olkApt.End) / 60
Else
excWks.Cells(lngRow, col) = excWks.Cells(lngRow, col) + DateDiff(“n”, olkApt.Start, olkApt.End) / 60
End If
lngCnt = lngCnt + 1
End If
End If
Next
excWks.Columns(“A:M”).AutoFit
‘excWks.Range(“A1:H” & lngRow – 1).Sort Key1:=”Category”, Order1:=xlAscending, Header:=xlYes
‘excWks.Cells(lngRow, 7) = “=sum(G2:G” & lngRow – 1 & “)”
excWkb.SaveAs strFil
excWkb.Close
MsgBox “Process complete. A total of ” & lngCnt & ” appointments were exported.”, vbInformation + vbOKOnly, SCRIPT_NAME
End If
Else
MsgBox “Operation cancelled. The selected folder is not a calendar. You must select a calendar for this macro to work.”, vbCritical + vbOKOnly, SCRIPT_NAME
End If
Set excWks = Nothing
Set excWkb = Nothing
Set excApp = Nothing
Set olkApt = Nothing
Set olkLst = Nothing
Set olkFld = Nothing
End Sub
Happy New Year, Steve.
Everything you described sounds doable. The only thing I’m a little unclear on is the layout of the resulting spreadsheet. Could you provide me with an example?
Hi David,
I appreciate your response and your willingness to help!
Sure, I can provide you with an example. What would be the easiest way to do so?
Should I provide you with a Dropbox link to an excel spreadsheet example or a screen shot of an example?
Please let me know what would be more convenient for you.
Thanks again!
Steve
Steve,
Dropbox will work or you can just email me the spreadsheet. If email will work for you, then I can send you a message and you can reply and attach the sample spreadsheet.
David,
That would be perfect – please, when you get a chance, send me a message as I am not sure where I can find your email address.
Thanks so much!
Steve