in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

David Wise's Sharepoint blog

Connecting SQL Reporting Services to a SharePoint List

There is a multitude of blogs that discuss how to access SharePoint data from SQL Reporting Services, so why another?  Simply because I had not found one that exposed all of the land mines I seem to hit when doing this.  So, I thought I'd try my hand at creating a detailed guide-map to the mine field.

The Requirements

In order to do this, you must have :

  • Visual Studio 2005 (I'm sure this works in 2008 as well, but I haven't tried it yet)
  • SQL Reporting Extensions.  These are installed by default when you install SQL Server
  • A SharePoint list exposed Anonymously or via Windows Integrated Authentication (more below)

Accessing the List

The Report Designer requires that the Data Source either require no authentication or uses Windows Integrated authentication.  Other options are available when defining the Data Source but you will not be able to use them as they are not supported for web services by the designer.

Note: If your SharePoint list requires Windows Authentication then your development machine *must* be in the same domain or a trusted domain as the SharePoint server.  If you are developing on a system that is not in the domain of the SharePoint list you are attempting to access, you will not be able to proceed.  Brutal, but there you have it.

The Steps

Start Visual Studio

Select File -> New Project -> Business Intelligence Projects -> Report Server Project.  Name and save the project.

In Solution explorer, right-click on Shared Data Sources and select Add New Data Source

FliE3

Make sure you specify the Type as XML and put the proper URL to your server's list.asmx web service page.  This is usually simply http://<server>/<path>/_vti_bin/lists.asmx, replacing <server> with your server name and <path> with the path to the site with the list you are trying to access.

Click the Credentials tab and make sure you set it to Windows Authentication (default) or No Credentials (if your SharePoint site allows anonymous access). 

FliEC


The other options are not supported by the Designer and will throw an error along the lines of "An error occurred while executing the query..." when you try to fetch the data.

 
Now that you have the data source defined, you will need to define the report.  To do this, right-click on the Reports folder and select Add-> New Item, then add a Report.  Do not use the Add New Report option on the right-click menu as that forces you to use the report wizard which can't properly connect to the web service to get data.
 

Fli11F

Fli120

 
Open the report and click on the Data tab and select <New Dataset...> from the Dataset dropdown

Fli140
 
Now enter a name for your dataset and make sure to pick the Data Source you created a few steps earlier.  The most essential thing on this form is to set the Query string properly.  It should be :

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

From there, click on the Parameters tab enter your parameters.  See the Parameters section below for more information.

Fli142

Parameters

There are 5 parameters that can be passed: listName, viewName, query, rowLimit and queryOptions and yes, they must be this exact case.  The catch here is that if you define all those parameters you will get data in the Data view, but then the Preview will fail with a multitude of messages, usually along the lines of "The Value expression for the parameter ... contains an error ... ".  To get around this, define only the parameters you are actually passing values for. 

listName

This tells the web service where to get the data from and it is the only required parameter.  You can give it either a list name or a Guid.  If you are unsure how to get the Guid, fire up Stramit CAML Viewer and browse to the list or simply click Settings->List Settings while viewing the list.  The list Guid will be URL encoded in the querystring after 'List=".  You can quickly decode it here.

viewName

The viewName tells the web service what view of listName to query in order to pull back data.  This is not required but strongly recommended because the Report Designer mangles the query parameter with severely limits your options for filtering data from the designer side of this process.  This is also an extremely picky parameter and I have yet to be able to get it to work consistently with a actual name of a view and have had to always use a Guid.

Note: If you do not specify a viewName, it will use whatever view is defined as the default for the list as the filter/sort for the data.  This is usually the All Items view and will likely include way more data than you want.

query

Do not use this parameter.  It is extremely useful for people calling the web service from code but does not work with the report designer.  I suspect that designer does some extra encoding of the CAML that this parameter normally accepts which confuses the web service to no end.  If someone finds a way to actually use this parameter from designer, please let me know!

rowLimit

The number of items to return.  SharePoint defaults to 100 so if you need more than this, you will need to include this parameter along with a number exceeding the number of rows you are likely to get.

queryOptions

Do not use this parameter for the same reason as query: it gets improperly encoded by the report designer.


