Quickly Updating the Default BI Data Connections

As you’ll quickly find in Project Server 2010, if you want to use the default Business Intelligence Center data connections then in order to include your own custom fields, then you’ll need to update the connectors. Here’s a quick guide on doing that to get to that data for your first Project Status Report.

Before I get into it don’t forget that the OLAP connections are automatically created, so in many cases you can use those, but if you’re like me and prefer direct reporting from the Reporting Database then you’ll have to create your own connections.

Step 1: Start from an existing connection file

For this I am going to use "Project Server – Project and Task Data" from the default location "BC CenterData Connections – English (…)", find the existing file and save it somewhere locally using the Send to – Download a Copy option.

clip_image001

Now open that ODC file in Notepad and you’ll see the XML contents and hopefully the important part the section labelled <odc:CommandText> where the SQL "SELECT …" statement is, that’s what we need to change to include our custom fields.

Step 2: Add your Custom Field details using SQL Management Studio

Using SQL Management Studio is the easiest way to confirm that you have the right field names to add to the query, to do that find your ProjectServer_Reporting database and in particular what you will want is the View named dbo.MSP_EpmProject_UserView (or one of the others if you want task or resource fields). Select the view and using the ‘Select Top 1000 Rows’ option to generate a SELECT query returning all data.

 

clip_image002

You’ll end up with something like this:

/****** Script for SelectTopNRows command from SSMS ******/

SELECT TOP 1000 [ProjectUID]

,[ProjectName]

[ …. Snip lots of built in fields….]

,[ProjectBaseline10Duration]

,[Project Departments]

,[Sample Business Need]

,[Sample Areas Impacted]

,[Sample Proposal Cost]

,[Sample Compliance Proposal]

,[Sample Assumptions]

,[Sample Goals]

,[Sample Post Implementation Review Date]

,[Sample Post Implementation Review Notes]

,[Sample Proposed Start Date]

,[Sample Proposed Finish Date]

,[Sample Approved Start Date]

,[Sample Approved Finish Date]

FROM [PWA_ProjectServer_Reporting].[dbo].[MSP_EpmProject_UserView]

The nice thing is in the views all the custom fields are listed last, as you can see from above the out of the box ‘Sample’ fields are all there to see. So next you just have to copy those field names into the ODC file opened earlier and save your changes.

Step 3: Update the ODC file

The only catch with updating the ODC file as you probably noticed is the format includes the view or table name prefix, such as:

MSP_EpmProject_UserView.ProjectBaseline10FinishDate as [ProjectBaseline10FinishDate],
MSP_EpmProject_UserView.ProjectBaseline10Duration as [ProjectBaseline10Duration],

So all you need to know is that unless your changing the name you don’t need the bit after ‘as’, so if you search and replace to prefix each of your custom fields to add the "MSP_EpmProject_UserView." before the "," so you end up with something like:

,MSP_EpmProject_UserView.[Sample Business Need]
,MSP_EpmProject_UserView.[Sample Areas Impacted]
,MSP_EpmProject_UserView.[Sample Proposal Cost]

Now the last step is to paste those lines into the ODC file in Notepad, but note that the commas are at the start not the end, so you just need to make sure that when you paste the new lines that you have just one comma between each line except for the last line before the "FROM". You should end up with something like this:

MSP_EpmTask_UserView.TaskBaseline10Duration as [TaskBaseline10Duration],
MSP_EpmTask_UserView.TaskBaseline10DurationString as [TaskBaseline10DurationString],
MSP_EpmTask_UserView.[Health] as [Health]
,MSP_EpmProject_UserView.[Sample Business Need]
,MSP_EpmProject_UserView.[Sample Areas Impacted]
,MSP_EpmProject_UserView.[Sample Proposal Cost]
FROM
dbo.MSP_EpmProject_UserView
INNER JOIN dbo.MSP_EpmTask_UserView ON
MSP_EpmProject_UserView.ProjectUID = MSP_EpmTask_UserView.ProjectUID
ORDER BY
MSP_EpmProject_UserView.ProjectName,
MSP_EpmTask_UserView.TaskIndex,
MSP_EpmTask_UserView.TaskName
</odc:CommandText>

