Brad's profileSharePoint BlogPhotosBlogLists Tools Help

SharePoint Blog

SharePoint notes, comments, solutions and ideas from a SharePoint Integration Consultant
November 12

The best search tutorial ever

I just stumbled across a massively funny search tutorial site - LMGTFY.com - standing for, "Let me Google that for you". Try it!
 
http://lmgtfy.com/?q=del+rio+resort - the place I'm camping this weekend!
 
Sweet...
November 10

SharePoint 2010 features for IT Professionals

This is an excellent paper describing the new features that appear in SharePoint 2010, and highlights enhancements and differentiations between Standard and Enterprise versions of SharePoint.
 
 
Brad 
 
 
October 29

And a web site that people publish and categorise tools on...

Another treat for today - this site has a list of some great tools (including the SharePoint Skinner tool) grouped by category. I know a similar thing exists on WSSDemo, but it's tough to navigate. This one's clean and friendly - http://www.sharepoint-tools.de/ (luckily, not in dutch, but english).

Themeing for SharePoint - Using Deployment packages

Came across a great tool today from the guys at Elumenotion called SharePoint skinner. Essentially it's an easy way of creating a new theme and packaging it up with the assets as a WSP to deploy to one or more farms. http://www.elumenotion.com/Blog/Lists/Posts/Post.aspx?ID=94 - Not bad guys, not bad at all!
 
B
October 28

When Security becomes annoying - Saving a .docx file from a web site automagically saves as a zip

I hate it when things don't go right on my computer. One of the things I've been annoyed with lately is how on some sites, when I click on a .docx file to open it or save it, it always reads the file "header" (the first part of the file) and thinks that it's a ZIP file (which it kind of is - except I don't want it to open in WinZip, I want to open it in Word).
 
I finally got jack of it tonight. Tools down, I was going to fix this problem come hell or high water. First thing I did was Google the problem - Heaps of hits on it. Great! this will be a cinch! The sites I opened though had other ideas on what they thought was a "helpful" solution.
  • Change the filename during the save dialog (Duh! Been there - I want a fix, not a workaround).
  • Rename it once you save it (these mental giants were having a laugh at me)
  • Use Firefox (I almost expected to find this on a Firefox site once I read it - I live in the Microsoft world)
  • Add the site to your trusted sites (again, not a solution but a workaround every time I saw the problem)
  • Change the MIME types on the web server... now this was interesting... okay, apparently a .NET framework update came out with a new set of MIME types that indicated what application should open up what file - this was controlled by the Web site administrator though, so out of my reach
  • Disable IE's habit of "sniffing" the file header and working it out based on what it saw <-- BINGO!

What was happening - in web servers that had not been recently updated, the docx and pptx and xlsx file types were not registered properly on the web server. As a result, IE downloads the start of the file, looks at the first few bytes and assesses what it thinks is the correct application to open it with. This prevents someone from "disguising one file as another type, just by changing the extension (eg renaming .exe to .txt). It's a security feature - Firefox does not have it (which is why the Firefox solution works).
As some would know, the docx format is a renamed zip (cab?) file with lots of XML data in it. In fact, you can rename any docx file to .zip and have a look at its innards. This is why it picked .ZIP as the extension.

The other solution is to disable this IE security feature in the Registry. Navigate to:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_HANDLING and
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_MIME_SNIFFING

Change iexplore.exe's DWORD value from 1 to 0 - this allows the OS to take over and use the native application. Security lowered, problem solved... Well, kind of.

Brad

Listener Channel Failures, Process Activation errors, Licence Acquisition failure. It's all happening today...

Just had an interesting error crop up at a client site. One of the team (Hi Daniel!) was building a SharePoint server and was halfway through configuring it, when it suddenly stopped working. 503 errors on all web sites on the server, and some very strange errors in the event log:
 

 
Event ID: 8200
Source: Security-Licensing-SLC
Log: Application
Level: Error
Details: License acquisition failure details. hr=0x8004FE33
 
Event ID: 5139
Source: WAS
Log: System
Level: Warning
Details:
A listener channel for protocol 'http' in worker process # serving application pool 'SharePoint Central Administration v3' reported a listener channel failure. The data field contains the error number.
 