Click OK and then try to get your list of fields by clicking the Refresh Fields icon ( Fli143 ) in the data view.  A small + should appear next to your report name.  Click on that to see all the fields it found.  If you don't see all the fields you were expecting, be sure to read the tip in the Annoyances section at the end of this posting.

Last step - get some data by clicking the Run icon ( Fli1EA ) on the Data tab.  It should pop up a dialog with the parameters you defined earlier.  Make sure all the parameters and values are there that you expect and click OK.

That's pretty much it.  I do have some general thoughts on the whole process that I've tacked on below.  Hopefully, this covers most of the quirks and oddities associated with this process.

 

General Troubleshooting

I cannot recommend Fiddler highly enough.  With this running on the dev machine you can easily see everything that is going on in the actual SOAP calls that are responsible for those vague errors that the designer throws out.  (click to see details)

Fli154

Guid's versus Names

Ok, so do I reference the list using the Guid or name?  There isn't an easy answer here as this is the classic catch 22.  The Guid is the ID of the item regardless of the name and is the natural thing for developers to want to use.  Unfortunately, if you are in an environment where code is migrated from a Dev farm through test/qa and then to Production, that Guid will change in each environment.  The Name is much friendlier and works across environments, but names have a tendency to change over time which will break your report.  Choose what works best in your environment.

A Word About Formatting

SQL Reports has no clue what to do with many of the columns used in SharePoint, so you might end up having to write some code to handle these.  The first you will probably see of this are the SharePoint fields that contain lookup values because these will show up on your report as something like "245#;My real name".  Pretty nasty.

What you can do is add the snippet of code below to the Code section of the report.  To get there choose the Layout view, then Click on Report -> Report Properties from the main menu.  Click on the Code tab and paste the code below in the window

function GetNameFromSP(pFullID as string) as string
  dim strRet as string
  dim iPos as integer

  if pFullID = nothing then return ""
  if pFullID = "" then return ""
  iPos = Instr(pFullID, ";")
  if iPos < 1 then return pFullID

  return Mid(pFullID, iPos +2)
end function

Then right-click on the field in the report that you want to fix this with and select Expression.  In the Expression Builder window, set it to the following:

=Code.GetNameFromSP(<your field reference>)

It is possible to use a .Net assembly for this function as well, but that is way beyond the scope of this article.  Besides, this method doesn't require any special installation steps on the target server.  If you are creating dozens of reports where you need this behavior or others like it, then it makes sense to look into the assembly approach.

A Word About Sorting

Odds are that the second place that you will hit the formatting snag mentioned above is when attempting to sort the report by one of the fields containing such values as it will sort by the ID part of the value string and not the name.  The easy fix is to use the same Expression as above in the Sorting and Grouping section of the report, which now allows you to sort on the real name.

Annoyances About the Report Designer in Visual Studio

Overall, working with the Report Designer in Visual Studio goes pretty good, but there are some soggy areas that you are bound to step in eventually.  I'm pretty sure these are related to working with either web services in general as a data source, or SharePoint web services specifically as I'm not seeing a lot of people reporting this problem over the net.

Vanishing Parameters

For reasons known only to designer itself, it will occasionally completely delete your list of parameters.  If you suddenly start getting errors or the wrong data and haven't changed anything substantial, make sure your parameters are still defined.  Just make sure you have them written down somewhere where you can refer to them in order to enter them again.  I guarantee you will hit this one at least once.

Erroneous Errors

Sometimes something gets stuck in memory and designer will keep throwing an error when you try to get data or preview what should be a good data call.  Nine times out of ten, just closing the report and re-opening it will take care of this.  It's very easy to lose an hour or more chasing a problem that isn't really there from this.

Now you have data, Now you don't

Fetching the data / previewing the report will work occasionally fail one attempt, then work perfectly the next with *no* changes in between.  This is a minor irritation and can usually be fixed by closing and re-opening the report.  After a while, you get used to trying everything twice.  If it fails on the second attempt, you probably really have an error.

Missing Columns

When you build the list of columns available for the report in Designer, it takes only the data in the first row of data returned.  If any of those columns are null, it won't include the column.  Make sure all the vital columns have data when you create the report and you should be fine, even if that means manually editing them for a short time to put temporary data in.  Update: Maria has offered a solution to this.  I'm not able to try it at this moment but it looks promising - thanks Maria!