Step 4: Upload the new ODC file to your Data Connection library

Now your just about done, save the file and back in your BI Center upload the file to a new location, make sure that you don’t try to overwrite the default file as those may be replaced by future service packs, I upload them directly into the Data Connections library.

Once uploaded you can now use them in Excel as normal. You might want to update or copy the existing templates and edit the data connection properties to point to this new ODC file, or otherwise just add them in as you normally would and carry on..

Share and Enjoy !

Shares

Extending the Branching Workflow with Approvals

With Project Server 2010 you get an out of the box workflow named ‘Sample Proposal Workflow’, this is quite a good demonstration as it includes all of the usual things you might see in such a process; Validation, Approval, Selection, etc. However unfortunately as of this time (days before RTM) the source for this sample is still not available, at the moment the only SDK example is a simple Branching Workflow which only includes a single validation step.

I had an opportunity at the Sydney Ignite to ask Jan Kalis about this one, and he assured me that the full source for the sample will be released sometime around RTM, but we’ll have to wait a little bit more for that one.

In the meantime the world moves on and I have been busily writing my first full blow demand management workflow for a customer deployment, and so I thought I would share some of what I have done here. To that end I have taken the SDK Branching Workflow and extended it to include an Approval stage similar to that in the Sample Proposal Workflow.

Read below for what I have done and what you need to test it for yourself, then download my Visual Studio 2010 project below.

Branching Workflow with Approval:

The steps below are a summary of the changes made to the Branching Workflow, for a more complete how-to guide I very strongly suggest that you read the SDK Branching Workflow article and if you complete the examples there you will end where my steps below begin. Furthermore all the general requirements for getting this running (Visual Studio 2010 etc) are in the SDK article.

Before you start (or download):

This example is built on a default PWA instance, I have renamed the out of the box Sample Proposal Workflow to ‘Branching Workflow with Approvals’ then after deploying the code changed the workflow selected to the new one. All other PDPs and Stages are used as is, and the only other change required is an optional one below in step 5 below (see image).

Changes Made:

  1. Starting with the SDK Branching Workflow (note that if you download it in the p14betasdk then the code is incomplete and a few steps from the MSDN article must be completed). I also renamed the Feature and the Workflow in the deployment package to avoid confusion.
  2. Then I added a pre-build event command to automatically regenerate the Strong Name. (Can be removed, but just makes testing easier)
  3. Added a step after the Proposal Details Stage where the workflow goes to Proposal Selection Stage in Select Phase (updateProjectStageStatus20 – Waiting for Approval) – Note I have used the Select phase as my ‘Approval’ phase, I am not doing anything with Portfolio Selection here just approval.
  4. Next I read the Project Properties of "Project Name" and "Owner" for the Workflow Task (These are optional and just for completeness).
  5. Read "Portfolio Managers" Project Server Group membership to create approval request for first person returned in group.
  6. Create Workflow Task using CreateTaskWithContentType and assign to approver and populate task properties with Project Name and Owner.

Important: In order for these task properties to work you must ad the built in Columns to the PSWApprovalTask content type by editing the Default Workflow Approvals, then updating the content type to include the existing list columns.

(See Screenshot from List Settings PSWApprovalTask Content Type Properties)

clip_image001

  1. Then we add a while activity onTaskChanged to wait for the Approval task to be actioned. In this step the ExtendedProperties are checked for a value "Approved" anything else results in Rejection.
  2. And finally an IfElseActivity is used to branch on the Approved / Rejected result.
    1. If true then continue to end and UpdateProjectStageStatus to Execution stage.
    2. Else UpdateProjectStageStatus to Not Selected state and Terminate.

Here is the result in Visual Studio:

BranchingWorkflowApproval

What’s left?

  • Email notification? You can simply use the SharePoint list notifications on the Workflow Task list as a simple and consistent email notification method.
  • Portfolio Selection? I’ll leave that one to you.

 

Technical Details:

This example was created on the following beta software, meaning that things might change by RTM:

  • SharePoint Server 2010 RC Build
  • Project Server 2010 RC Build
  • Visual Studio 2010 RC Build

