Recently I had to query a list in a meeting workspace, but I got an empty resultset for every meeting except the first one. Seems that tools like the U2U CAML Query Builder and SharePoint Manager 2007 were only able to query the items of the first meeting. Time to start googling and after some time I found a post of Sanket Shah describing the same problem I had. There is one property, ‘query.MeetingInstanceId’, you have to set on the query, if you want to get items out of a list other than those of the first meeting. It won’t work if you add the Instance ID column to your CAML query.

Code example (list is an SPList):

Dim query As SPQuery = New SPQuery()
query.Query = YourCAMLQuery
query.MeetingInstanceId = instanceID
Dim results As SPListItemCollection = list.GetItems(query)

Ever wanted to add an item to a list inside a Meeting Workspace? Well, I did and I couldn’t find instructions on how to. Don’t understand me wrong, I did know how to add an item to a list, but what about the instance id. This is pretty simple, every list in a workspace has a field, called ‘Instance ID’, type Integer. So just set the value of this field for each item to the correct ID and the item only shows under the specified meeting date.

Small code example (workspace is a SPWeb object):

Dim list As SPList = workspace.Lists(“aListName”)
Dim listItem As SPListItem = list.Items.Add()
listItem(“Title”) = “aItemTitle”
listItem(“Instance ID”) = 1
listItem.Update()

Update 8 june 2009: It only works for new items. Instance ID is a readonly field, so don’t try to reset it and update the listitem. It simply keeps the old value. There must be some special setting method implemented to have this behaviour.

Suppose you have a list in SharePoint with a column ‘User’ of type ‘Person or Group’ in it and you are writing custom EventReceivers to add to the list (eg ItemAdded, ItemUpdated, etc). As long as you work on the properties.ListItem and you get the value from properties.ListItem.Item(“User”), you will receive a typical string formatted as <siteusers.id>;#<displayname>. This string can be easily split to separate the ID from the DisplayName. This DisplayName can be passed to SPWeb.EnsureUser() method to retrieve a SPUser object. This object can’t be passed to the UserProfileManager, so sometimes you even have to get the SPUser.LoginName to pass to the UserProfileManager.GetUserProfile() method to get a UserProfile object.

Code example:
Dim web As SPWeb = properties.OpenWeb()
Dim formattedUser As String = properties.ListItem.Item(“User”)
Dim splitUser() As String = formattedUser.Split(“#”)
Dim userDisplayName As String = splitUser(1)
Dim user As SPUser = web.EnsureUser(userDisplayName)

But as soon as you start working with the AfterProperties and BeforeProperties (of type SPItemEventDataCollection) and you get the value of ‘User’, you will notice that you only get the <siteusers.id> (without the DisplayName). You now have two options to continue:

  1. You get the value of ‘display_urn:schemas-microsoft-com:office:office#User’, which contains the DisplayName and continue like in the above example.
  2. Or, you work with the ID and you use the SPWeb.SiteUsers.GetByID() method to retrieve a SPUser object.

Code example:
Dim web As SPWeb = properties.OpenWeb()
Dim beforeProps As SPItemEventDataCollection = properties.BeforeProperties
Dim user As SPUser = web.SiteUsers.GetByID(beforeProps.Item(“User”))

Personally I would suggest to use the second way and rewrite the code above to get the ID out of the formatted string instead of the DisplayName. This way you can write a universal method where you pass the ‘User’ value without bothering about the format of the string you pass. If you can find a ‘;’ you have to split the string on the ‘;’ to retrieve the ID, otherwise you only have the ID in the string.