Event ID: 5002
Source: WAS
Log: System
Level: Error
Details:
Application pool 'SharePoint Central Administration v3' is being automatically disabled due to a series of failures in the process(es) serving that application pool.
 

 
WAS is the Windows Process Activation Service (you'll need to know that shortly). I'm not sure what the root cause of this error is, but someone somewhere in Microsoft does. Essentially, if you are using IPv6 and have nominated a Dedicated Crawl Server, the SharePoint application writes some bogus entries to the Windows Host file, causing WAS to fail.
 
The solution is to either:
  • Set up the SharePoint crawl service so it uses all WFE servers to crawl content (as Central Admin is FUBAR'd, you'd need to use STSADM to change this property), or
  • Remove IPv6 from the Server NIC's and restart the Windows process Activation service.

This then writes nice entries to the Hosts file and the problems evapourate like morning dew on a hot day. This is the site that we found the solution on - http://blogs.msdn.com/jmacleod/archive/2008/06/25/iis7-sharepoint-2007-fails-with-503-service-unavailable-errors.aspx (we used Workaround 2).

Cheers!
Brad

October 07

KRB_ERR_RESPONSE_TOO_BIG - Forcing TCP/IP over UDP

I thought I had this error on my blog somewhere, but when I went looking for it, I could not find it...
 
When you are working in an environment that uses machines running earlier versions of Windows than 2008 Server or Windows Vista, you may encounter an authentication problem when trying to pass through authentication using Kerberos tickets.
 
Essentially, the UDP Protocol cannot handle the larger size packets required to capture a Kerberos ticket for someone who has a large collection of groups associated with their login. This scenario has a list of dependencies required to trigger it which are outlined in KB Article 244474, but the fix is to set the following registry key on the web server to 1:
 
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
MaxPacketSize=1 (Decimal)
 
The Parameters key may not exist, if it does not, then create it.  The KB Article http://support.microsoft.com/kb/326985 has a lot of useful links to Kerberos articles and descriptions which I have used in the past, so you may also find that helpful.
 
B
September 18

Version Numbers for SharePoint – WSS 3 or 2007 Server

Not sure how long this page has been here for, but every time I want to find out what the hotfix level is I always google it and come up with some blog list that is half up-to-date… but no more! This list on TechNet is up to date and direct from the source – Thanks Microsoft! Every Hotfix, Every Service Pack and the corresponding version numbers. Great!

September 15

I didn’t know you could do that!!! – Embedding the version number into a document footer (Office 2007 Only)

I love SharePoint. The constant “Gee, I didn’t know you could do that” moments that only come at 2AM in the morning.

This one is compliments of a Demo preparation, one question in the demo script in particular asks about document policies. So I open it up and make sure the Disposal Policy is set for the demo… then I have a look at the other ones, and the “Label” one catches my eye.

I recently had a client come and ask me if they could embed the current version number of the document in the document footer so that when they printed it, everyone would know which version they were looking at. I said at the time that it would require a small amount of development (which was correct if you are stuck using Office 2003 like they are) – but if you have the unadulterated joy of ribbonly goodness that is in Office 2007, then Oh! Happy Days! - you can just add a label from the Information policy and make sure that it includes the variable placeholder {Version}.

image

Then you open the document, insert the Label QuickPart and save.

image

When you re-open the document, voila! The footer contains your version number! Thanks Brian for your detailed guide - http://bryansgeekspeak.blogspot.com/2009/03/moss-2007-show-sharepoint-version.html – which my cloudy brain needed to make this work (I never closed and reopened the document – Just thought it would pick up the version number immediately).

Naturally, this is more effective when you have versioning switched on – so remember to enable it on the document library. And if this is something you want to have in all documents, make a mandatory site policy that is applied across all Document Libraries.

Bedtime…

B

September 09

Twitter for people who don't Twitter - Twinbox

Finally – an add-in for Outlook to:

  • Let you Twitter from Outlook
  • Subscribe to as many or as few people's tweets as you want – either in your main mailbox, or in a separate "Twitter" folder
  • Discovery – Find out when ANYBODY twitters about a topic you are interested in!

I am a minimalist toolset kind of guy. The reason I have not jumped on the Twitter train yet is because it would be another information source for me to have to process. Currently, I have 2 – iGoogle and Outlook. I use iGoogle for searching things I want to know, and for polling SharePoint MVP's and Microsoft Employees RSS feeds (On-demand information). I use Outlook for Email (although I use iGoogle for home email, so there's some crossover there…) – for me, Outlook is delivered information.

Anyway, Tweetdeck and those other Twitterrific tools just annoy me because it's something else I have to check. I have no way of controlling the inbound flow, notifications, etc – It's either on or off. With Twinbox, I can set up rules on tweets the same way I set up rules on email – I stay on top of it, and can review them on my bus ride home. Tweet… er I mean Sweet! Here's the video describing how it works…

B

August 24

w00t! A supported way of adding and removing themes from a Web Application!

One thing that's always bothered me about theming SharePoint is that essentially you are modifying system files. While this is unsupported, it's the accepted practice – Heck, the theming Queen herself, Heather Solomon takes you step by step through doing it this way… until now :)

Robin Meure from Zevenseas has come up with a new Central Admin app page that allows you to select a Web Application and essentially "Nominate" the themes you want to be made available to the site collections within the Web Application. You can also add New Themes without modifying the spthemes.xml file (that we all know and love) – From robin's blog post:

The only thing you have to do is add the Theme to the THEMES folder and add your own custom SPThemes.XML somewhere in the 12 hive (a folder in the FEATURES folder could be a good example) and add this path to my solution and you’re done!

You can download the compiled code from here, and see the blog article with usage instructions here.

Thanks Robin!

August 17

Talking about SharePoint in Plain English

  This is a good video to show at the start of a training course on using SharePoint.

SharePoint in Plain English

This is a short video that explains in simple terms what SharePoint is, and why/how people use it. - Click here - SharePoint in Plain English 

August 13

Site dedicated to SharePoint and Reporting services integration

Just found this site which is dedicated to SharePoint and Reporting Services integration. A very useful resource in an area that has little available content - http://blogs.msdn.com/prash/default.aspx
 
Thanks Prash! Keep it up...
August 07

Redirecting users to a File Share from within SharePoint

Just a quick note - you can use a dash of JavaScript and a splash of HTML to redirect users to a UNC path on a file share. We had an issue recently where a user wanted to load 400MB of reference material onto a SharePoint team site. Instead of allowing this travesty to go ahead, I compromised and wrote up the following htm file that did what they wanted without filling my Site's space... It was data that was also being indexed by SharePoint on the file share, so it made sense to keep it there.
 
<script type="text/javascript">
<!--
window.location = "file://<Server Name>/DATA$/IT/Planning & Design Phase/2. Workstreams";
//delay
setTimeout("history.back()",2000);
//-->
</script>
 
Save it as a .htm file.
 