Download the full project files in a zip here. (*see update below)

 

MSDN References:

How to: Create a Branching Workflow <http://msdn.microsoft.com/en-us/library/ee767701(v=office.14).aspx>

Step 3: Create the Workflow <http://msdn.microsoft.com/en-us/library/ms580283.aspx>

 

UPDATE 3/09/2010:

I thought that I’d revisit this one as clearly from the comments there was something wrong after RTM, basically the problem everyone seems to be having relates to the ‘WorkflowTaskCTypeID’ defined. Somehow what I had in the BranchingWorkflow.cs file is actually incorrect, the solution has the following on line 46:

public String WorkflowTaskCTypeID = “0x0108010038A52C27344148C9B9214F82C7C0298500544602C73FFD1245BCC090442C85426B”;

When it should be:

public String WorkflowTaskCTypeID = “0x0108010038A52C27344148C9B9214F82C7C02985?;

Not quite sure where the first one came from (and why it worked?!) but that fixed it for me. If you update that line then recompile / rebuild you should be good.

 

PS. I don’t use the CreateTaskWithContentType anymore, have a look at the 2010 workflow activity (OfficeTask class) used in the Sample Proposal found in the SDK: http://msdn.microsoft.com/en-us/library/microsoft.office.workflow.actions.officetask.aspx

Share and Enjoy !

Shares

Reporting workspace lists directly from SharePoint

Update 31/03/2011: See the following blog about how much simpler this is with SQL Server 2008 R2.

This is one of the most common gripes that I hear about Project Server’s reporting database, the fact that only the default fields in your Project workspace lists, ie Project Risks, Project Issues, etc are available to report on.

Unfortunately I have yet to come across a client who uses (for example) a percentage probability of risk, I’m guessing it’s all that PRINCE2 influence. So as a result you are usually left with two options;

  1. Update the default fields to match your requirements, which actually is possible in 90% of the cases with some careful modifications to the workspace template and possibly some custom MDX measures for your cube. The biggest drawback with this one is if you want to report on new lists, such as for example a Change Register it is simply not possible without extending the RDB and cube!
  2. Secondly you could find and purchase a third-party product that will allow you to report directly on all of the list contents of your workpace, some of these link directly into the sites, others use a staging database.

There is of course a third option though, do it yourself, and that is what this blog post is about.

How to access the SharePoint data?

The first question is how, and of course I should be clear as a one-time minion of the capital MS, the question must be how to do it in a supported manner. So that completely rules out direct SQL access to the databases!

Fortunately there is another way: XML.

Let me start by saying that there is a lot of information is out there on this method, so here are some links to some of the most helpful pages; at codeproject, and other blogs here and here. (That last Blog one I probably found most useful!)

Before I get into it it’s worth mentioning that my example involves using Visual Studio 2008 with the SQL Business Intelligence Design Studio (BIDS) installed. Don’t let the VS2008 bit scare you it would be possible to do much of this using Report Builder, at least once you have your data connections created, perhaps I’ll leave that for a future blog?

In summary this is what you need to do:

  1. Create a SRS data source pointing to your PWA Reporting database.
  2. Use the above data source to identify the field named "ProjectWorkspaceInternalHRef" from the "MSP_EpmProject_UserView" table for each project you want to report on.
  3. Then use the URL indentified to dynamically construct your XML data source query by basically appending "/vti_bin/lists.asmx" to the end of the string.
  4. Finally using XML pull down the information that you want.

Too easy!

Okay show me the details!

Okay so first thing you need to do after firing up Visual Studio is start a new blank Report Server Project, then:

Step 1: Create your Shared Data Source

Create a standard SQL data source pointing to your Project Server Reporting database, such as:

Data Source=EPM2007DEMO;Initial Catalog=ProjectServer2007_Litware_Reporting


Step 2: Enumerate Workspace URLs and Select your Project

Firstly create a blank report with a simple SQL query to enumerate a list of all projects and their associated workspace URL:

Example query:

SELECT ProjectName, ProjectWorkspaceInternalHRef

FROM MSP_EpmProject_UserView

