none
Outlook userform control labels that opens items when clicked RRS feed

  • Question

  • Hi.

    I've created a user form that displays the subject, recipients, start time, end time of the selected Outlook appointments in my calendar. 

    The below code is a excerpt from the actually user form where I've written the codes to display the mentioned above, which I've done already. Now, as a refinement, I want the user to be able to actually open up the actual appointments. eg. If I clicked on the subject name "40th day internal review...", Outlook opens up that appointment. I know that the actual code that displays outlook is "objFolder.Items(splitTarget(m)).display" but then since I am creating these labels conditioanlly depending on what the size of the "splitTarget" array(which contains the index of the outlooks i want to display out of every apppointment) and there could be as many as 20 labels created. Please assume that this splitTarget has already been worked out.

    Thanks!

    -------------------------------------------------------------------------------------------------------------------------------------------

    Private Sub UserForm_Initialize()
    Dim Subject, recipient, StartDateTime, EndDateTime As Control
     Dim n As Integer
     Dim objOutlook As Outlook.Application
     Dim objNamespace As Outlook.NameSpace
     Dim objFolder As Outlook.MAPIFolder
     Dim objAppointment As Outlook.AppointmentItem
     Set objOutlook = Outlook.Application
     Set objNamespace = objOutlook.GetNamespace("MAPI")
     Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
     Dim recips As Outlook.Recipients


    n = 0
    For m = UBound(splitTarget) To 0 Step -1
    Set Subject = Me.Controls.Add("Forms.Label.1")
    With Subject
     .Width = 516
     .Height = 18
     .Top = (4 + 2 + 3 * n) * 6
     .Left = 2 * 6
     .Caption = objFolder.Items(splitTarget(m)).Subject
     .Font.Size = 10
     .Name = "subject" & n
    End With

    n = n + 1
    If n >= limit Then
     Exit For
    End If
    Next

    .

    .

    .

    End sub

    Friday, January 10, 2014 1:23 AM

Answers

  • If you are reading existing Appointment items already to build your UI, your best bet is to save the AppointmentItem.EntryID values in a variable array.  Then later you can use NameSpace.GetMessageFromID and pass the EntryID values that you've stored, then call .Display on the returned AppointmentItem to show it.


    Eric Legault (MVP: Outlook)
    About me...
    Outlook Appins: Store Social Media fields in your Outlook Contacts!

    Friday, January 10, 2014 1:55 AM
    Moderator
  • Hi William,

    Unfortunately you can't identify Outlook items by the subject uniquely.

    Each Outlook item has a field called EntryID, which is a unique ID field generated by the messaging storage system for use with the MAPI folders that store the item. Note, the EntryID field may be changed if an item is moved to a different folder or if an item is exported and then imported (even to the same folder).

    Each folder has an ID field called Folder.StoreID, the value of which is the same for all the folders in a particular message store. Each folder also has a unique Entry ID field.

    If you know the IDs of an item and the folder it's stored in, you can directly reference the item using the NameSpace.GetItemFromID method. When using the GetItemFromID method to retrieve an item based on its ID, you should specify both the EntryID of the item and the StoreID of the folder. If you do not specify the StoreID, GetItemFromID searches the default message store.

    As Eric already suggested, you can use an array for storing EntryID values (with their store IDs) of items selected in Outlook and shown on your form. Then, if a user click on a particular subject on the form you can get the corresponding EntryID value and open an Outlook item using the GetItemFromID method. For example, the following sample code stores entry IDs in an array and then picks the second item, retrieves and display it:

    Sub OutlookEntryID()
       ' If there are more than 500 contacts, change the following line:
       Dim MyEntryID(500) As String
       Dim StoreID As String
       Dim EntryID As String
    
       Set olns = Application.GetNamespace("MAPI")
       Set objFolder = olns.GetDefaultFolder(olFolderContacts)
       ' Get the StoreID, which is a property of the folder.
       StoreID = objFolder.StoreID
       ' Set objAllContacts equal to the collection of all contacts.
       Set AllContacts = objFolder.Items
       I = 0
       ' Loop to get all of the EntryIDs for the contacts.
       For Each Item In AllContacts
          I = I + 1
          MyEntryID(I) = Item.EntryID
       Next
       ' Randomly choose the 2nd contact to retrieve.
       Set Item = olns.GetItemFromID(MyEntryID(2), StoreID)
       Item.Display
    End Sub
    @Eric, most probably you mean the GetItemFromID method of the Namespace class. There is no GetMessageFromID in the Outlook object model.

    Friday, January 10, 2014 10:35 AM