What this does is it opens a file manager window pointing to your UNC path, then after 2 seconds goes back in history on your browser (otherwise the users see a white page and don't know what to do...).
B
August 05

"Error: Class not registered" when trying to start WSS Search

Had a puzzling error recently where I was trying to set up a new farm. Single WFE, Separate SQL Server, simple config.

So I installed MOSS 2007, then SP 2 for WSS and MOSS. Everything went fine until I started to run through my configuration process – Every time I tried to start the WSS Search Service on the Windows 2003 R2 server I was installing onto, it would come up and say

Error: Class Not Registered

Like most of the alerts that appear in MOSS, this too was incredibly helpful and told me exactly what I needed. So… here's what I tried:

Check the ULS logs – Nothing in there saying that "Driver nnnnn is not registered" or something that would have been useful, just garbage

0 Unassigned Initialize New Project: Search called  - File:d:\office\source\search\search\gather\server\gatherobj.cxx Line:653
0 Unassigned Initialize New Project, Remove: Search - File:d:\office\source\search\search\gather\server\gatherobj.cxx Line:739
0 Monitorable CContentSourceCollection::Init in m_pScheduler.CoCreateInstance, Error is 0x80040154 - File:d:\office\source\search\search\gather\server\contentsource.cxx Line:1287
0 Monitorable <Exception><HR>0x80040154</HR><eip>00000000601BE7B0</eip><module>d:\office\source\search\search\gather\server\contentsource.cxx</module><line>1288</line></Exception>
0 Monitorable <Exception><HR>0x80040154</HR><eip>00000000601E29D3</eip><module>d:\office\source\search\search\gather\server\gatherobj.cxx</module><line>837</line></Exception>
0 Unassigned Leaving Initialize New Project: Search ; hr=0x80040154  - File:d:\office\source\search\search\gather\server\gatherobj.cxx Line:954
0 Monitorable <Exception><HR>0x80040154</HR><eip>0000000060107B50</eip><module>d:\office\source\search\search\gather\gthrsvc\cgatherprj.cxx</module><line>690</line></Exception>
0 Monitorable CGatherPrjCollection::AddRecoverOptional: Failed in :pProject->InitializeNew, Error is 0x80040154 - File:d:\office\source\search\search\gather\gthrsvc\cgatherprj.cxx Line:3712
8u6i High     Application '544760de-b60e-4da7-aea3-b02d6881ae9b': Class not registered  . Failed while configuring the gatherer application with an exception. Attempting to clean up... - System.Runtime.InteropServices.COMException (0x80040154): Class not registered       at
0 Monitorable <Exception><HR>0x80070002</HR><eip>0000000000A9369B</eip><module>d:\office\source\search\ytrip\tripoli\query\isreg.cxx</module><line>825</line></Exception>
8wsw High     Now terminating ULS (mssearch.exe, onetnative.dll)
8wsv High     ULS Init Completed (mssearch.exe, onetnative.dll)
8dw7 High     The call to SPSearchServiceInstance.Provision (server 'AUMLC52DIA46') failed. Setting back to previous status 'Disabled'. System.Runtime.InteropServices.COMException (0x80040154): Class not registered       at Microsoft.SharePoint.Search.Administration.MSSITLB
8dw7 High     ...PSearchServiceInstance.Synchronize(Boolean installGathererApplication)     at Microsoft.SharePoint.Search.Administration.SPSearchServiceInstance.Provision()     at Microsoft.SharePoint.Search.Internal.UI.SPSearchServiceInstanceSettings.BtnSubmit_Click(Objec
8xqz Medium   Updating SPPersistedObject SPSearchServiceInstance Parent=SPServer Name=AUMLC52DIA46. Version: 3105 Ensure: 0, HashCode: 66070359, Id: 53538cac-1888-446d-88ce-38a2106549e1, Stack:    at Microsoft.SharePoint.Administration.SPPersistedObject.Update()     at Micr
8xqz Medium   ...ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)     at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)     at System.Web.UI.Page.ProcessRequest()
8xqz Medium   ...t context, AsyncCallback cb, Object extraData)     at System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)     at System.Web.HttpRuntime.ProcessRequestNoDemand(HttpWorkerRequest wr)     at System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr
8inc Medium   In SSOService::Synch(), sso database conn string:
8u3j High     Registry key value {SearchThrottled} was not found under registry hive {Software\Microsoft\Office Server\12.0}. Assuming search sku is not throttled.
0 Medium   Entering MRU trim routine.
0 Medium   Initial table size: 27232355 in 136 entries
0 Medium   Final table size: 27232355 in 136 entries
0 Medium   Exiting MRU trim routine.

So, maybe the installation didn't go well? I decided to discount that as an option after the third attempt with no change.

Maybe it was because I was setting the Search Index to be on D drive prior to enabling search (and MS had hard-coded the default search index path in there as part of the deployment script)? Tried fixing that too, nothing changed.

Maybe I'd found a new bug in SP2 (I was applying SP2 before configuring the farm)? It turned out that I was not correct there either.

Google had lots of hits, most of which related to MS CMS or .NET Framework development.

Then I thought… What if this search service account does not have enough disk access rights based on local privileges? Sure enough, as soon as I added the account to the local Admin group it all went fine. So I tried to refine my search on Google and came up with this little beauty - http://social.technet.microsoft.com/Forums/en-US/sharepointadmin/thread/0cca4e8b-eac0-4c27-9bc2-0e574c8094ad – the response from Microsoft was: Give the Search account more rights. Not what to, or why, or what level of rights… just "More". Sweet!

Now I know what it is, I can use this information about the mandatory security required to narrow down the issue – MOSS http://technet.microsoft.com/en-us/library/cc721637.aspx – WSS 3 http://technet.microsoft.com/en-us/library/cc721631.aspx.

What's that Roger? Oh, it's a development environment? Well, at least I've got a starting point the next time this issue comes up :)

B

July 27

Duplicate people results in Search

I've fallen for this twice in the last few months now - when you set up a search source for SharePoint 2007 Server, you do not need to separately index the User profiles on My Sites - if you do, it generates 2 results for each user.
 
SharePoint search is smart enough to automatically pick up the user profiles associated to the MOSS Site you are indexing. Sometimes, it doesn't help to try and outwit the Search Engine's logic :)
July 19

Setting up a Project Status Rollup dashboard - The Easy Way