Note: if you know of fixes to any of the above, please, please post it in the comments!

 

Some Helpful Links

Published Nov 28 2007, 04:06 PM by DavidWise
Filed under:

Comments

 

Joe said:

There is also the Enesys RS Extension at http://www.enesyssoftware.com.  They have a commercial version and a free community edition (older version).  I've used the community version and it works for what I need to do.

But this is really something MS should do natively in Reporting Services.  You would think since RS and SharePoint are both MS products......

November 29, 2007 7:48 AM
 

SharePoint 2007 Link love: 12-02-2007 part two at Virtual Generations said:

Pingback from  SharePoint 2007 Link love: 12-02-2007 part two at  Virtual Generations

December 1, 2007 5:40 PM
 

Work Related at BruceObenour.com said:

Pingback from  Work Related at BruceObenour.com

December 8, 2007 4:42 PM
 

mariae said:

December 13, 2007 12:03 PM
 

DavidWise said:

Awesome!  

I've updated the entry to include the links to your solution but I'll incorporate the actual fix into the entry once I get a chance to give it a test drive.

Thanks Maria!

December 13, 2007 4:26 PM
 

Tricky Dicky said:

I tried this and it works ... I have to make reports for a client and could use this. But there's something I don't get (with little experience in using Report Services): what I can do with all this is generating a report showing .... a view! What do I win here knowing that with MOSS2007 I can export a view to Excel or Access? In other words, why would I use report services to do something I can already do with Sharepoint?

December 27, 2007 6:07 AM
 

DavidWise said:

The primary reason would probably be that you can get a lot of more control over formatting in Reporting Services than in a view.  You can also get around one of the Render bugs (see my post on Render Failed) this way.

The biggest reason would simply be the complex reporting needs that the higher ups seem to have.  They always want to slice the data certain ways and present it other ways.  These same people tend to be the ones footing the bill for SharePoint, so it is best to keep them happy.

I'm sure you can accomplish nearly the same reports using Designer and XSLT but I'm pretty sure that you really don't want to be digging through all that every time senior management wants a slightly different cut on the data.  Worse yet - try maintaining all of that XSLT as they keep creating all of the one-offs that are needed.

Hope that helps!

December 27, 2007 11:19 AM
 

Tricky Dicky said:

Ok, I see what you mean.

But I would like to add something here that might be interesting for people who wants to make reports over sharepoint lists . In Access 2007 it's posible (I think it is not possible in Access 2003) to link to lists in Sharepoint and use them like ordinary tables. In that way you can make Access reports over multiple lists.

December 28, 2007 5:47 AM
 

DavidWise said:

Very true, and that is a solution that shold not be overlooked.  

The downside is that you still have the deployment headaches of Access.  In a small shop with only a few nearby facilities or a national shop with a solid backbone connecting locations, it is not much of an issue.  However, when you get to sprawling international organizations or organizations with remote facilities that rely on dial-up (gack!) deploying Access-based solutions simply isn't practical.  There is also the issue of Access Licensing as most offices only put Access on developer machines.

As with all things, you have to pick the solution that best solves the problem within any constraints you might have.

December 28, 2007 10:27 AM
 

Windows Update Fail » Connecting SQL Reporting Services to a SharePoint List said:

Pingback from  Windows Update Fail &raquo; Connecting SQL Reporting Services to a SharePoint List

January 11, 2008 3:46 AM
 

Windows Update Errors » Connecting SQL Reporting Services to a SharePoint List said:

Pingback from  Windows Update Errors &raquo; Connecting SQL Reporting Services to a SharePoint List

January 12, 2008 10:14 AM
 

Trevor said:

Any idea why the dataset would return multiple rows while when viewing the report using data from that dataset you could only view a single (in fact, the first row pulled by the dataset) rows worth of data?

January 30, 2008 12:15 AM
 

DavidWise said:

I have seen people create reports where they put all of the fields in the grouping sections of the report instead of the detail which results in something like you describe.  No idea other than that though.

January 30, 2008 9:52 AM
 

Trevor said:

Being unfamiliar with RS as a whole, could you describe how to do that?