All replies

  • If you are reading existing Appointment items already to build your UI, your best bet is to save the AppointmentItem.EntryID values in a variable array.  Then later you can use NameSpace.GetMessageFromID and pass the EntryID values that you've stored, then call .Display on the returned AppointmentItem to show it.


    Eric Legault (MVP: Outlook)
    About me...
    Outlook Appins: Store Social Media fields in your Outlook Contacts!

    Friday, January 10, 2014 1:55 AM
    Moderator
  • Hi Eric. Thanks for your reply.

    I'm still not sure how to display the appointment upon clicking the subject label for each outlook label which is created upon the initialisation of my userform. I'm a bit lost here. Can anyone see why the click event is not happening? this is what I have so far:

    Private Sub UserForm_Initialize()
    'Dim Subject
    Dim recipient, StartDateTime, EndDateTime As Control
    Dim n As Integer
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objFolder As Outlook.MAPIFolder
    Dim objAppointment As Outlook.AppointmentItem
    Set objOutlook = Outlook.Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
    Dim recips As Outlook.Recipients

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Dim cLblEvents As UserFormEvents
    Dim Subject As MSForms.Label
    Set mcolEvents = New Collection
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    n = 0
    For m = UBound(splitTarget) To 0 Step -1
    Set Subject = Me.Controls.Add("Forms.Label.1")
    With Subject
     .Width = 516
     .Height = 18
     .Top = (4 + 2 + 3 * n) * 6
     .Left = 2 * 6
     .Caption = objFolder.Items(splitTarget(m)).Subject
     .Font.Size = 10
     .Name = "Subject" & n
    End With

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Set cLblEvents = New UserFormEvents
    Set cLblEvents.mLabelGroup = Subject
    mcolEvents.Add cLblEvents
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    n = n + 1
    If n >= limit Then
     Exit For
    End If
    Next

    End Sub

    In the UserFormEvents Class Module I have:

    Option Explicit
    Public WithEvents mLabelGroup As MSForms.Label
    Private Sub mLabelGroup_Click()
     MsgBox mLabelGroup.Caption & " has been pressed"
    End Sub



    Friday, January 10, 2014 2:26 AM
  • Hi William,

    Unfortunately you can't identify Outlook items by the subject uniquely.

    Each Outlook item has a field called EntryID, which is a unique ID field generated by the messaging storage system for use with the MAPI folders that store the item. Note, the EntryID field may be changed if an item is moved to a different folder or if an item is exported and then imported (even to the same folder).

    Each folder has an ID field called Folder.StoreID, the value of which is the same for all the folders in a particular message store. Each folder also has a unique Entry ID field.

    If you know the IDs of an item and the folder it's stored in, you can directly reference the item using the NameSpace.GetItemFromID method. When using the GetItemFromID method to retrieve an item based on its ID, you should specify both the EntryID of the item and the StoreID of the folder. If you do not specify the StoreID, GetItemFromID searches the default message store.

    As Eric already suggested, you can use an array for storing EntryID values (with their store IDs) of items selected in Outlook and shown on your form. Then, if a user click on a particular subject on the form you can get the corresponding EntryID value and open an Outlook item using the GetItemFromID method. For example, the following sample code stores entry IDs in an array and then picks the second item, retrieves and display it:

    Sub OutlookEntryID()
       ' If there are more than 500 contacts, change the following line:
       Dim MyEntryID(500) As String
       Dim StoreID As String
       Dim EntryID As String
    
       Set olns = Application.GetNamespace("MAPI")
       Set objFolder = olns.GetDefaultFolder(olFolderContacts)
       ' Get the StoreID, which is a property of the folder.
       StoreID = objFolder.StoreID
       ' Set objAllContacts equal to the collection of all contacts.
       Set AllContacts = objFolder.Items
       I = 0
       ' Loop to get all of the EntryIDs for the contacts.
       For Each Item In AllContacts
          I = I + 1
          MyEntryID(I) = Item.EntryID
       Next
       ' Randomly choose the 2nd contact to retrieve.
       Set Item = olns.GetItemFromID(MyEntryID(2), StoreID)
       Item.Display
    End Sub
    @Eric, most probably you mean the GetItemFromID method of the Namespace class. There is no GetMessageFromID in the Outlook object model.

    Friday, January 10, 2014 10:35 AM
  • I amended my code using the EntryID and having used it, I realised the convenience of it and I really should've gone for this option in the first place. The below code is the amended version.

    I'm going to use the following code to display my appointment like Eugene suggested:

    Set Item = olns.GetItemFromID(MyEntryID(m))
       Item
    .Display

    But how do i build the label click event?(When user clicks on the label of an appointment, that appointment opens from Outlook) I've spent ages on this but nothing seems to be working.

    Thanks guys

    Private Sub UserForm_Initialize()
    'Dim Subject
    Dim recipient, StartDateTime, EndDateTime As Control
    Dim n As Integer
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objFolder As Outlook.MAPIFolder
    Dim objAppointment As Outlook.AppointmentItem
    Set objOutlook = Outlook.Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)
    Dim recips As Outlook.Recipients

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'Dim cLblEvents As UserFormEvents
    'Dim Subject As MSForms.Label
    'Set mcolEvents = New Collection
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    n = 0
    For m = 1 To UpperBound
    Set Subject = Me.Controls.Add("Forms.Label.1")
    With Subject
     .Width = 516
     .Height = 18
     .Top = (4 + 2 + 3 * n) * 6
     .Left = 2 * 6
     .Caption = objNamespace.GetItemFromID(splitTarget(m)).Subject
     .Font.Size = 10
     .Name = "Subject" & n
    End With

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'Set cLblEvents = New UserFormEvents
    'Set cLblEvents.mLabelGroup = Subject
    'mcolEvents.Add cLblEvents
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    n = n + 1
    If n >= limit Then
     Exit For
    End If
    Next

    End sub

    In class module:

    Option Explicit
    Public WithEvents mLabelGroup As MSForms.Label
    Private Sub mLabelGroup_Click()
     MsgBox mLabelGroup.Caption & " has been pressed"
    End Sub


    Monday, January 20, 2014 11:46 PM
  • Hello William,

    First of all, I'd recommend asking separate questions in new forum threads. The current forum thread is marked as answered and don't attract new visitors/answerers. Moreover, it is hard to locate the real answer for future forum readers.

    The AppointmentItem class from the Outlook object model provides the Open and Read events. The Open event differs from the Read event in that Read occurs whenever the user selects the item in a view that supports in-cell editing as well as when the item is being opened in an inspector.

    Tuesday, January 21, 2014 12:05 PM
  • Hi William.  Take a look at the approach here, simplified but based on your example. You basically have to create a new instance of a Class for each label, and the click event will fire in a specific instance of a class for the related label.  If you need to track which Appointment the label control is associated with, add some properties to that class and store the item data there.

    Dim cLblEvents() As UserFormEvents 'Declare as an array
    
    Private Sub UserForm_Initialize()
    	Set cLblEvents = New UserFormEvents
    	
    	'...your looping code that creates label controls
    	     Dim intCtlCnt As Integer
    	     
    	     intCtlCnt = intCtlCnt + 1
    	     ReDim Preserve cLblEvents(1 To intCtlCnt)
    	     Set cLblEvents(intCtlCnt).LabelEvents = myLabelControlVariable
    	'...end your looping code
    	
    End Sub
    
    'UserFormEvents
    
    Public WithEvents LabelEvents As MSForms.Label
    
    Private Sub LabelEvents_Click()
    
    End Sub


    Eric Legault (MVP: Outlook)
    About me...
    Outlook Appins: Store Social Media fields in your Outlook Contacts!

    Tuesday, January 21, 2014 3:23 PM
    Moderator