From Access to Outlook-Add Your Custom Data to the Outlook Calendar


Probably the most used Microsoft Office Application is Outlook. Often Outlook is open all day to receive emails, schedule appointments, and manage Contact information. Unfortunately, it is not always easy to share data between Outlook and Access.

If you use an Access Database that stores almost any kind of dates such as shipping dates, appointments, service scheduling, and maintenance schedules you may wish you could save that information to the Outlook Calendar with just the click of a button.

In this article, we will show you how to do just that. We will show you how to add data from an Access Form to an Outlook Calendar Appointment with just one mouse click.


One of the best things about this method is its flexibility. You can create an Access Form that holds the precise data you want to save to Outlook. We have set up a Table and Form to hold the Appointment Information we want. Yours can be set up differently. You may use a maintenance schedule, client appointments, project progress dates, or almost any kind of information with a date.


We can add an Appointment to the Outlook Calendar with just one click on our Form’s “Link” button.

The Access and Outlook Appointment Manager

The Access and Outlook Appointment Manager


Let us look at the code behind that button. First we need to make sure the Current Record is saved. If a Form is “Dirty” that means there has been a change made to the data on the Form, but it has not yet been saved. In order for Access to make the Form “Dirty = False” it has to save the current data on the Form.

Private Sub btnAddApptToOutlook_Click()
    If Me.Dirty Then
        Me.Dirty = False
    End If  


Next, we check to make sure the appointment has not already been added to Outlook. On our form we have a checkbox that indicates if that has been done. If the appointment already exists, we inform the user and Exit the Sub.

  
If Me.chkAddedToOutlook = True Then
    MsgBox "This appointment has already added to Microsoft Outlook", vbCritical
    ' Exit the procedure
    Exit Sub
Else
    ' Add a new appointment. 


We are using “late binding” so our code works in almost all versions of Outlook. This is crucial if you distribute your Database or take it with you in your thumb drive to use on other computers. However, one drawback of using late binding is that it is slower than early binding. With late binding we use an Object variable:

 
' Use late binding to avoid the "Reference" issue
Dim olapp As Object ' Outlook.Application
Dim olappt As Object ' olAppointmentItem  


This is how we would do it if we were using “early binding”:

 
Dim olApp As Outlook.Application
Dim olappt As Outlook.AppointmentItem
Set olapp = CreateObject("Outlook.Application")
Set olappt = olapp.CreateItem(olAppointmentItem)  


We need to know if Outlook is already open because there are two methods of instantiating Outlook and other Office Applications. You use the CreateObject Function if Outlook is not open, and you use the GetObject Function if Outlook is already open.


To determine if Outlook is open we are using the isAppThere Custom Function which we have included at the end of this article. This Function returns True if the application is open, and False if it is not open.

 
If isAppThere("Outlook.Application") = False Then
    ' Outlook is not open, create a new instance
    Set olApp = CreateObject("Outlook.Application")
Else
    ' Outlook is already open--use this method
    Set olapp = GetObject(, "Outlook.Application")
End If


An Outlook Appointment is called an Item, and is referenced in Outlook as olAppointmentItem; its constant value is 1. We must use the value 1 in order to create the Appointment Item so we put the 1 in parentheses after “CreateItem”. With late binding, we must use the numbers. In early binding, we could have put olAppointmentItem in the parentheses.


To create a new Appointment Item we use the CreateItem Function instead of the CreateObject Function.

 
Set olAppt = olApp.CreateItem(1) ' olAppointmentItem


Our example adds data from the Form to Outlook Appointment Properties. Your Fields and Form Controls probably will not have the same names as the Outlook Appointment Properties. This is no problem because you can easily manage that difference in code. For example, if you have a TextBox named “txtProjectDueDate”. You can use that as your Outlook “Start” Property like this:

 
Start = Me.txtProjectDueDate  


You may need to use more Appointment Properties than we have in our example. You can use the Object Browserto see the complete list of Appointment Properties. It is a long list with more than enough Properties to meet almost anyone’s needs.


Now let us examine how to add our data to the Appointment Properties:

 
With olAppt 
    ' If There is no Start Date or Time on
    ' the Form use Nz to avoid an error
    
    ' Set the Start Property Value
    .Start = Nz(Me.txtStartDate, "") & " " & Nz(Me.txtStartTime, "")  