January 30, 2008 10:20 AM
 

Newbee said:

Ok, I have the report working/visable via Visual Studio. But when deployed to Reporting Services it's failing with (the shared datasource is deployed as well)...

Info: Microsoft.ReportingServices.DataExtensions.XmlDP.XmlDPException: Failed to execute web request for the specified URL. ---> System.Exception: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "www.w3.org/.../strict.dtd">

<HTML><HEAD><TITLE>You are not authorized to view this page</TITLE>

February 7, 2008 4:16 PM
 

DavidWise said:

I'm assuming that you can can see both the report in RS and the data in SharePoint, right?  If so, then you might also need to grant the ID that RS runs under view permissions on the list.

February 8, 2008 10:19 AM
 

DavidWise said:

Trevor,

Not easily in text but I'll try.  You create a table on the report and group on whatever column makes sense for you.  You then put your data in the group header along with whatever calculation you wanted, like Sum() but leave the Detail section empty.

The report renders just like normal but since you haven't defined anything in the Detail section it doesn't list detail data and ends up looking like the totals report desired.

February 8, 2008 10:25 AM
 

Newbee said:

The Report does not come up in RS, as the first thing it does is to query out of SP.  

I have the data source setup to run with integrated security, so I didn't set any permissions in SP for the user that RS is running under.  I had thought that since I could view the report from Visual Studio all would be fine from within RS (same credentials set in both environments).

Thanks for your help.

February 8, 2008 11:31 AM
 

DavidWise said:

If you are not using Kerberos then what is probably happening is that while NTLM is carrying the user credentials in the hop between the browser and RS but then it drops them in the second hop between the RS and SP.  You don't see this in VS because it connects directly and you don't have that second hop.

February 8, 2008 2:03 PM
 

Newbee said:

Thanks David, That pointed me to another area/direction.  We were able to get it working by changing the data source from integrated to using my user id (just as a test) and it worked.  We are thinking of creating an AD user that has read access in SP, and manage who has rights via RS to run the reports.  I know this has a security gap, in that people that don't have rights in SP can see data we expose via this.

Thanks again for your help.

February 8, 2008 4:10 PM
 

Paul. said:

Hi David, Have you any examples of breaking out the data contained in ows_Metainfo from a document library. Unfortunatly, most of the columns that I want to report on are contained in this field. I'm assuming I'm going to have to drop into similar code that you've used to remove the prefixes, but a ready made example would be a bonus if you've seen or used similar!

February 26, 2008 4:37 AM
 

Alex said:

What about parameters and SharePoint? Has anyone ever added parameters where the user can change the dropdown menau to filter the results?

In SQL, it is @parameter1

in MDX, it is roughly the same, does it work for RS and SharePoint as well?

April 8, 2008 4:10 PM
 

David MacLeary said:

What if I'm trying to query multiple sites? Is this possible? I have a specific site collection where each site is a client we do business with. Each site is structurally identical in template design so they all have a Shared Documents library, etc. There are 100's of subsites. So I'd like to write a query like:

"Give me a count of all documents that are "approved"  (in the Shared Document lib) where all client names begin with the letter "A"."

That's a real simple SQL query if this data was in a relational db where the data was spread over a couple of tables, but how do I define a single Data Source that can query across multiple sites? Your data source example seems to indicate I can only define against one specifc client site:

http://<server>/client001/_vti_bin/lists.asmx

April 17, 2008 2:09 PM
 

Wendy said:

Hi, just one simple quesstion, what did you use for editing the images in this article??

May 7, 2008 4:02 PM
 

DavidWise said:

Wendy,

I use Snagit for all of my Screen Captures (www.techsmith.com/screen-capture.asp).  I've blogged about some of the things it can do in the past:

www.sharepointblogs.com/.../handy-snagit-trick.aspx

May 8, 2008 11:50 AM
 

DavidWise said:

Alex,

No idea, but if you try it can you let me know how it worked out for you?

May 8, 2008 11:55 AM
 

DavidWise said:

David,

I've read that it can be done as long as all of the sites are in the same site collection but have never done it.  There is also a product by Enesys(http://is.gd/dNO) that might be what you are looking for.

Hope that helps!

May 8, 2008 12:08 PM
 