Then create a Parameter to prompt the user for a selection:

Name: SelectedProject

Prompt: Select Project

Select Get values from a query for Available Values:

Value field: ProjectWorkspaceInternalHRef

Label field: ProjectName


Step 3: Create your XML Data Source

Now the interesting bit, create a new non-shared datasource (Embedded connection).

Type: XML

Connection String: Expression

Credentials: Do not use credentials

Expression should be as follows:

=Parameters!SelectedProject.Value & "/_vti_bin/lists.asmx"


Step 4: Now create your Dataset using XML

Now you need to create your first Dataset in this XML data source, this is where we reference the actual list item, in this example Project Risks.

Create a new dataset using the following query:

<Query>

<Method Namespace="http://schemas.microsoft.com/sharepoint/soap/" Name="GetListItems"/>

<SoapAction>http://schemas.microsoft.com/sharepoint/soap/GetListItems</SoapAction>

</Query>


Populate the Parameters with the "listName" (note: this is case sensitive) parameter with the value "Risks":


Step 5: Select your Fields to include in the report

Now the annoying bit, under Fields you must include each field that you want to include in your report, however because we are dynamically generating the data source we cannot automatically populate this.

Note: To automatically populate this list hard code the data source to an actual workspace site then when you create the query for this dataset select Refresh Fields.

Otherwise you can manually populate these, just open the list in question in a workspace and open list settings:


Then use the Column name in the Fields list source by simply prefixing each name with ows_, for example: ows_Title

Resulting in something like this:


Step 6: Finally Create a Test Report to see the Results!

Now add a table to your report and add those columns to preview the data, you should see something like this:


Unfortunately you might notice some fields being blank, there’s actually something we forgot! One of the possible parameters in the dataset above is "viewName", that does exactly what you would think select’s the desired view, so as my example above (using the EPM2007DEMO databases with default column names) Owner, Description and Mitigation Plan are all blank, this is because the Default view configured for that list does not include them.

So you can fix this by changing the default view to include the required fields or by creating your own view and using the viewName parameter. Note though; that parameter requires the GUID of the view not it’s name, so you need to use something like http://meyerweb.com/eric/tools/dencoder/ to decode the GUID from the URL of the view. (See the above linked blog by David Wise for additional details on the parameters available)

One that is done, you should now see something more like this:


Looking good! (Almost!)

Just one last thing there, you can see the special characters in the data, for the Description and Mitigation Plan it is an easy matter of changing the ‘Placeholder Properties’ to Markup Type: HTML. However for the Owner and as you’ll find various other fields they contain internal codes used by SharePoint, these have to be removed with code, again David’s blog above has some code to do just that, or if you’re like me and didn’t quite bother to read down that far you can create your own and add it to the Report Properties – Code section:

Public Function CleanSPSInput(strIn As String) As String

Dim RegEx as System.Text.RegularExpressions.Regex

‘ Replace invalid characters with empty strings

if strIn = "" OR IsDBNull(strIn)

Return ""

Else

Return Regex.Replace(strIn, ".+;#", "")

End If

End Function

Then just replace your Owner field name with the following expression:

=code.CleanSPSInput(Fields!Owner.Value)

Now your report should look something like this:


All Done!(Well for me at least)

What’s the catch?

There is actually a big one which you might have guessed: performance.

The above report is effectively generating the report by browsing to each page and pulling down each list item every time the report is generated. For one single project like in the example above, that’s not such an issue, but if you wanted to create a portfolio summary report for example or batch process a single project report for all active projects then performance would quickly become a problem.

Much of that can be addressed through Reporting Services itself, using caching and pre-generation, etc or better yet using SQL Integration Services (SSIS). With that and some much more interesting scripting a DTS job could be created to setup your very own staging database using the same XML methods as above! Definitely something to blog about another time…

But what about??

Yes there are lots of questions left unanswered;

  1. What if someone renames the list used above?
  2. What if someone changes / deletes the view I selected?
  3. What if …

I think you can see some of the limitations here and possible also how they can be overcome (workspace template standards, etc) but I’ll leave that to you.

    Share and Enjoy !

    Shares