I’ve been working on a project at a clients site and a request came through from the Program Manager to have a reporting dashboard where the management team could quickly see:

  1. A list of project statuses collected from all project sites
  2. Present the statuses in a format that makes it easy to see where the issues are
  3. Allow mgt to quickly view issue detail
  4. Provide quick access to the detailed report

Immediately I thought:

  1. Content Query Web Part, with a common “Status Report” content type being used across Sub-sites
  2. Traffic lights or something
  3. Hmm… maybe some kind of layer that popped up when the user moused over it? Easy done with an Alt tag on an image
  4. Link to the Status report document

This incredibly long-winded blog article is going to take you through the process of going from this:

image

To This:

image

Don't be disheartened though – it's long because it's detailed, not because it's hard. The second time you do this, I expect it would take 1-2 hours.

So, the first thing to do is to create the common Content type that the CQWP would use to “see” all of the status reports. It needed to contain some HTML Calculated fields in it, that would be used to present the traffic light images to the user.

Ingredients:

For each aspect of a Project Status Report (Overall, Scope, Schedule, Risks and Issues, Resources and Budget) the following fields were created:

  • Status (Choice - Red / Yellow / Green)
  • Details (Multiline Text field)
  • Calculated Field
  • Hidden Field (Single Line Text – To store what was in the details field last time, and see if it’s changed)

The other field that was also created was an Executive Summary, which described the project at a high level (some project names – especially acquisition / sensitive projects - are intentionally vague :) ). The result was something like this:

image

If the company has an existing "Status Report" Word document template then you can build a Document Content type based on this, with embedded Status, Details and Executive Summary fields into the relevant areas of the document, so they can be modified while the document is open (Word 2007 allows you to edit SharePoint Fields in the document, then save the document and fields in one step).