Capt_Plutonium said:

Hi David,

Great post - I got it up and running in no time (after I figured out my parameters disappeared the first time!).

Question: Where do you recommend adding additional filtering criteria - in the Report in Reporting Services or in the filtering criteria in the SharePoint List?  I was planning on making a master list of all the data and then doing filtering within the Report Services report, but would it be less processing/work for the report to use a filtered list?

Also, if I do filter within Reporting Services, is the only way to perform this is by using the 'filter' tab with configuring the dataset?

Thanks for any additional input on this!

May 12, 2008 12:33 PM
 

Shel said:

Hi,

I have a extremely huge report created using sql reporting services. I tried exporting it to Excel but it takes very long and a lot of memmory space. Is there a better software that would hold huge reports?

Thnx.

May 13, 2008 2:36 PM
 

DavidWise said:

Shel,

That isn't really my area, but Sql Reports is quite good at holding large reports, it even allows you to slice and dice them somewhat.  For more advanced topics, look into Sql Server Analysis Services.

May 13, 2008 4:16 PM
 

Mark said:

HI David,

Great post and just what I was after.

I have a list that includes a Currency  value. I can sum it ok in the view but trying to do so in a group is causing it to return an #Error. The expression that I am using is =sum(Felds!ows_FIELDNAME.Value). Do you think my expression is incorrect or do I need to play with the formatin the dataset?

Thanks....

May 30, 2008 8:27 AM
 

DavidWise said:

Mark, first verify that your formula uses "Fields" not "Felds"  :)  Beyond that, I'd make sure that RS is seeing the currency field as a numeric instead of a string.  You might have to do a convert as part of your formula as well.

May 30, 2008 10:27 AM
 

Azhar said:

how can i develope a SQL report from two sharepoint Lists, I am trying this from 2 days, but not able to find any solution, could u help me out from this?

June 13, 2008 5:04 AM
 

Dave said:

Here is a link to another option for connecting to Sharepoint List data from Reporting Services- www.teuntostring.net/.../finally-fixed-problem-w-reporting-over.html

Link to the orginal article explaining the code- www.teuntostring.net/.../reporting-over-sharepoint-lists-with.html

The 'Enesys RS Extension' product is based on the code in this blog article.

It helps to read the comments for trouble shooting and installation.

I was able to set this up on a vhd and filter sharepoint list data in the filter tab.

Only supports reporting on one list.

June 13, 2008 2:10 PM
 

mobrien118 said:

I have a little info about what happens to the <query> tags and others. To use these tags, they must have embedded tags in their hierarchy. HOWEVER: SSRS tries to "help" us by XML encoding reserved characters (such as < and >). So, what it passes to the Web Service if you try to send "<Query xmlns=""></Query>" as the value of the <query> tag, it will actually send:

<query>

 &lt;Query xmlns=""&gt;

 &lt;/Query&gt;

</query>

This is why the web service won't accept it. I am trying to figure out a workaround for it. If we could just get SSRS to escape those characters, we'd be golden. (I have verified this with an HTTP sniffer).

I'll post here WHEN I figure it out, because I would like to use queries I generate in U2U CAML Query Builder in SSRS. Unless anyone else already knows the answer?

June 26, 2008 1:26 PM
 

Mindaugas said:

Your query string doesn't work  with Services 2005. I've used this one: <Query>

   <Method Namespace="schemas.microsoft.com/.../soap" Name="GetListCollection" />

</Query>

July 21, 2008 8:42 AM
 

Patricio Ogaz said:

Hi Dave.

Good article, about the query parameter: In fact the problem raised because in the method GetListItems the query, viewFields and queryOptions are XmlNode parameter type, and the reporting engine can't work with this data type.

In my case I develop a WebService from wrapping the query (and other parameters), a clone from GetListItems, and this webservice clone, receive the query "string" and call the back-end SPPS webservice with the XmlNode parameter. Work fine. We need use this parameter, your article help us. Thanks !!!

July 22, 2008 1:10 PM
 

patricio.ogaz@gmail.com said:

For the "web service wrapper", don't forget reuse the credentials !!!

In the webMethod:

proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

;-)

July 22, 2008 1:18 PM
 

DavidD said:

I try to connecting SQL Reporting Services to a SharePoint List. I have Microsoft SQL Server 2005 and Windows Sharepoint Service 3.0. I followed all the step in this post and I keep receiving the Failed to execute web request for specified URL. (Microsoft.ReportingServices.DataExtensions) Error message. What can be the cause of the error?

July 25, 2008 3:59 PM
 

PaulC said:

I have a report that has say 2 columns Title and Status.  I have 10 rows in the View that I'm quering and in that 10 rows I have 3 different statuses, so same status is on each row.

I want to create a parameter for this report based on Status.  So I added a parameter and made it from the same query that pulls all of the information.  I'm going to then use this parameter to hide the rows on the report that are not equal to what is picked by the user.  My problem is that in my list of States when I Preview the report I have the same status listed several times.  Is there a way that I can get it to just display a distinct list, if I was writing a SQL report I would just create a new dataset that just queried the same table and add DISTINCT to the select clause, but is there a was that I can do something to make this work?

August 22, 2008 9:23 AM
 

PonnalaV said:

Hi,

        I want to create a RS 2005 report by joining two SharePoint lists at reporting end.

Any idea or Suggestions please?

Thanks.

August 28, 2008 5:36 AM
 

mobrien118 said:

As I mentioned in my last comment, I have tried desperately to find a way to send contents in the <query> tag (such as <Query xmlns=""></Query>). As you mention, it would be extremely useful, but my quest has been to no avail.

@ Mindaugas: If your response was at me, I am not referring to the overall Query tag that you send, but the sub-tag <query> that you use to pass more parameters (like what fields you would like to see, etc.). See the SharePoint namespace definition for more details.

August 28, 2008 1:06 PM
 

Dan Barua said:

I was having trouble getting this to work

<Query>    <Method Namespace=schemas.microsoft.com/.../soap             Name="GetListItems"/>    <SoapAction>schemas.microsoft.com/.../soapGetListItems</SoapAction></Query>

putting a space in between

Name="GetListItems"

and

/>

helped.

September 1, 2008 11:27 AM
 

Patty B said:

I am trying to get a list of all items that are within a folder. My GetListItems query only returns the top level list. From everything I've read, it looks like I need to use the queryOptions parameter with

<QueryOptions>

     <ViewAttributes Scope="Recursive" />

</QueryOptions>

I've tried all kinds ways to try to get this to work with no luck. Any ideas?

September 9, 2008 5:18 PM
 

WinWire Technologies said:

Steps to access data from two Sharepoint lists:

1. Create two datasets as suggested in the article and store parameters listName and viewName one Sharepoint list in one dataset  and second set in second Dataset.

2. In the layout mode of the report create two tables and each dataset data goes to one table.

3. Arrange the fields to get the look and feel desired.

Note: This method works fine for two, three or four SharePoint Lists. In case we want to get data from n number of lists then not sure what kind of issues we have to deal with.

Thanks.

September 11, 2008 1:09 AM
 

Ritesh said:

hi all..

I am currently working on SSRS integraion with sharepoint...I need to get the data from  two or more sharepoint lists (by joining the lists-2 columns from one list and 3 from other, say)  and add report parameters to the report in SSRS...

Is there anyone who can help me with the syntax/procedure I have to follow..I am on a timeline and need to do that quickly...

Thanks.

September 26, 2008 1:29 AM
 

DavidWise said:

Ritesh, I'm not aware of any product that does this out of the box.  I know that if you look in the Field Xml for the list, you can get the columns used and use that against the SharePoint database itself, but that is not supported in any form and probably wouldn't get past your security folks anyway.  I did find some ideas in this thread (www.sharepointu.com/.../3645.aspx) perhaps there is something there you can use.

September 26, 2008 9:09 AM

Leave a Comment

(required )  
(optional )
(required )  
Add

About DavidWise

I have been writing software for over 16 years and web applications for 11 years. I have been also been elbow deep in SharePoint 2007 since Beta 2 and loving it! Currently, I work for Bennett Adelson Consulting (a Microsoft Gold Partner) based in Cleveland, Ohio.

Need SharePoint Training? Attend a SharePoint Bootcamp!

Posts (c) their respective authors. Everything else (c) 2007 SharePoint Experts