“Start” is the first Appointment Property we are setting. Outlook uses both the Date and Time in the Start Property, but our Form has the date and time in seperate TextBoxes. To handle this, we just concatenate the date and time together like this:

Me.txtStartDate & ” ” & Me.txtStartTime

In order to avoid errors, we will use the Nz Function to handle nulls and zero length strings in our TextBoxes or ComboBoxes. The Nz Function gets the value you designate if the value is Null or a Zero Length String after the comma like this: Nz(Me.myTextBox, 0). This will not change the value in the TextBox, but it will change the value in the code.


Outlook does not require that the time be added to the Start Property. However, to avoid errors, if you leave the Start Time blank, then you need to leave the End Time blank also. You can do this if you just want to add the due date for a project without the Time.


The Outlook Appointment Property “End” is not always required but you may get an error if you do not supply any value.

 
    ' Set the End Property Value
    .End = Nz(Me.txtEndDate, "") & " " & Nz(Me.txtEndTime, "")  


Here we are using the Nz Functionto provide a 0 value in case the txtApptLength TextBox is Null.

 
    .Duration = Nz(Me.txtApptLength, 0)     ' vbNullString uses a little less memory than ""
    .Subject = Nz(Me.cboApptDescription, vbNullString)
   
    .Body = Nz(Me.txtApptNotes, vbNullString) 


We have provided a Combo box to select Locations from a Table to add to our Form along with other information about the location in unbound TextBoxes. Here we add the Outlook Location Property.

 
    .Location = Nz(Me.txtLocation, vbNullString)  


If we want Outlook to Remind us when our appointment is near we check the chkAppointReminder Checkbox on our Form and enter the number of minutes we want to be reminded before our Appointment. If the chkAppointReminder Checkbox is checked but we forget to enter our reminder minutes it will cause an error. To avoid that error we use code to change no minutes to 30 minutes.

 
    If Me.chkApptReminder = True Then
        If IsNull(Me.txtReminderMinutes) Then
            Me.txtReminderMinutes.Value = 30
        End If
        .ReminderOverrideDefault = True
        .ReminderMinutesBeforeStart = Me.txtReminderMinutes
        .ReminderSet = True
    End If  


Now we can save the Appointment Properties and start cleaning up:

 
        .Save
    End WithEnd If ' Release the Outlook object variables.
    Set olAppt = Nothing
    Set olApp = Nothing    ' Set chkAddedToOutlook to checked
    Me.chkAddedToOutlook = True

    ' Save the Current Record because we checked chkAddedToOutlook
    If Me.Dirty Then
        Me.Dirty = False
    End If

    ' Inform the user
    MsgBox "Appointment Added!", vbInformation
End Sub


Here is the code by Rick Dobson that checks if Outlook is open.

 
'---------------------------------------------------------------------------------------
' Procedure : isAppThere
' Author    : Rick Dobson, Ph.D - Programming Microsoft Access 2000
' Purpose   : To check if an Application is Open
' Arguments : appName The name of the Application
' Example   : isAppThere("Outlook.Application")
'---------------------------------------------------------------------------------------
'
Function isAppThere(appName) As Boolean
On Error Resume Next
 
    Dim objApp As Object
 
    isAppThere = True
 
    Set objApp = GetObject(, appName)
    If Err.Number <> 0 Then isAppThere = False
 
End Function


We have shown you how you can transfer Calendar data from Access to Outlook with just one mouse click using the Appointments Database. With just a little modification of the code, you can use your present Forms to send information with Dates to the Outlook Calendar.


Note: Code Updated 7/10/2010 – The updated code works with Outlook 2003, 2007, 2010. Get the complete updated code at our free Code Samples page.

Other free downloads include our new Microsoft Access and SQL Azure and demonstration application which uses Microsoft Access and SQL Azure to leverage the power of cloud computing.

More Free Downloads:
Us or UK/AU Pop-up Calendar
Report Date Dialog Form in US or UK/AU Version.
Free Church Management Software with Contributions management.
Code Samples


Get the Access and Outlook Appointment Manager to manage all of your Outlook Calendar Appointments and Access dated information.


Happy computing,

Patrick (Pat) Wood
Gaining Access

About these ads

