Every week I have to fax a form that has data that I keep in a log, a SharePoint list actually. The recipient expects it to be done by hand, I guess there aren’t many people who go the extra step and make a SharePoint list. I was just hoping to export the information to an excel spreadsheet, but the spreadsheet confused them. They just wanted to see their little for filled out by hand. I don’t like to do anything by hand.
Using GDI+ to load up the form as a bitmap then using the Graphics object to draw text in a comic font, kind of looks like I wrote it by hand. I had even considered (and still considering) buying our own fonts, for each person who enters information into the log, from a place like www.yourfont.com. By checking the “last modified by” to see whose font to use. I decided against it because they are 9 bucks a piece and I figured no one would ever notice and there’s certainly no value in it other than it’s “cool”. Once the image is created it’s sent as an email attachment to www.fax1.com and they fax it where it needs to go. Seems simple enough. I figured it would take a few hours, but I ran into a couple problems around using an existing view on a list.
There is a time and a place to use a SPView vs an SPQuery. The problem is that people can change the SPView and that could be exactly what you want. But most of the time you want to use an SPQuery in your code. I was in a hurry and didn’t feel like writing a CAML query and it bit me right in the butt a couple of times.
First problem I ran into was "Value does not fall within the expected range" which means the column isn’t in the result set that I was bringing back. So I went to the view and added the column, but not so fast! I first assumed that the column was there already and spent some time searching for a solution and trying a few variations on the code. This hacking led me down a road where I thought something was seriously wrong. I could do something like items[i].Fields[“my-Field”].InternalName and it would give me my_x002d_Field, or whatever the hex for a hyphen is. Then I would pass the internal name to the items collection like this items[items[i].Fields[“my-Field”].InternalName] and I still got the error! The point being I got all wound up in the wrong direction for two reasons:
- The fields collection doesn’t have anything to do with the fields that are brought back in the view.
- The hyphen wasn’t as near much trouble as I was trying to make it.
The field names don’t change no matter what the user does, but they can delete a field. A missing field can cause your code problems, so you need to check for the field first just so your code doesn’t bomb. Using a view can be nice because a user change change the sort order or even the order of fields. They can also mess with the group by which leads me to the second problem.
The other problem I ran into was a very vague message "An entry with the same key already exists" around Collections.Specialized was mentioned. I’m not making a collection, I’m being handed one! I was just simply pulling back a collection and I was getting this error messages. I tried it as an SPItemsCollection, I tried it as a DataTable, I tried it in the morning and I tried it at night. I was even looking around for a virgin goat to sacrifice. Then it dawned on me that the duplicate key that it could be talking about is the group by on the DateTime column. I removed the group by and everything worked as designed. I loaded up the ChartPart and pointed to a view that had a groupby on it as well. Groupbys are nice for people and I think a very common thing. But unless you’ve written your code to accommodate them know that you’ll have problems.
For the most part an SPQuery is the way to go, but when I’m in a hurry, being cheap, or just want to prove a point I’ll use a SPView and manage it on the list. I can imagine where a SPView would be very useful when the business needs the user to manage the query, but if that’s not the case then SPQueries are the way to go.