All posts in Development

Build Views on the Fly When Gathering Data from SharePoint

So recently at my client site we had a report that was running incredibly long.  This was a while ago, so unfortunately I can’t remember the run time, but I believe it was greater than 12 hours.  The report was pretty basic, just a determination of which documents were created within the month and an output that displayed things like location, file name, created date and creator.

When reviewing the code I noticed the original solution had been coded to loop through each site in the web and then grab all the documents within a particular date range.  The line in particular that scanned the documents was as follows:

 

[code language=”csharp”]
var listAddedItems = listItems.Where(x => ((DateTime)x["Created"] >= reportManager.ReportStartDate && (DateTime)x["Created"] <= reportManager.ReportEndDate) || ((DateTime)x["Modified"] >= reportManager.ReportStartDate && (DateTime)x["Modified"] <= reportManager.ReportEndDate));
[/code]

Pretty straight forward, but what it’s actually doing is going through and gathering all the data and throwing out what you don’t need.  Not a big deal unless you are working with a lot of data.  Right now we are sitting at around 1 million items in our SP farm.  I think I found the culprit.

Read more

Leading Practices for Planning and Implementing a SharePoint Environment

This month I traveled to Saskatoon, Edmonton and Calgary to present on the Leading Practices of Planning and Implementing a SharePoint Environment.  This was not meant as a technical discussion, but instead a discussion on implementing a SharePoint environment.  There is a bit of technical topics within it, but the focus is how to plan out your entire project to get the best SharePoint implementation you can.  I had a lot of great discussions and questions from everyone that attended and really enjoyed myself.   I promised everyone I would post my slide deck so they could reference it and use it should they choose to.

I would really like to thank the Saskatchewan SharePoint User Group,  Edmonton Microsoft User Group, and the Calgary SharePoint User Group for hosting me for these presentations.  I really enjoyed myself and hope to return soon with another presentation.  I would also like to thank Solvera Solutions for making this all possible as well.

As promised… the slide deck.

Leading Practices for Planning and Implementing SharePoint

Playing Outside your Sandbox (Part 2) – SharePoint BCS Features by Version

In this post we will discuss the different features that are available to you within your SharePoint environment.  The information I am providing will be based on SharePoint 2013, but unless I specifically state the features are new to SP2013 you can assume they exist in SP 2010 as well.

Click here for part 1 of this series

SharePoint Foundation

Although this is the free and most basic version of SharePoint you actually get some great features from BCS.  Many environments are more than capable of fully utilizing everything they could possibly need with just the foundation version of SharePoint.

External Content Types

The External Content type is the heart of BCS.  99.9% of everything you do with BCS starts with an External Content Type (ECT).  ECTs basically act as the connection between SharePoint and the external data.  An ECT maps all the data within the external source that you want to bring into SharePoint.  I say that you want because even if you hit a data source with 25+ columns and you want 3, then you only have to bring in 3.  The ECT then maps all the connections, and configuration of the data from the external data source to objects within SharePoint.  The ECT in the end is really just a content type which contains columns that just happen to get their data from a source outside of your SharePoint farm.

Read more

Playing Outside Your Sandbox – Connecting SharePoint to External Data Sources (Part 1)

Business Connectivity Services (BCS) in my opinion is one of SharePoint’s most powerful, yet most under-utilized services.  Let’s think about this for a second.  If you are building a .NET app that needs to connect to an external database you need to create the connections to it and the basic CRUD methods into your data layer (you better be using a separate data layer or get off my blog ;-p  ).  Yes I know there are lots of code out there that will generate it for you, or you could just build your own.

But what if I told you that you could do it all with your already existing SharePoint environment and in a lot of cases without writing a single line of code.  Now before you developers get out your torches and pitchforks (remember I am one of you), let me assure you, for the more complex data connections you will still need to write code.  You will need to be able to write the code that can access, update and insert the data properly.  All I am saying is that for simple to moderately difficult data operations you can do it within SharePoint without writing any code.  Perhaps this means you could delegate some of this to the non-developers on your SharePoint support team so you only get the fun development work.

Read more

SharePoint User\Group columns and People Picker Controls

So recently I had to perform some custom code that would add an entry from a people picker control to a user\group column and back again (on another form).  Going from the people picker control to SharePoint is really easy (the code snippet’s below are obviously vb.net.  I am trying to keep most of my examples on this site in C#, but this particular client I wrote this for was a VB shop at the time).


Protected Sub btnSave_Onclick(sender As Object, e As System.EventArgs) Handles btnSave.Click
'I use a dictionary here as I find it a very efficient method for holding all
'my data columns and their values (I have a lot more than shown here)
Dim dataToInsert As Dictionary(Of String, String) = New Dictionary(Of String, String)
Dim spControl As SharePointControl = New SharePointControl 'SharePointControl is a custom class for all my SP data access

If (ppManager.ResolvedEntities.Count > 0) Then
Dim manager As PickerEntity = TryCast(ppManager.ResolvedEntities(0), PickerEntity)
dataToInsert.Add(AttendanceSupportStrings.ManagerColumn, manager.Key)
Else
lblMessage.Text = "Manager field cannot be blank"
Exit Sub
End If
'...
'do other validation and value storage here
'...
Try
spControl.AddListItem(SPContext.Current.Site, dataToInsert)
Catch ex as exception
lblMessage.Text = (String.Format("An error occurred adding this entry.  Error returned: {0}", ex.Message))
lblMessage.Visible = True
End Try

 

Next, cast the value to an SPUser type and update the list. Please note: I realize some of you may be wondering why I am not going directly from the people picker to SPUser.  The reason being is that in most cases you are updating more than one field at a time and I wanted to show you a method (at least the one I use) to store columns of multiple types

'Use the dictionary key as the column name and the value as the column value
Sub AddListItem(sPSite As SPSite, dataToInsert As Dictionary(Of String, String))

Try
Using Web As SPWeb = sPSite.OpenWeb
Dim splist As SPList = Web.Lists(AttendanceSupportStrings.AttendanceListName)
Dim listItem As SPListItem = splist.AddItem()

For Each dictEntry As KeyValuePair(Of String, String) In dataToInsert
Select Case (dictEntry.Key)
Case AttendanceSupportStrings.ManagerColumn
listItem(dictEntry.Key) = Me.GetEmployeeByID(sPSite, dictEntry.Value)
'...
'More conditional updates here
'...
End Select
Next
listItem.Update()
End Using
Catch......

Private Function GetEmployeeByID(sPSite As SPSite, userName As String) As SPUser

Dim serviceContext As SPServiceContext
serviceContext = SPServiceContext.GetContext(sPSite)
Dim profileManager As New UserProfileManager(serviceContext)

If (profileManager.UserExists(userName)) Then
Dim spUser As SPUser = sPSite.OpenWeb.EnsureUser(userName)
Return spUser
Else
Throw New UserNotFoundException("This user is not found in SharePoint.  For the workflow process to proceed ensure user has valid email")
End If

End Function

 

That may seem like a lot of code just to upload, but remember it was written to handle more than just the one column. It also illustrates a method to upload an entire list row’s worth of data.

Now to go from a User Column to a people picker is quite a bit less code because I am only doing it one column at a time and access the column directly.  I am not building a dictionary to hold different field types nor updating a number of fields at once.  However, I do think that going from a User column to a People Picker is a bit more convoluted.  You actually first cast the user column into a SPUser object, then you put the user object’s login name into a Picker Entity.  You then add the picker entity to an ArrayList and finally you then add the array list to the picker object.

If (Not spListItem(AttendanceSupportStrings.UnionRepColumn) Is Nothing) Then
Dim unionContact As PickerEntity = New PickerEntity()
Dim unionList As ArrayList = New ArrayList()
Dim userUnion As SPUser = New SPFieldUserValue(spListItem.Web, spListItem(AttendanceSupportStrings.UnionRepColumn).ToString).User

unionContact.Key = userUnion.LoginName
unionList.Add(unionContact)
ppHRCContact.UpdateEntities(unionList)

End If

 

So hopefully this illustrates a method that can be used to take a value from a People Picker in a custom form up to SharePoint and then back again.