36 Comments

  1. Brian
    Posted September 17, 2008 at 11:47 AM | Permalink |

    Excellent tutorial!
    My application is for consumable items which have a shelf life. The alarm is to remind me when an item is about to expire so I can order more and remove it from the floor. However the items could be consumed before the shelf life expires. In that case I would like to remove the entry from Outlook so I do not get an alarm for something that is used up. How would I go about creating a button in Access that would remove the entry from Outlook?

  2. Patrick Wood
    Posted September 17, 2008 at 12:14 PM | Permalink |

    Hi Brian,

    That would be a great feature to have!

    It should not be too hard to do except we need to be careful to delete only the Appointments we want to delete.
    Possibly the best way to do this is to enable drill-down selection starting with dates, categories, and finally, selecting the exact Appointment(s) using a ListBox on a Dialog Form.

    I will check into it and see what I can come up with. It may be a few days before I can post it.

    My next Post here will be about completing and using the Date part of a Dialog Form and I should have it up today. You can also read that article and download some of the code from my other site listed below.

    Best Regards,
    Pat
    http//gainingaccess.com

  3. Larry H.
    Posted October 16, 2008 at 12:34 PM | Permalink |

    Hi Patrick
    Great information and very timely regarding a problem I am trying to figure out.
    Attempting to schedule an Outlook appointment from MS Access. The users have multiple Outlook mailboxes. How do I setup an appointment in a calendar other than the default calendar ?

    Thanks ahead for the help and best regards;
    Larry

  4. Patrick Wood
    Posted October 16, 2008 at 3:08 PM | Permalink |

    Hi Larry,

    That is a great question. All you need to do is modify the code a little.

    Dim olApp As Object ‘Outlook.Application
    Dim olAppt As Object ‘olAppointmentItem
    ‘ Declare a variable for the MAPI Namespace
    Dim olNS As Object ‘ Outlook Namespace

    If isAppThere(“Outlook.Application”) = False Then
    ‘ Outlook is not open, create a new instance
    Set olApp = CreateObject(“Outlook.Application”)
    Else
    ‘ Outlook is already open–use this method
    Set olApp = GetObject(, “Outlook.Application”)
    End If

    ‘ Set a Pointer to the NameSpace
    Set olNS = olApp.GetNamespace(“MAPI”)
    ‘ Now we “pick” the Appointment Item Folder
    ‘ This opens the Outlook PickFolder Dialog Form
    Set olAppt = olNS.PickFolder

    ‘ Create an Instance of the AppointmentItem
    ‘ Add the Form data to Outlook Calendar
    With olAppt.Items.Add(1) ‘ olAppointmentItem

    ‘Then continue as shown in the Post above
    ‘ Set the Start Property Value
    .Start = Nz(Me.txtStartDate, “”) & ” ” & Nz(Me.txtStartTime, “”)

    Let us know how that works for you

    Best Regards,
    Pat

  5. Ritzvy
    Posted March 20, 2009 at 9:55 AM | Permalink |

    Pat,

    Very simple and neately explained for a begginers.

    You are GOOOOOOD.

    Thanks Ritzvy

  6. Posted March 20, 2009 at 10:45 AM | Permalink |

    Thank you Ritzvy. You are very kind. Helping beginners was exactly what I wanted to do with this post.
    Pat

  7. Joel Madrid
    Posted August 7, 2009 at 6:39 AM | Permalink |

    I really love the tutorial!

    Is there a way to pass these appointments from MS Access to a calendar that is stored in Access, Excel, or Word.

    I have thousands of appointments that clinical therapists have made with their patients (stored in Access table) and want to populate a calendar with that information, but don’t necessarily want the info to go into an Outlook calendar.

    thanks for any help!!!

    • Posted August 7, 2009 at 10:33 AM | Permalink |

      Thank you, Joel. I am glad you find the articles useful.
      To answer your question, a custom calendar can be done. Access makes a very good platform for such a calendar. To talk about it more click the “Contact Me” link in the upper left of the web page.
      Best Regards.

  8. Paul P
    Posted August 29, 2009 at 10:58 PM | Permalink |

    I used the code you provided above in another comment in order to add the appointment to a different calendar but regardless of the calendar I chose in the folder selection window, it still juar added it to the main calendar for some reason. How can that be fixed?

    Also, is there anyway to program it to just add it to a specific calendar (like a public calendar) all the time.

    • Posted August 30, 2009 at 1:41 AM | Permalink |

      Hi Paul,

      Some time ago I tried to solve the same problem you are having without success. At the present, I am unable to take on this issue. You may be able to find a solution for this on an Outlook Forum like the one at the link below. (You may need to copy the link and paste it into your browser.)

      http://www.microsoft.com/office/community/en-us/default.mspx?dg=microsoft.public.outlook.calendaring&lang=en&cr=US

      If you find a solution, I would love to hear about it.

      My best regards to you.

      • Paul P
        Posted September 4, 2009 at 3:08 PM | Permalink

        Patrick, I got it fixed. I posted it on UtterAccess Forums and someone pointed out that it was setting olAppt twice and that the second instance was to the default calendar, so I deleted the lines:

        Set olAppt = olApp.CreateItem(1) ‘ olAppointmentItem
        With olAppt

        and I also had to delete an End With later down the code.

        Now when I add the appointment and choose a public calendar it goes straight to it.

        Is there any way to set a label (color label) for an appointment in the Access form? I have a yellow custom label in the calendar that I named “AV/Equipment Request” that I want to be able to set in the Access form.

        Thanks,
        Paul

  9. Posted September 4, 2009 at 5:19 PM | Permalink |

    That is great Paul. Thank you for letting us know about it.

    You can find some help with changing the color of the labels at the link below. It may take some studying to understand how it works. You will need to set a Reference to the Microsoft CDO 1.21 Library. On my computer it is located at C:\Program Files\Common Files\System\MSMAPI\1033\CDO.DLL.

    http://www.outlookcode.com/codedetail.aspx?id=139

    Best Regards

  10. r_dunbar
    Posted April 28, 2010 at 9:01 AM | Permalink |

    This has been very helpful! Thank you all for sharing your expertise :-)

  11. rcdunbar
    Posted May 3, 2010 at 9:23 AM | Permalink |

    Follow-up question: I got this method working for a public calendar. Has anybody found a way to automatically post appointments to the public calendar instead of choosing through the folders-subfolders directory?

    Thanks ahead for sharing!

    Roxan

  12. Eric
    Posted May 12, 2010 at 10:28 AM | Permalink |

    I have never done any VB scripting on Access 2007 are there any examples that I can look at to help me get this code above working. I’m sure its easy Thanks for the help.

    Eric

    • Posted May 12, 2010 at 12:24 PM | Permalink |

      Hi Eric,

      You can copy the code used in this article at this webpage: AppointmentToOutlook. You will need to create a table and build a form using the same name for controls as used in the code or you can change the code to match the name of your controls.

      If you need further help you can contact me at contact@gainingaccess.net.

  13. Posted February 21, 2011 at 6:43 PM | Permalink |

    Can your application work with a local outlook connected to exchange server?

    • Posted February 21, 2011 at 9:12 PM | Permalink |

      Hi John,

      This application has been developed for use on individual machines. I believe you would have to modify the code for it to work with an exchange server.

      Best Regards,
      Pat

  14. Posted April 28, 2011 at 5:28 PM | Permalink |

    Hello Paul,

    Trying to figure out a way to get the EntryID from Outlook as soon as the appointment is entered into Outlook. Is there a way to do this? Why I am asking is that we are going to have Access storing the data (SQL Server 2008 R2 backend) and also have the data put into a shared Outlook calendar. The reason I want the EntryID immediately is so I can store it in the database in case the users need to make updates to the entry. Our users have to make changes frequently and this would allow the change in the database to push over into Outlook.

    Does that make sense?

    Thanks,
    Robert

    • Posted April 28, 2011 at 6:29 PM | Permalink |

      Hi Robert,

      After you save the Appointment Item you can use a variable to get the EntryID like this

      strMyEntryID = objAppt.EntryID

      Be careful though, because there is a possibility that Outlook can change the EntryID and that is why they are not recommended to be used as a unique identifier of an Outlook Items. I use UserDefined Properties to save an ID with each Appointment Item, however they require a bit of coding.

      • Posted April 29, 2011 at 6:06 PM | Permalink

        PS – Sorry, was reading the other post. I guess that is why I said Pual. Sorry again about that Patrick.

        I am thinking my best option is to use the Access data to search and pull the actual Outlook data for an item into a temp table and manipulate it there before I push the changes to Outlook. This way I am certain to get the correct EntryID and Item.

      • Posted April 30, 2011 at 12:05 AM | Permalink

        Hi Robert,
        Here is a quote from the Access Developer’s Reference that may help you:

        A MAPI store provider assigns a unique ID string when an item is created in its store. Therefore, the EntryID property is not set for an Outlook item until it is saved or sent. The Entry ID changes when an item is moved into another store, for example, from your Inbox to a Microsoft Exchange Server public folder, or from one Personal Folders (.pst) file to another .pst file. Solutions should not depend on the EntryID property to be unique unless items will not be moved. The EntryID property returns a MAPI long-term Entry ID. For more information about long- and short-term EntryIDs, search http://msdn.microsoft.com for PidTagEntryId.

        You know your development and production environment better than I do so knowing this may help make good decisions as your develop your application.
        Wish you the best.

      • Posted May 25, 2011 at 1:13 PM | Permalink

        One last thing; do you recommend on updating an item in Access to delete and recreate in Outlook or try to change the item in Outlook?

        Thanks again for all you do for the development community.

      • Posted May 25, 2011 at 4:56 PM | Permalink

        Hi Robert,

        Thanks for your comments and questions. It may be easier to delete the Outlook Appointment and create a new one since you already have the code to do that but there is a downside to doing it that way. You may loose some Outlook property values that are not in Access if you delete the Appointment. For example you might loose Attachments, Importance, IsConflict, MeetingStatus, Mileage, Resources, and UserProperties, among others.

  15. Posted September 13, 2011 at 5:07 PM | Permalink |

    Is it possible to use this code to post a calendar event from Access to a Sharepoint calendar?

  16. Posted September 14, 2011 at 7:25 AM | Permalink |

    Thanks Patrick, Do you know if there is a function to write the calendar event to sharepoint and or a shared calendar on an exchange server?

  17. Posted October 20, 2011 at 6:12 AM | Permalink |

    Hi Patrick…a very good piece.

    I have been able to get it to work for my default calendar on outlook. However, when i try and use the code above to choose the calendar I want it to go to i keep getting the error message “Error 13: Type Mismatch”.

    I was hoping you could have a quick look at my code and correct me where wrong.

    Dim outobj As Outlook.Application
    Dim outappt As Outlook.AppointmentItem
    Dim olNS As Outlook.NameSpace
    Set outobj = CreateObject(“outlook.application”)
    Set olNS = outobj.GetNamespace(“MAPI”)
    Set outappt = olNS.PickFolder
    With outappt
    .Start = Me!ApptDate & ” ” & Me!ApptTime
    .Duration = Me!ApptLength
    .Subject = Me!Appt
    If Not IsNull(Me!ApptNotes) Then .Body = Me!ApptNotes
    If Not IsNull(Me!ApptLocation) Then .Location = _
    Me!ApptLocation
    If Me!ApptReminder Then
    .ReminderMinutesBeforeStart = Me!ReminderMinutes
    .ReminderSet = True

    Thanks a lot.

    R

  18. Posted October 21, 2011 at 1:47 AM | Permalink |

    Hi Rory,
    You are using code to make sure you pass to Outlook the proper data types for some of the values. But you need to verify all the data types that you are passing to Outlook.
    You need to use Nz(Me!ApptLength, 30) or some other number for the length of your appointments. Text boxes tend to produce numbers as strings even when we enter numbers.
    Also you need to use something like Nz(Me!Mytextbox, “”) so that you do not pass a Null where a string is required which will cause the error you saw. The Nz Function is good to use because it allows you to use either a string or an integer if the value is Null.

    If you do that and you still have problems you may need to use code to verify the Date and Time is being passed in the correct format for Outlook.

    Of course the best way to do this would be to set a breakpoint and step through the code line by line until you see exactly where the error is occurring.

  19. Posted November 29, 2011 at 1:02 PM | Permalink |

    hi Patrick,

    This article has been very usefull. Thanks so much.
    I have one question… Is it possible to use GetFolderFromPath instead of GetFolderFromID to call a folder from the public folders and if so do you know how to do this?

    Thanks

    Sam

    • Posted January 15, 2012 at 12:56 AM | Permalink |

      Hi Sam,

      I am sorry that I just came across your comment. Somehow I missed it. As to your question GetFolderFromPath is not a part of Outlook VBA. Sue Mosher has a GetFolderPath Function in her 2007 book and GetFolder Function in her 2002 book code that uses the folder path. You can download the code from this page: http://www.outlookcode.com/member/book.aspx

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: