0
votes

I am creating outlook appointment items programmatically using VBA in MS Access and the Outlook Object Model (though the language shouldn't matter).

Items are added to multiple calendars belonging to a single user that other users are given read/write permissions to. The users have no reason to create or edit appointments on the calendar using Outlook. Appointment data is then stored in backend tables. Essentially, Outlook is being used as my "calendar view."

I am having major issues, however, with users changing appointment items directly in Outlook, which in turn do not update in my backend.

I would love an updateable "ReadOnly" property that can be set per appointment item and that disallows changes unless set back to False...but don't think one exists. Any suggestions?

Things I've tried or dismissed as solutions:

  • Reminding users of the rules.
  • Script that finds all mismatched items - this works but is not practical.
  • Custom Outlook form that doesn't allow edits - doesn't prevent users from dragging appointment around.

UPDATE: Using the suggestion by nemmy below, I have manged to get this far. This only works if the user selects the appointment before changing anything. It does not work if the appointment is selected and dragged in the same click.

Private WithEvents objExplorer As Outlook.Explorer
Private WithEvents appt As Outlook.AppointmentItem

Public Sub Application_Startup()
Set objExplorer = Application.ActiveExplorer
End Sub

Private Sub objExplorer_SelectionChange()
 If objExplorer.CurrentFolder.DefaultItemType = olAppointmentItem Then
    If objExplorer.Selection.Count > 0 Then
      Set appt = objExplorer.Selection(1)
    End If
  End If
End Sub


Private Sub appt_Write(Cancel As Boolean)
If Not appt.Mileage = "" Then 'This appointment was added by my program
    MsgBox ("Do not change appointments directly in Outlook!")
    Cancel = True
    appt.Close (olDiscard)
End If
End Sub
2
Try taking a look at the PropertyChange event. You may be able to trap a change in the Start / End properties of the AppointmentItem when they are drag/dropped.nemmy
Appreciate the help. The problem is in setting "appt" as I've defined it above. I can't figure out how to fire an event when "any appointment is selected", not just "this appointment index". I am able to fire an event for "any Item" but those events are limited. If I could get that figured out, your original suggestion of using Appt_Write would work beautifully.JBL

2 Answers

1
votes

Can you hook into the Write Event of appointment items? You could prevent changes being made that way. Something like below might work (Disclaimer not tested):

Public WithEvents myItem As Outlook.AppointmentItem 

Sub Initialize_handler() 

 Set myItem = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderCalendar).Items("Your Appointment") 

End Sub 



Private Sub myItem_Write(Cancel as boolean) 

  Cancel=true 

End Sub
0
votes

The problem you have is that the people have write access, can you or is it possible to only give them read access? If that is not acceptable, then my answer is you cannot or should not stop them from changing the items. You need to deal with it. This is what I do.

So when you create the calendar item give it a unique ID for example the ID from your backend table row. Add this to a property of the calendar item like the mileage property.

Now just create an update method which loops through all current calendar items in your table and get them from outlook with the ID, check it has not changed and if it has update your table.

Alternatively and given your comment below;

In my opinion you must control outlook. As such nemmy is on the right track you need to hook into the outlook object probably with the use of an outlook addin. Then you need to get each appointment item that the user opens and check if it has a mileage ID. If it does you either need to tell them to change this in your data base and not outlook, or you need to get the events relevant indicating changes to the appointment item and wait for it to be changed. Then send these changes from outlook to your database.