Activate the "Publishing" Site Collection Feature, which gives you the CQWP (if you don't already have it activated, you will need to).

Finally, add the new content type to all of the relevant document libraries and to the site template that is being used to create the project sites. To make it easier to implement on other sites, you could also create a Status Report Document Library template and save it to the root site.

Let's Get Started.

For those of you unfamiliar with the HTML Calculated field, basically we build a HTML string in the calculated field using properties within the same list item, then with a bit of JavaScript magic we turn it into real HTML that gets rendered by the browser. You can find out more about it here: HTML Calculated Column – where it all began!

Where To Start:

First thing is to write down all of the project aspects you want to appear in the Dashboard, then create the fields and the Content Type at the Parent Level of the sites that will be containing the information being "Rolled up" into the dashboard. We'll then use these tracked items to create "sets" of fields for each item.

HINT: – When creating the Site Columns, do yourself a favour – create them WITHOUT spaces, apostrophes, hyphens, etc – UseCapitalLettersAtTheStartOfEachWord – Then once the field is created, go back and change it to something more readable (otherwise you're dealing with _x0020_'s in the field names).

The List Fields and Calculated Columns

So once you've created a document library and added the "Executive Overview", "Status" and Details" columns you want to track in it, you then need to add 2 more columns – A Calculated HTML column for each tracked status, and a single line details column which captures the first 255 characters of the Multiline Details column (more on that later). Both columns are hidden in the content type you are using The calculated fields contained the following formula

="<DIV><nobr>Risks and Issues: <IMG id='HoverImage' src='/_layouts/images/KPIDavid-"&IF([Risks and Issues]="Green",0,IF([Risks and Issues]="Yellow",1,2))&".gif' alt='"&[RiskDetailsShort]&"'  align='absmiddle' /><img src='/_layouts/images/projects_blank.gif'></nobr></DIV>" 

Basically, this formula identifies what the "Choice" field is set to (in this case [Risks and Issues]) and displays an image based on the setting – Green displays "KPIDavid0.gif", Yellow Displays "KPIDavid1.gif" and Red / Null displays "KPIDavid2.gif". The Details Field is then attached to the image as the "Alt" property, and finally we Tag it with the "HoverImage" ID and give it a text heading (in this instance, "Risks and Issues: "). The reason we give these images a specific unique ID of HoverImage is because we need a way to identify which ones get affected by our popout bubble script – we don't want it to affect all the images on the page :)

One other thing to note: I created 3 image files and called them KPIDavid0.gif, 1.gif and 2.gif (Green, Yellow and Red respectively). I also created a "spacer" blank gif file which I used to generate nice pixel-accurate separation between the results, applying the same effect across all results (this is the projects_blank.gif that appears in the formula above).

The SharePoint Designer Workflow

The one field that needs to be updated using an SDP Workflow is the Hidden Details field – you'll notice in the ingredients listed, the details field is a multiline field whereas the Hidden Details field is a single line text field. I did this because inputting data into a multiline text field with a toolbar is intuitive, but I didn't want random line breaks or HTML breaking my script (note I never tested to see if it did, but I figured it would – and this was a safe way to filter out the rubbish). Also, you can't use multiline text fields in a Calculated Field - which we need to do. At the time this was a "SkunkWorks" project – Hidden budget, no committed resources – so I minimised the test cycle any way I could.

The SharePoint designer workflow looked like this:

clip_image001

Essentially, it checks to see if the multiline fields start with the same as the single line fields. If they are the workflow finishes. If the file is currently checked out, the workflow finishes (Not having this will lead to failing workflows when a user hits save while editing the Status report online). If both of these conditions are false, then it updates all of the "Hidden Details" fields with the content in the multi-line detail fields the user fills out. I did this prior to finding out that SP2 came with a fix for infinite looping of "On Change" workflows – see here for the details. Had I known, I would have skipped the first condition.

So we have the Content Type, the Columns, the Workflow – What's next?

The Content Query Web Part and ItemStyle.xsl!

There's 2 parts that need to be customised – the XML to return the fields we want (you can change it when you export the CQWP), and the XSL that will render the additional fields we're interested in. Load up the page you want the dashboard to appear on, then add the CQWP – you will probably want to use settings like this:

  • Source – Show items from following site and all subsites, then browse to the current site (or type it in) – this will allow you to "See" all of the Project Status Reports on the current site or any project site below it.
  • List Type – Document Library (Assuming you're status reports are a document) or a custom list you have built for this piece of work.
  • Content Type – First choose the Content Type Group, then the content type you created earlier.

Click OK and make sure the CQWP returns a result – you will need to add a dummy file and data in there so you can be sure (it'll help if you need to troubleshoot as well).

ItemStyle.XSL – Round One

Now you know you're returning the status report documents, it's time to see what's already getting retrieved from the CQWP – for that we need to add a new Item Style to the ItemStyle.xsl file you'll find in the Style Library - http://<SiteRoot>/Style%20Library/XSL%20Style%20Sheets/ItemStyle.xsl.  

<xsl:template name="RenderStatusReportFields" match="Row[@Style='RenderStatusReportFields']" mode="itemstyle">
    <xsl:for-each select="@*">
        P: <xsl:value-of select="name()" /><br />
    </xsl:for-each>
</xsl:template>


This piece of code goes between the final </xsl:template> and before the </xsl:stylesheet> at the bottom of the file.This will give you a neat list of all the properties being returned from the CQWP.

  • Save the ItemStyle.xsl file back to the http://<SiteRoot>/Style%20Library/XSL%20Style%20Sheets/ library,
  • Publish a major version of it
  • In the CQWP Properties, change the Item Style Drop-down list to the one you just created (in our example, it's called RenderStatusReportFields) then
  • Refresh your page with the CQWP on it – You'll see something like this:

image

So… now we know what fields are already there. Hmmm… There's a couple of useful fields there… We might use "Author" and "Modified" so we can see who last updated it and when… we have Title as well… but none of our custom fields are coming through. Easy to fix :)

The Content Query Web Part

Export the Content Query Web Part, and open it in Notepad. For each additional field you want, go through the following process:

  • From the "Status Report" Content type, click on a column name
  • Right-click the "Open in a new Window" link and click "Properties".
  • Highlight (with your mouse) the "Path" on the properties window, Copy it onto the Clipboard and Paste into a separate Notepad
  • <CTRL>+F, type in &Field= and search for that string
  • The word that appears after that string is the Internal Column Name you need to Write down. If you followed my HINT above, it should be the column name you first typed in.

Make the following changes to the CQWP:

Change the CommonViewFields property Type so it contains the extra fields you want (All you need are the calculated fields and the Executive Overview field)

        <property name="CommonViewFields" type="string">Exec_x0020_Overview,Note;Budget_Calc,Calculated;Overall_Calc,Calculated;Resources_Calc,Calculated;Risks_Calc,Calculated;Sched_Calc,Calculated;Scope_calc,Calculated</property>

You can see in the list above that I created Executive Overview field with a space, which then had to be written in as Exec_x0020_Overview. Each field has an InternalName and a ColumnType reference. To determine the Column Type (if you have a multiline text field for example, it's a Type "Note"), refer to this table of column types:

Type As String (Use this Column) Type Display Name Type Short Description
Boolean Yes/No Yes/No (check box)
Calculated Calculated Calculated (calculation based on other columns)
Choice Choice Choice (menu to choose from)
Computed Computed Computed
ContentTypeId Content Type Id Content Type Id
Currency Currency Currency ($, ¥, €)
DateTime Date and Time Date and Time
File File File
Guid Guid Guid
Integer Integer Integer
BusinessData Business data Business data
ContentTypeIdFieldType Content Type Id Content Type Id
HTML Publishing HTML Full HTML content with formatting and constraints for publishing
Image Publishing Image Image with formatting and constraints for publishing
LayoutVariationsField Variations Page Layout Variations
Link Publishing Hyperlink Hyperlink with formatting and constraints for publishing
PublishingScheduleEndDateFieldType Publishing Schedule End Date Publishing Schedule End Date
PublishingScheduleStartDateFieldType Publishing Schedule Start Date Publishing Schedule Start Date
SummaryLinks SummaryLinks Summary Links data
TargetTo Audience Targeting Audience Targeting
Lookup Lookup Lookup (information already on this site)
LookupMulti Lookup Lookup (information already on this site)
Number Number Number (1, 1.0, 100)
Recurrence Recurrence Recurrence
Note Multiple lines of text Multiple lines of text
Text Single line of text Single line of text
URL Hyperlink or Picture Hyperlink or Picture
User PeoplePicker People Picker Control

 

You will also need to update the Title key:

 <property name="Title" type="string">Project Status Dashboard</property>

This makes sure you're not trying to pick between 2 webparts called "Content Query Web Part" when you have them both uploaded :). So, upload the customised CQWP to the Webpart gallery (http://<siteRoot>/_catalogs/wp/Forms/AllItems.aspx), then return to the dashboard page and out with the old, in with the new!

ItemStyle.XML – Round 2

Now this time, we need to check the ItemStyle.xml file back out and replace this

    <xsl:for-each select="@*">
        P: <xsl:value-of select="name()" /><br />
    </xsl:for-each>

With this

<xsl:variable name="SafeLinkUrl">
  <xsl:call-template name="OuterTemplate.GetSafeLink">
    <xsl:with-param name="UrlColumnName" select="'LinkUrl'" /> 
  </xsl:call-template>
</xsl:variable>
<xsl:variable name="DisplayTitle">
  <xsl:call-template name="OuterTemplate.GetTitle">
    <xsl:with-param name="Title" select="@Title" /> 
    <xsl:with-param name="UrlColumnName" select="'LinkUrl'" /> 
  </xsl:call-template>
</xsl:variable>
<xsl:variable name="LinkTarget">_blank</xsl:variable> 
  <div id="linkitem" class="item link-item">
    <xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate" /> 
    <a href="{$SafeLinkUrl}" target="{$LinkTarget}" title="{@LinkToolTip}" style="font-size:12px;font-weight:bold;">
      <xsl:value-of select="$DisplayTitle" /> 
    </a>
  <div class="description">
    <table border="0" cellspacing="0">
      <tr>
        <td>
          <xsl:value-of select="@Overall_Calc" /> 
        </td>
        <td>
          <xsl:value-of select="@Scope_calc" /> 
        </td>
        <td>
          <xsl:value-of select="@Sched_Calc" /> 
        </td>
        <td>
          <xsl:value-of select="@Risks_Calc" /> 
        </td>
        <td>
          <xsl:value-of select="@Resources_Calc" /> 
        </td>
        <td>
          <xsl:value-of select="@Budget_Calc" /> 
        </td>
      </tr>
    </table>
  </div>
</div>

The areas to focus on are:

  • The closing </a> after <xsl:value-of select="$DisplayTitle" /> is where I had the "Modified" and "Author" info. I then had a <br> and the Exec_x0020_Summary field values displayed before the calculated fields. At the end it was decided that these were not required in the final delivered solution, but it's easy enough to add them back in if required.
  • The Field Names, Properties are both CaSe-SeNsItIvE – Above you can see where I created a field called Scope_calc – The C starting calc is lowercase, whereas all of the other ones are upper case. It does not throw an error, it just displays nothing – so check the case if you can't get your fields to render.
  • See *** Update *** Below - You can add a property to the XSL that will automatically render the text as HTML, negating the need for the TextToHTML web part - add disable-output-escaping="yes" to the Calculated Field properties in the CQWP eg <xsl:value-of disable-output-escaping="yes" select="@Overall_Calc" /> - A disadvantage of this though is that debugging your HTML gets a little trickier, because you can't see it on the screen... on the other hand, if you're like me and you build your formulas in Excel, it's going to work first time every time :)

Progress Check!

At this time, you should have a fairly ugly CQWP that looks like this:

image

We're spitting out HTML code – Congratulations, you've done all the heavy lifting! Now to the easy part :)

  • Create A "Resources" document library, enable versioning.
  • Give the "Style Resource Readers" group the ability to read documents in the Resource Library.
  • Grab all of the files from my SkyDrive folder
  • Extract the contents of the TooltipJS ZIP file to
    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\1033\STYLES\tooltipJS
  • Put the 4 images into
    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\IMAGES
  • Upload the HTM files to your Resources library you just created.
  • On the page with the CQWP, create a hidden Content Editor Web Part (CEWP) and link it to the TextToHTML.htm file you just uploaded to the Resources Library

    image
  • Create a second hidden CEWP and link it to the Tooltip_Bubble_Code.htm file you just uploaded to the Resources Library

Voila! – That gives you everything you see on this page… except the Auto-Refresh (the countdown timer's in the bottom of the window). If you want that as well (useful for an active dashboard) then create another CEWP and link it to the 5_minute_page_refresh.htm file.

Project Page

Thanks for taking the time to read through this article – hopefully you can see that with some pre-engineered modules and a quick tweak to the CQWP you can build your own KPI Indicators and reporting dashboards in no time. For other visual reporting enhancements (like heat graphs, highlighting rows or values based on Excel logic) using similar techniques, be sure to visit Cristophe's Blog. I got the Tooltips popup from Alessandro Fulciniti - http://web-graphics.com/mtarchive/001717.php – and modified it to suit the scenario above.

Cheers!
Brad

*** UPDATE *** - 10/Aug/09

Cristophe has pointed out that if I disable Output escaping in the XSL, I don't even need the TextToHTML script! Not so bad for me (because I use it elsewhere on the page) but it makes it even easier to deploy. In the code sample above, you change the Calculated fields from this -
<xsl:value-of select="@Overall_Calc" />
- to this -
<xsl:value-of disable-output-escaping="yes" select="@Overall_Calc" />
which means you can skip using the TextToHTML Script / Web part - this speeds up the load time incrementally too... Thanks Christophe!

July 17

Sites built on SharePoint

This is a great reference when talking to clients who say "But SharePoint looks so bad out of the box, and it's so hard to customise it"! There's a few hundred there, but I got bored counting it.

http://www.wssdemo.com/Lists/Resources/AllItems.aspx, and the Top 100 - http://www.wssdemo.com/Pages/topwebsites.aspx

Uploading large files fails (2003 and 2008)

When you attempt to upload a large file in Sharepoint, you may receive errors relating to timeouts, 404s etc.
 
To resolve this, make the following changes:
 
By default, the maximum size for uploading files is set to 50 MB. If you need to be able to upload larger files (such as when you use smigrate.exe to migrate a site between servers), you can change this setting to any value up to 2 GB (2047 MB).
To configure large file support you must increase the default upload size in SharePoint Central Administration (Web Application properties). You may also need to perform the following additional actions (depending on your hardware configuration):
 
  • Increase the maximum upload size
    Click Start, point to All Programs, point to Administrative Tools, and then click SharePoint Central Administration.
    Under Virtual Server Configuration, click Configure virtual server settings.
    On the Virtual Server List page, click the virtual server you want to change.
    On the Virtual Server Settings page, under Virtual Server Management, click Virtual server general settings.
    Under Maximum upload size, type the maximum file size (in MB) that you want to allow to be uploaded.
    Click OK.
    If IIS is timing out when you upload large files, you can configure the Connection timeout setting in IIS to allow more than the default 120 seconds (2 minutes).
  • Tune the IIS connection timeout
    Click Start, point to All Programs, point to Administrative Tools, and then click Internet Information Services (IIS) Manager.
    Right-click the virtual server you want to configure, and then click Properties.
    Click the Web Site tab.
    In the Connections section, in the Connection timeout box, type the number of seconds you want IIS to wait before timing out.
    Click OK.
  • Increase the default chunk size for large files
    The large–file–chunk–size property must be set from the command line. This property is configured for a server or server farm, and cannot be configured for an individual virtual server. To set this property, use the following syntax:
    Stsadm.exe –o setproperty –pn large–file–chunk–size –pv <size in bytes>.
    After making a change to this property, you must restart IIS. You can restart IIS by typing iisreset on the command line.
If you want to increase the maximum limit for Web Parts...
This change is required only when working with large Web Parts. The maximum limit for Web Parts is set to 1048576 bytes by default.
  • On your server computer running Windows SharePoint Services, open Notepad.
    In Notepad, navigate to the %HomeDrive%\Inetpub\wwwroot folder and open the web.config file.
    Locate the PropertySize attribute in the configuration\SharePoint\WebPartLimits element.
    Change the PropertySize attribute to the maximum size you need.
    Save and close the web.config file.

Large file support limitations

The following features do not support files larger than 50 MB:

  • Virus checking.
  • Picture libraries.
  • Streaming files.
  • Client-side restoration of smigrate backup files (limited to 2 GB). The manifest files for an smigrate backup cannot be larger than 2 GB.
  • Site templates (limit of 10 MB per site template, including content).
Additional changes in 2008 server:
In 2008 server, there's a second change you need to make as well -
In either the WSS3 / MOSS site's Web.config, add / update the following line -
<system.webServer>
  <security>
  <requestFiltering>
                                              <requestLimits maxAllowedContentLength="52428800"/>
                                </requestFiltering>
  </security>
</system.webServer>
 
If you wish to apply it across all sites, make the change in the Application.config file in %windir%\system32\inetsrv\config\applicationhost.config
 
Other Notes:
You may find these hints useful as well
 
In the web.config file for the farm (Program Files\Common Files\Microsoft Shared\Web server extensions\12\TEMPLATE\LAYOUTS), update the executionTimeout value in this line:
 <location path="upload.aspx">
    <system.web>
      <httpRuntime executionTimeout="999999" maxRequestLength="2097151" />
    </system.web>
  </location>
 
You may also have to do something similar if the property is declared in the Web Application -
<httpRuntime executionTimeout="999999" maxRequestLength="51200" />
July 16

No More Spam from SharePoint Designer! (Infinite "On-change" loops are fixed)

Finally. After years of creating new workflows, running a test, only to have the CIO come into me and say "Hmm Brad I've received 200 emails in the last minute asking me to approve this task - could you look into it please?".
 
It appears that Microsoft have finally changed the logic so that an "On Change" workflow event cannot trigger itself by making changes to the current list item. This means that there's a lot less test logic and column value validation that needs to go into a workflow, reducing the overall size and complexity of the workflow.
 
July 07

Hover (MouseOver) Highlight and Click to stay highlighted in a SharePoint list…

While I was working in CustomWare I had the great pleasure of working with a guy called Sukri, a SharePoint developer. He's the kind of guy you'd mention something to, and it would tick over in the back of his mind, while he was doing his normal day-to-day work…. then a few days later, he'd come to you and say - "By the way, I know how we can address your client's requirements". Like he did for one of our clients… we were going through the client's needs, and we talked about how the client wanted to be able to present financial data in SharePoint, then allow the user to hover over and highlight a row of data… and allow the user to click the row and make it stay highlighted.

He came up with a script that allowed you to do both – then one of the other guys, Ben, decided to enhance it so you could select and deselect multiple rows. Here's a screenshot of how it looked on the screen…

Code:

<script language="javascript" type="text/javascript">
var preRow;
var preClassName;
var orgBColor;
var hoverColor = "#ffcc99";
var selectedColor = "#d2d2ff";
var SPGridViewGuid = "{<<LIST GUID>>}-{<<LIST VIEW WEB PART GUID>>}"; 

_spBodyOnLoadFunctionNames.push("addSelectedRowEvent");
function addSelectedRowEvent() {
// Get all TABLE tag objects
var oTables = document.getElementsByTagName("TABLE");
for (var i=0;i < oTables.length; i++ )
{
  // Filter where table id equal to SPGridView guid
  if (oTables[i].id == SPGridViewGuid)
       {
        // Get all TR tag objects
        var oRows = oTables[i].getElementsByTagName("TR");
        for (var j=0;j < oRows.length; j++ )
   {
    if (j != 0)
    {
     // Add client event onMouseOver
     oRows[j].onmouseover = function() {
      this.style.backgroundColor = hoverColor;
     }
     // Add client event onMouseOut
     oRows[j].onmouseout = function() {
      this.style.backgroundColor = "";
     }
     // Add client event onClick
     oRows[j].onclick = function() {
      // If previous row is not null 

      if(typeof(preRow) != 'undefined')
      { 

       // Assign previous stored background color and class name to TR object
//Code below has been commented out prior to demo
//
//preRow.bgColor = orgBColor; //preRow.className = preClassName; // Change font weight // try{ChangeFontWeight(preRow,'normal');}catch(e){;} } // If this row is alternating row if(this.className != "") { // Assign previous alternating class to TR object preClassName = this.className; this.className = ""; } // Assign new background color to TR object orgBColor = this.bgColor; if(this.bgColor == "#d2d2ff") { this.bgColor = "white"; try{ChangeFontWeight(this,'normal');}catch(e){;} } else { this.bgColor = selectedColor; // Change font weight try{ChangeFontWeight(this,'bold');}catch(e){;} } preRow = this; } } } } } } function ChangeFontWeight(selectedRow,fontWeight) { ; for (i=0;i<selectedRow.cells.length;i++) { selectedRow.cells(i).style.fontWeight = fontWeight; } } </script>

How it works:
The code you see above affects the HTML that is already on the page, so you need to position this at the end of the page below the list you are trying to modify. Because it is restricted to a list and a view, you can put it on a standard page (such as default.aspx) and it will only affect one of the views on the page.

Configuration:
The only thing you need to do before using this script is to replace <<LIST GUID>> with the list GUID, and <<LIST VIEW WEB PART GUID>> with the web part GUID. you get both of these from the URL when editing a "View" – all you need to do is strip off the %7B and &7D, and the %2D's replace with hyphens " - ".

image

image

Deployment:
I recommend creating a library and storing this as a .htm file – then referencing it from the Content Editor Web Part. Place the CEWP after the list view, and mark it as hidden. Change the title to something meaningful (such as Sukri's cool mouseover highlighting and multiclick code) and you're done!

image

Storing the code as a separate file in a helper library gives you maximum flexibility, minimum change (no unghosting of pages) and version control of your code.

Issues:
The only problem with the code is that it does not capture what the original background colour was – so if you click and unclick a row, it stays white. Not so bad if your list view is white rows, but an issue if you have alternating background colours. Ben was working on getting that resolved too, but he didn't get it debugged in time for the demo (check the highlighted part above). If anyone can see where the issue in the code is, please let me know :)

Cheers!

Brad

May 31

Proposal and Scoping Visio diagrams / resources

I was busy looking for something entirely different on SharePoint and stumbled on the following resources, which will come in handy when building proposals / response documents, architecture diagrams, etc.

http://technet.microsoft.com/en-us/library/cc263199.aspx – these are a series of models and diagrams here in PNG, JPG and Visio format that can be used as a starting point for architecture diagrams in proposals and presentations. They are based on real-world production deployments using best-practices design and architecture. They include:

  • Logical Architecture Sample Design: Corporate Deployment
  • Architecture Design Example: Twynham School (U.K.)
  • Architecture Example: Single School, Single Server
  • Extranet Topologies for SharePoint Products and Technologies
  • Shared Services Providers for Office SharePoint Server 2007
  • Inter-Farm Shared Services for Office SharePoint Server 2007
  • Deploying Microsoft Office SharePoint Server Geographically
  • Global Knowledge Management with Microsoft Office SharePoint Server
  • Office SharePoint Server 2007 Data Protection and Recovery model
  • Office SharePoint Server 2007 Availability model
  • Upgrading Windows SharePoint Services 2.0 to Windows SharePoint Services 3.0
  • Model: Upgrading Microsoft SharePoint Portal Server 2003 to Microsoft Office SharePoint Server 2007
  • Model: Site Permissions for Office SharePoint Server 2007 and Windows SharePoint Services 3.0
  • Model: SharePoint Products and Technologies Baseline Site Hierarchies
  • Sample project plan: Microsoft Office SharePoint Server 2007 deployment
  • Extranet hardening planning tool: back-to-back perimeter
  • Poster: Stsadm Technical Reference (Office SharePoint Server 2007)
  • Poster: Stsadm Technical Reference (Windows SharePoint Services)

There's also a MOSS and WSS 3 STSADM tech reference poster that can be downloaded from Ian Morrish's WSS Demo site (which is handy, because the redirect links on the Microsoft page above do not work).

Finally, here's a list of resources for SharePoint, grouped by resource type here - http://www.wssdemo.com/Pages/GroupBy.aspx

May 29

The HTML Calculated Field

I have been using this function a lot lately, as it's easy to build, easy to modify and does not require SPD's Data Form Web Part to create good looking lists. The basic premise behind it is you use a "calculated field" to construct a HTML String, then you throw a small bit of javascript on a page in a content editor web part (the js never changes from page to page, so you could lob it in a sharepoint js file too, as it does not affect anything else). This allows you to do things like apply traffic lights to any conditional test you can perform in Excel (as a calculated field has 90% of the functionality of excel formulas) or colour-code a list item based on its approval status. It's pretty cool, and really jazzes up your user interface – for example, you can colour a monthly calendar event to represent some type of event, without chewing up valuable real-estate describing the event in the item title.

Cristophe also has some other neat features, such as a month calendar view that can be displayed on the right side of the screen without requiring a 1600x1200 display, a scrolling news item, etc. Check his site out to be inspired :) He also has some other sites containing content too - http://8002.freesharepoint2007.com/default.aspx and http://pathtosharepoint.wordpress.com/

May 28

Theming – a useful utility for getting colours

So, more on the theming quest for knowledge – I was at a corporate site and they dumped this style guide on my desk and said "Follow That, sport" (actually, it was nothing like that, I'm just talking it up – it's a great client). After laughing my ass off at the Branding Nazi's (Marketing) choice of site colours, I thought – I could probably use one or 2 of these colours and come up with a nice theme. Maybe there is a tool on the web that'll help me…

http://colorsontheweb.com/colorwizard.asp – Enter your hex colour code and hit go, and it'll pick colours that work together well (shades) and colours to use for "hover" and button effects (Tetradic and Split Complimentary were great for these).

Oh, I also use Paint.NET to create and manipulate images, buttons etc – this was an undergraduate program started at MS to supersede MS Paint, but it's now a community tool. The best part are the plug-ins, but it's simple enough to use without being an art major. You can grab it here.

A theme with the name "<themename> 1011" and version already exists on the server.

First time I've ever hit this one – Building a custom theme for a client, using the technique Heather Solomon suggested here (Great strategy, saves heaps of time in testing cycles). Everything's going smashingly, then when I first change the test site to the new theme, it comes up with the dodgy message listed in the title.

Googling found a few people with some unique ideas – Change the name of the theme (puh-lease), renaming the theme folder (uh-huh) and delete the cached theme using SPD (this was plausible at least, but didn't help me resolve the issue).

In the end, I had to go in to the codepage value within the inf file in the themes folder to a different value (anything but what it was) and it resolved the problem. Thinking about it now, I probably could have deleted the file altogether as generally it's only used for multilingual environments so they can "read" the theme name in their native language, and has nothing to do with the theme functionality. One trap I'll remember for next time when copying a theme folder as a starting point for customisation.

Thanks for the tip, Aris!

 

Brad Saide