Sep 06

You can download both SQL Server 2008 R2 CTP and Report Builder 3.0 below:

SQL Server 2008 R2 August, 2009 CTP:

SQL Server 2008 R2 - August, 2009 CTP

Report Builder 3.0

SQL Server 2008 R2, Report Builder 3.0

SQL Server 2008 R2, Report Builder 3.0 readme

Cheers!

Aug 10

This article explains how to create a recursive hierarchy group, which organizes data in a report to include multiple hierarchical levels. This is helpful when you want to display hierarchical data in a report. For example: employees in an organizational chart, or product subcategory in a product list. The image below is an example: 

reporting builder 2.0

 This article assumes you have the following:

  • SQL Server 2008 and Reporting Services installed
  • Business Intelligence Development Studio (BIDS) or Report Builder 2.0 is installed. Note: We are using Report Builder 2.0 for this example.
  • AdventureWorks database
  • Experience working with Reporting Services

Steps Taken:

  1. Create a new report
  2. Add a Data Source and Dataset
  3. Add a Table to the report and include dataset field
  4. Edit Group properties and reference a Recursive Parent 
  5. Add custom format expressions
  6. Run code 

Create a new Report

1) Open Report Builder 2.0 and create a new report.

Note: If you have not done this before, please view my previous article "Creating a Report" for more information.

2) Save the report to your desired Report Server location and name it "RecursiveHierarchyGroup".

Add Data Source and Dataset

Creating the Data Source

1) From the Report Data pane, click New and select Data Source

reporting builder 2.0

the data source dialog will open...

reporting builder 2.0

 Note: You may choose an existing shared data source, if you have previously created one. For this example, we will be using an embedded connection. 

2) Provide a name for your data source. We will use the default value provided in this example.

3) Select "Use a connection embedded in my report" option

4) Select your Connection Type from the drop down. For this example we are using Microsoft SQL Sever.

5) Click the Build button from the right of the "Connection string:" textbox. You will see the Connection Properties dialog below.

reporting builder 2.0

6) Enter the same values in the property fields, found in the image above.

  1. Test the connection when you are done.
  2. If test is successfull, click OK.
  3. Click OK to close the Connection Properties window.
  4. Click OK to close the Data Source Properties window.
  5. You should now see your data source name on the left Report Data pane.

Note: the value in Server Name property is a period "."

reporting builder 2.0

Creating the Dataset 

1) From within the Report Data pane, select New >> Data Set

2) Make sure the Query item is selected in the left pane of the Dataset Properties window. Enter "Organization" in the Name field.

3) Select "AventureWorks" from the Data Source dropdown, or the name you gave your data source.

4) Copy and paste the following T-SQL script to the Query textbox:

select hr.EmployeeID, hr.ManagerID, c.FirstName + ' ' + c.LastName as 'Name', hr.Title

from HumanResources.Employee as hr inner join

Person.Contact c on hr.ContactID = c.ContactID

you should have something similar to below:

 reporting builder 2.0

 5) Click OK to save changes and close the window.

Add Table to Report

1) In Design view, add a table, and drag the following dataset fields to display:

  1. Name
  2. Title

2) Insert a new column to the right of the Title field and name it "Level".

3) Click in the "Click to add Title" field and enter "Organizational Hierarchy"

Your design view should look similar to the image below:

reporting builder 2.0

Edit Group properties and reference a Recursive Parent

4) Right-click anywhere in the table to select it. The Grouping pane displays the details group for the selected table. Optionally, you can select View from menu tab reporting builder 2.0 and check Grouping. In the Row Groups pane, right-click Details, and select Group Properties. The Group Properties dialog box opens.

5) In Group expressions section, click Add. A new row appears in the grid.

6) In the Group on list, type or select the field to group - EmployeeID.

Your Group Properties General tab should look similar

reporting builder 2.0

7) Click the Advanced tab, from within the left pane of the Group Properties dialog.

8) In the Recursive Parent list, type or select the field to group on - ManagerID.

9) Click OK.

10) Run the report. You will notice the list of Employee names and titles. However, we need to do some formatting to indent the hierarchy accordingly.

Add custom format expressions

Indent Hierarchy

1) Right click on the [Name] field and select Text Box Properties...

2) From the left property pane, select the Alignment tab.

3) From under the Padding options section, select the Left expression button.

reporting builder 2.0

After clicking the expression button, you should see the following expression dialog.

reporting builder 2.0

4) Enter the following script in the expression textbox:

=CStr(2 + (Level()*10)) + "pt"

The Padding properties all require a string in the format nnyy, where nn is a number and yy is the unit of measure. The example expression builds a string that uses the Level function to increase the size of the padding based on recursion level. For example, a row with a level of 1 would result in a padding of (2 + (1*10))=12pt, and a row with a level of 3 would result in a padding of (2 + (3*10))=32pt.

Set Font Style

1) From the left property pane, select Font.

2) Under the Style section, click Bold expression button.

3) Enter the following script in expression textbox:

=IIF(Count(Fields!Name.Value, "Details", Recursive) > 1, "Bold", "Normal")

Essentially the Count function is searching the Fields!Name.Value, from within the "Details" group, recursively. If the recursive parent has children, then the parent is set to Bold, else Normal.

4) Click OK.

5) Right click on the Level field and click Expression...

6) Enter the following script:

=Level()

The Level() Function returns the current level (Integer) of depth in a recursive hierarchy.

7) Click OK.

5) Run the report. You should see similar results.

reporting builder 2.0

That's all there is to it.

Cheers!

Jul 22

This article describes how to render a list of data sources and dataset's from with a Report Definition (.RDL) file, while using the SQL Server Reporting Services Web Services. You will find a dowload of the code at the end of the article.

This article assumes you have the following:

  • SQL Server 2008 and Reporting Services installed
  • Microsoft Visual Studio 2008 installed
  • Experience with Reporting Services 2005/2008 
  • Experience with ASP.NET and C#
  • Experience with the Reporting Services SOAP API

Steps Taken:

  1. Create ASP.NET Web Application
  2. Reference Reporting Services Web Services SOAP API
  3. Add Web Form
  4. Reference required namespaces  
  5. Create code for both ListReportDataSource and ListReportDataset
  6. Run code 

Create ASP.NET Web Application

1) Open Microsoft Visual Studio 2008 from Start >> All Programs >> Microsoft Visual Studio 2008 >> Microsoft Visual Studio 2008

2) From the menubar, select File >> New >> Project

reporting builder 2.0

3) Expand the C# node and select the Web child node.

4) From the template pane, select ASP.NET Web Application.

5) Name the project "RSIntegrationDemo".

reporting builder 2.0

6) Click OK.

Reference Reporting Services SOAP API

1)  From within your Solution Explorer pane, right click on the project name and select Add Web Reference... to create a new web services reference.

reporting builder 2.0

2) For URL: enter "http://localhost/reportserver/ReportService2005.asmx?wsdl" (replace localhost with your server name, if different).

3) For Web Reference Name: enter RS2005.

reporting builder 2.0

4) Click Add Reference button.

You will notice a new folder named Web References with RS2005 reference located within the folder.

reporting builder 2.0

 You have completed referencing the Reporting Services WSDL

 Add Web Form

1) Create a new Web Form and name it "RSDataset.aspx".

Reference Namespaces

1) Open the RDLUpload.aspx.cs and add the following additional namespaces: 

using System.Web.Services.Protocols; // protocols used to transmit data across the wire using ASP.NET

using RSIntegrationDemo.RS2005; // your wsdl reference

//used for ListReportDataset

using System.Xml;

using System.Xml.XPath;

using System.IO;

Adding the Data Source Code

The ListReportDataSource method will return all data sources within a report, by using the GetItemDataSources method, within the Reporting Services SOAP API. The custom method ListReportDataSource takes one parameter - ReportPath (string).

  /// <summary>

        /// lists all datasources within a report definition (.rdl)

        /// </summary>

        /// <param name="reportName"></param>

        private void ListReportDataSource(string reportPath)

        {

            DataSource[] dataSources = null;

 

            try

            {

                dataSources = rs.GetItemDataSources(reportPath);

 

                if (dataSources != null)

                {

                    foreach (DataSource ds in dataSources)

                    {

                        Response.Write(ds.Name + "<br />");

                    }

                }

            }

            catch (SoapException e)

            {

                Response.Write(e.Detail.InnerXml.ToString());

            }           

        }

Adding the Dataset Source Code

The ListReportDataset method will return all dataset items within a report, by using the GetReportDefinition method, within the Reporting Services SOAP API. In addition to the GetReportDefinition, we use the following objects to help with reading the stream:

  • byte[] - array of bytes 
  • XmlDocument - Represents an XML document
  • MemoryStream - Creates a stream whose backing store is memory. In this case we use for initializing a new non-resizable instance of the MemoryStream class based on the specified byte array.
  • XmlNode - Represents a single node in the XML document. References our XmlDocument object.
  • XmlNodeList - Represents an ordered collection of nodes. All the elements under our Root Node (XmlNode reference and xpath).

The custom method ListReportDataset takes one parameter - ReportPath (string).

        /// <summary>

        /// List all dataset(s) names within a report definition (.rdl) file

        /// </summary>

        /// <param name="reportPath"></param>

        private void ListReportDataset(string reportPath)

        {

            byte[] reportDefinition = null;

            XmlDocument xmldoc = null;

 

            reportDefinition = rs.GetReportDefinition(reportPath);

 

            using (MemoryStream rdlFile = new MemoryStream(reportDefinition))

            {

                xmldoc = new XmlDocument();

                xmldoc.Load(rdlFile);

                rdlFile.Close();

            }

 

            XmlNode root = xmldoc.DocumentElement;

            // Get all the elements under the root node.

            XmlNodeList nodelist = root.SelectNodes("descendant::*");

 

            foreach (XmlNode node in nodelist)

            {

                if (node.Name == "DataSets") // Only search DataSets.

                {  

                    XmlNodeList childList = node.ChildNodes;

 

                    foreach (XmlNode childnode in childList)

                    {

                        if (childnode.Name == "DataSet") // Check if DataSet element exists.

                        {

                            Response.Write(childnode.Attributes["Name"].Value + "<br />");

                        }

                    }

                }

            }

        }

Run Code

1) You'll need to call the methods in your Page_Load before running your code. Enter the following code (change the report path to desired location):

  private ReportingService2005 rs;

 

        protected void Page_Load(object sender, EventArgs e)

        {

            rs = new ReportingService2005();

            // Create an instance of the Web service proxy and set the credentials

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

 

            if (!IsPostBack)

            {

                // get list of data sources...

                ListReportDataSource("/Corporate Reports/Company Sales 2008");

                // get list of dataset's...

                ListReportDataset("/Corporate Reports/Company Sales 2008");

            }

        }

That's it! Think about applying these concepts while using custom user controls for best results.

Cheers!

Download the code here: RSIntegrationDemo.zip (442.21 kb)

Jul 08

In this article we will describe how to programmatically add a new Folder and create Properties for the folder, using Reporting Services Web Services. For this example, we will be using the ListChildren, CreateFolder and GetProperties methods. The article also show's how to render a list of Reporting Services catalog items (e.g., reports, data sources, folders, etc) by searching the Property Name and Value. This could be helpful if you plan to group information using Reporting Services and want a way to narrow your search for catalog items.

Note:The use example for the FindItemsByPropertyValue method below may be applied to reports, or any other Reporting Services object that allows for custom properties - for this demo, we will only search against folders.

The ReportingService2005.CreateFolder method adds a new folder the Reporting Services database. Optionally, you can add an array of Property objects to the newly created folder to hold additional information. For example, you may want to create a new folder name KPI's and add a property named Department, with a value of "Sales and Marketing". The really cool thing about creating a custom property value is, it allows you to create metadata to help with categorizing your information. You can then run a search for all named properties of "Department" with a value of "Sales and Marketing".

This article assumes you have the following:

  • SQL Server 2008 and Reporting Services installed
  • Microsoft Visual Studio 2008 installed
  • Reporting Services 2008 installed and a configured Report Server
  • Experience with Reporting Services 2005/2008 
  • Experience with ASP.NET and C#
  • Exposure to Web Services

You may download the code below to follow along with article. 

Adding Namespaces

1) Create a new Web Form and name it "CreateFolder.aspx".

2) Open the CreateFolder.aspx.cs and add the following namespaces:

Creating a Folder and Properties

using System.Web.Services.Protocols; /* used for the SoapException */

using RSIntegrationDemo.RS2005; /* this is what I named the reference to the Reporting Services Web Services. */

using System.Data; /* used for our datatable and datarow */

using System.Drawing; /* used for Color object */

 

 1) Add the following method to your CreateFolder.aspx.cs file.

        /// <summary>

        /// Adds a new folder to the Reporting Services database

        /// </summary>

        /// <param name="parentFolder"></param>

        /// <param name="folderName"></param>

        /// <param name="props"></param>

        /// <returns></returns>

        public bool CreateNewFolder(string parentFolder, string folderName, Property[] props)

        {

            rs = new ReportingService2005();

            // Create an instance of the Web service proxy and set the credentials

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

 

            try

            {

                rs.CreateFolder(folderName, parentFolder, props);

                Label2.Text = "Success";

                Label2.ForeColor = Color.Blue;

                return true;

            }

 

            catch (SoapException e)

            {

                Label2.Text = "Failed";

                Label2.ForeColor = Color.Red;

                throw (new Exception(e.Detail.InnerXml.ToString()));               

            }

        }

 2) Next, add the following event that calls the method. Essentially, we're just creating an araay of property values and passing that to the CreateNewFolder method.

        protected void btnApply_Click(object sender, EventArgs e)

        {

            // create properties for folder

            Property[] props = new Property[2];

            Property desc = new Property();

            desc.Name = "Description";

            desc.Value = txtDescription.Text;

            props[0] = desc;

            Property department = new Property();           

            department.Name = "Department";

            department.Value = cmbDepartment.SelectedValue;

            props[1] = department;

 

            // add new folder and related properties

            // you can replace '/' with whatever root path you desire

            CreateNewFolder("/", txtFolderName.Text, props);

        }

Search Property Items

The method below traverses though catalog items, from within Reporting Services database, and render only those values that meet the Property Search criteria. We first start off by listing all children from the root (i.e., ListChildren("/", true)). Next, for each item found in the catalog, we pass the path to the item to the GetProperties method to get available properties. If the catalog item has a property, we then compare if the Keyword pass matches the propertis within the catalog item. You will notice the ItemTypeEnum is set to only search type of Folder.

        /// <summary>

        /// Search items by keyword

        /// </summary>

        /// <param name="propertyName"></param>

        /// <param name="keyword"></param>

        /// <returns></returns>

        public DataTable FindItemsByPropertyValue(string propertyName, string keyword)

        {

            rs = new ReportingService2005();

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

 

            DataTable dt = new DataTable();

            DataRow dr;

 

            // add column names for dataview

            dt.Columns.Add(new DataColumn("ReportPath", typeof(string)));

            dt.Columns.Add(new DataColumn("ReportName", typeof(string)));

            dt.Columns.Add(new DataColumn("Description", typeof(string)));

 

            // Create the property to retrieve.

            Property retrieveProp = new Property();

            retrieveProp.Name = propertyName;

            Property[] props = new Property[1];

            props[0] = retrieveProp;

 

            CatalogItem[] items;

 

            try

            {

                // if catalog path is empty, use root, if not pass the folde path

                if (keyword.Length != 0)

                {

                    items = rs.ListChildren("/", true); // no recursion (false)

 

                    // iterate through catalog items and populate datatable

                    foreach (CatalogItem item in items)

                    {

                        //If folder is hidden, skip it

                        if (item.Hidden != true)

                        {

                            // ensure only folders are rendered

                            if (item.Type.Equals(ItemTypeEnum.Folder))

                            {

                                Property[] properties = rs.GetProperties(item.Path, props);

                                // check to see if the property value matches the keyword

                                foreach (Property prop in properties)

                                {

                                    if (prop.Value == keyword)

                                    {

                                        dr = dt.NewRow();

                                        dr[0] = item.Path;

                                        dr[1] = item.Name;

                                        dr[2] = item.Description;

                                        dt.Rows.Add(dr);

                                    }

                                }

                            }

                        }

                    }

                }

            }

            catch(Exception e)

            {

                throw (new Exception(e.Message));

            }

 

            return dt;

        }

The code is provided as a concept to approaching Reporting Services Web Application Integration and is not recommeded for production use.

Optionally, you may consider using a custom user control to handle this functionality.

Cheers!

Download the code here:

RSIntegrationDemo.zip (442.21 kb)

Jul 02

This article will demo the use of Reporting Services SOAP API to integrate with a web application. We will begin by creating a new Web Project in VS 2008 and configuring the web.config so we can authenticate using impersonation. Next, we will reference the ReportingService2005 web services proxy object. Finally, enter some code to render a list of reports from within the Report Catalog.

For this example, we will be using Visual Studio 2008 and ASP.NET/C# for sample code.

This article assumes you have the following:

  • SQL Server 2008 and Reporting Services installed
  • Microsoft Visual Studio 2008 installed
  • Reporting Services 2008 installed and a configured Report Server
  • Experience with Reporting Services 2005/2008 
  • Experience with ASP.NET and C#
  • Exposure to Web Services

Steps Taken:

  1. Create a ASP.NET Web Application project
  2. Reference the Reporting Services WSDL
  3. Add Treeview control to web form
  4. Develop code to consume Reporting Services Web Service

Create new ASP.NET Web Application

1) Open Microsoft Visual Studio 2008 from Start >> All Programs >> Microsoft Visual Studio 2008 >> Microsoft Visual Studio 2008

2) From the menubar, select File >> New >> Project

reporting builder 2.0

3) Expand the C# node and select the Web child node.

4) From the template pane, select ASP.NET Web Application.

5) Name the project "RSIntegrationDemo".

reporting builder 2.0

6) Click OK.

Reference Reporting Services WSDL

1)  From within your Solution Explorer pane, right click on the project name and select Add Web Reference... to create a new web services reference.

reporting builder 2.0

2) For URL: enter "http://localhost/reportserver/ReportService2005.asmx?wsdl" (replace localhost with your server name, if different).

3) For Web Reference Name: enter RS2005.

reporting builder 2.0

4) Click Add Reference button.

You will notice a new folder named Web References with RS2005 reference located within the folder.

reporting builder 2.0

 You have completed referencing the Reporting Services WSDL

Adding a TreeView Control

1)  When you create your project, the ASP.NET Web Application template should have included a default.aspx page, along with a default.aspx.cs file. If you do not have this file, please add a new web form to your project and name it "default.aspx".

2) Open the default.aspx web form in design mode.

3) Point to the Toolbox pane (if not visible) and expand the Navigation tab.

4) Drag on drop the TreeView object to the default.aspx web form.

5) From within the design pane, right click the TreeView item you just added and select properties.

6) From the properties pane on the right, name the TreeView "tvCatalog".

Steps 7-9 are optional.

7) Right click on the TreeView object and click the right arrow to expand the TreeView Tasks.

reporting builder 2.0

8) Select Auto Format...

9) From the Select a scheme:, select "XP File Explorer" and then click OK.

10) Save your work.

Consuming the Reporting Services Web Service

1) Open the default.aspx.cs file.

2) In order to communicate with our web service we need to add the following reference to our file.

using RSIntegrationDemo.RS2005;

3) Add the following code above Page_Load(object sender, EventArgs e)

 private ReportingService2005 rs;

 

        protected void Page_Load(object sender, EventArgs e)

        {

 

4) We need to create and instance of ReportingService2005 and pass credentials in order to authenticate to the web service. Enter the following code within the Page_Load event.

 protected void Page_Load(object sender, EventArgs e)

        {

            rs = new ReportingService2005();

            // Create an instance of the Web service proxy and set the credentials

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

 

            if(!IsPostBack)

                BuildTreeView();

        }

Note: The DefaultCredentials property applies only to NTLM, negotiate, and Kerberos-based authentication. For ASP.NET applications, the default credentials are the user credentials of the logged-in user, or the user being impersonated. If you have problems authenticating, make sure the application pool account used has permissions to SSRS.  

5) Next, we will add our private methods, which will populate the treeview control with report items from the catalog. The first method, BuildTreeView() creates the Parent Node for our treeview control. The Method then calls the GetCatalogItems() method, which populates the treeview control with Report Items. 

Objects and Methods used:

CatalogItem - This object is used to return a report item from the report server database. We will pass an array of CatalogItem objects.

ListChildren - This will return a list of children withing a specified folder. For example, if we wanted all folder, reports, datasources, etc. returned, we would simply pass the following: 

 /// <summary>

        /// Build Treeview

        /// </summary>

        private void BuildTreeView()

        {

            TreeNode RootNode = new TreeNode();

            // give root node a name

            RootNode.Text = "Report Server";

            RootNode.Expanded = true;

            // add node to treeview object

            tvCatalog.Nodes.AddAt(0, RootNode);

            // populate treeview with catalog items

            GetCatalogItems(string.Empty, RootNode);           

        }

 

        /// <summary>

        /// recursivly get folder items from report

        /// server catalog; render to treeview control

        /// </summary>

        /// <param name="catalogPath"></param>

        /// <param name="parentNode"></param>

        private void GetCatalogItems(string catalogPath, TreeNode parentNode)

        {

            CatalogItem[] items;

 

            try

            {

                // if catalog path is empty, use root, if not pass the folder path

                if (catalogPath.Length == 0)

                {

                    items = rs.ListChildren("/", false); // no recursion (false)

                }

                else

                {

                    items = rs.ListChildren(catalogPath, false); // no recursion (false)

                }

 

                // iterate through catalog items and populate treeview control

                foreach (CatalogItem item in items)

                {

                    // if folder is hidden, skip it

                    if (item.Hidden != true)

                    {

                        // ensure only folders are rendered

                        if (item.Type.Equals(ItemTypeEnum.Folder) &

                            (item.Type != ItemTypeEnum.DataSource

                            & item.Name != "Data Sources"))

                        {

                            TreeNode folderNode = new TreeNode(item.Name, null);

                            folderNode.ImageUrl = GetNodeImage(item.Type);

                            folderNode.Text = item.Name;

                            folderNode.Value = item.Path;

                            folderNode.ToolTip = item.Name;

                            //Add the node to the parent node collection                           

                            parentNode.ChildNodes.Add(folderNode);

                            // recurse                      

                            GetCatalogItems(item.Path, folderNode);

                        }

                    }

                }

            }

            catch (Exception ex)

            {

                throw (new Exception(ex.Message));

            }

            finally

            {

                rs.Dispose();

            }

        } 

6) Add the following method to handle the node image

 /// <summary>

        /// Gets corresponding node image

        /// (e.g., folder, reports,..)

        /// </summary>

        /// <param name="type"></param>

        /// <returns></returns>

        private string GetNodeImage(ItemTypeEnum type)

        {

            string imagePath = string.Empty;

 

            switch (type)

            {

                case ItemTypeEnum.Folder:

                    imagePath = folderImage;

                    break;

                case ItemTypeEnum.Report:

                    imagePath = reportImage;

                    break;

                case ItemTypeEnum.LinkedReport:

                    imagePath = reportImage;

                    break;

            }

 

            return imagePath;

        }

 

7) Add the following Constants 

const string reportImage = "~/images/report.gif";

const string folderImage = "~/images/folder.gif";

You can get the images from the download below.

Optionally, you may consider using a custom user control to handle this functionality.

Download code here:

RSIntegrationDemo.zip (442.21 kb)

Jul 02

This article will provide an example of how to create a Shared Data Source and publish it to your Report Server. You may use the data source while developing reports in Report Designer and Report Builder 2.0 tools. For this example, we will be using SQL Server Business Intelligence Development Studio 2008.

This article assumes the following:

  • SQL Server 2008 and Reporting Services installed
  • Business Intelligence Development Studio (BIDS) or Report Builder 2.0
  • AdventureWorks database
  • Limited exposure to Reporting Services

Create Report Server Project

1) Open Business Intelligence Development Studio from Start >> All Programs >> Microsoft SQL Server 2008 >> SQL Server Business Intelligence Development Studio

2) From the menubar, select File >> New >> Project

reporting builder 2.0

3) Select the Report Server Project template. Give the project a name and save to your desired path location.

reporting builder 2.0

4) Click OK.

Set Deployment Properties

1) From the Solution Explorer pane, right click and select Properties.

reporting builder 2.0

 2) The Property Pages diaglog will open up. Enter the following values for the properties:

  • OverwriteDataSourcesFalse
  • TargetDataSourceFolder = Data Sources
  • TargetReportFolder = DataSourceDemo
  • TargetServerURL = http://localhost/reportserver

reporting builder 2.0

3) Click OK.

Create Shared Data Source

1) From within the Solution Explorer pane, right click Shared Data Sources >> Add New Data Source

reporting builder 2.0

The Shared Data Source Properties dialog shows

2) Enter "AventureWorks" for the Name field.

3) For Type, select Microsoft SQL Server from the dropdown list.

4) For the Connection String, click the Edit... button on the right of the textbox. The Connection Properties dialog will prompt you for values.

reporting builder 2.0

5) Use the Server Name dropdown to select your Server location, or if you are running it locally, simply enter a period "." (without the quotes) for a value. 

6) For the Log on to the Server section, select Use Windows Authentication option.

7) For the Connect to Database section, select Select of enter database name option. Using the dropdown, find AdventureWorks database.

Your Connection Properties dialog should look similar to the following:

reporting builder 2.0

8) Click the Test Connection button to test. You should received Test Connection Succeeded.

9) Click OK to save changes.

10) Click OK again to close Shared Data Source Properties window.

You should see the AdventureWorks data source in your Solution Explorer pane.

reporting builder 2.0

Publish Data Source

1) Right click on the AventureWorks.rds >> Deploy

The data source will be deployed to the Server location you specified earlier in this article. Look at the Output window for the deployment results. You should see Deploy Succeeded in the lower status bar.

reporting builder 2.0

That's it! You have completed Creating a Shared Data Source.

Cheers!

Jun 25

Cascading parameters are used to organize and limit the number of available values for the user. For example, you may have one parameter that filters a product category, and the second parameter used to list products related to product category. In this post we will walk through the steps of building a report and with query parameters for both product category and subcategory items. Then we will develop individual datasets to provide values for the cascading parameters. We will be using Report Builder 2.0 for this demo, but you may use the concepts presented below, while designing a report using BIDS.

This article assumes you have the following:

  • SQL Server 2008 and Reporting Services installed
  • Business Intelligence Development Studio (BIDS) or Report Builder 2.0
  • AdventureWorks database
  • Experience working with Reporting Services

Create report

1) Open Report Builder 2.0 from Start >> All Programs >> Microsoft SQL Server 2008 Report Builder 2.0.

2) From the upper left corner, click the red ribbon button, click Save As.

3) From within the left pane, select Recent Sites and Servers. Navigate to the location of where you would like to save your report.

4) Enter a Name for your report and click OK to save and close the Save As Report window. You should see a similar view.

reporting builder 2.0

Create Data Source

For this section, you may follow the steps from Introduction to Report Builder 20 Part 2 Creating a Report. This site will provide details along with images.

1) From the Report Data pane, create a new data source; select an existing shared data source.

2) You will be using the AdventureWorks sample database for this demo, please select this db as the source.

3) Click OK to save and close the Data Source Properties window.

Create Data Set and Parameters

1) From within the Report Data pane, select New >> Data Set

2) Make sure the Query item is selected in the left pane of the Dataset Properties window. Enter "TerritorySales" in the Name field.

3) Select "AventureWorks" from the Data Source dropdown, or the name you gave your data source.

4) Copy and paste the following T-SQL script to the Query textbox.

SELECT ST.Name AS Territory, SUM(DET.LineTotal) AS SalesAmount
FROM Sales.SalesPerson SP
    INNER JOIN Sales.SalesOrderHeader SOH ON SP.SalesPersonID = SOH.SalesPersonID
    INNER JOIN Sales.SalesOrderDetail DET ON SOH.SalesOrderID = DET.SalesOrderID
    INNER JOIN Sales.SalesTerritory ST ON SP.TerritoryID = ST.TerritoryID
    INNER JOIN Production.Product P ON DET.ProductID = P.ProductID
    INNER JOIN Production.ProductSubcategory PS ON P.ProductSubcategoryID = PS.ProductSubcategoryID      
    INNER JOIN Production.ProductCategory PC ON PS.ProductCategoryID = PC.ProductCategoryID
WHERE (PC.ProductCategoryID = @ProductCategory)
AND (PS.ProductSubcategoryID IN (@ProductSubcategory))
AND (SOH.OrderDate > @StartDate) AND (SOH.OrderDate < @EndDate)
GROUP BY ST.Name
ORDER BY SUM(DET.LineTotal) DESC

 You should have a similar view below

reporting builder 2.0

 5) Click OK to save changes and close the window.

6) From within the Report Data pane, expand the Parameters node. You'll notice several new parameters, as shown below.

reporting builder 2.0

Set Parameter Data Types and Default Values

1) From within the Report Data pane, right click @StartDate and select Parameter Properties.

2) From within the left pane of the Report Parameter Properties window, make sure General is selected.

3) Under Data Type, select Date/Time.

reporting builder 2.0

4) From within the left pane of the Report Parameter Properties window, select Default Values.

5) Select the Specify Values option.

6) Click Add.

7) Enter in 2001-01-01 and click OK.

reporting builder 2.0

8) Repeat the same steps for the @EndDate parameter, but set the default value to 2004-07-01

You are finished with setting the data types and default values.

Create Product Category Dataset and set Parameter values

1) From within the Report Data pane, select New >> Dataset...

2) Make sure the Query item on the left pane is selected; Enter ProductCategoryList.

3) Select the AdventureWorks from the Data Source dropdown list.

4) Copy and paste the following T-SQL script into the Query textbox:

SELECT DISTINCT PSC.ProductCategoryID AS ProductCategoryID, PSC.Name AS Category

FROM Production.ProductCategory AS PSC

      INNER JOIN Production.ProductCategory AS PC ON PC.ProductCategoryID = PSC.ProductCategoryID 

 

 5) Click OK to save your changes and close the Datset Properties window.

 The ProductCategoryList dataset should be visible in the Report Data pane.

Set the Product Parameter available and default values

1) From within the Report Data pane, expand the Parameters folder and right-click @ProductCategory, and then click Parameter Properties.

2) Check "Allow Multiple Values"

3) Click Available Values from the left pane.

4) From the right pane, select “Get values from a query” option.

5) For the Dataset value, select ProductCategoryList from the dropdown list.

6) Value field = ProductCategoryID.

7) Label field = Product.

6) Click OK.

Create Product Subcategory Dataset and set Parameter values

1) From within the Report Data pane, select New >> Dataset...

2) Make sure the Query item on the left pane is selected; Enter ProductSubcategoryList.

3) Select the AdventureWorks from the Data Source dropdown list.

4) Copy and paste the following T-SQL script into the Query textbox:

SELECT DISTINCT ProductSubcategoryID AS ProductSubcategoryID, PSC.Name AS Subcategory

FROM Production.ProductSubcategory AS PSC

      INNER JOIN Production.ProductCategory AS PC ON PC.ProductCategoryID = PSC.ProductCategoryID

WHERE PSC.ProductCategoryID = @ProductCategoryID

5) Click OK to save your changes and close the Datset Properties window.

 The ProductSubcategoryList dataset should be visible in the Report Data pane.

Set the ProductSubcategory Parameter available values

1) From within the Report Data pane, expand the Parameters folder and right-click @ProductSubcategory, and then click Parameter Properties. Click Available Values from the left pane.

2) From the right pane, select “Get values from a query” option.

3) For the Dataset value, select ProductSubcategoryList from the dropdown list.

4) Value field = SubcategorySubcategoryID.

5) Label field = Subcategory.

6) Click OK.

7) Click Run, from the ribbon above the Report Data pane.

You should see the following

 

8) Select an item from the Product Category dropdown and notice how Product Subcategory is populated with values.

Next, you could go back to design mode and add a Table or Matrix to the report to render data.

Cheers!

 

Jun 24

Reporting Services provides the ability to add references to embededed VB.NET code from within the report. You can use this feature to create reusable functions that are called more than once in a report. This post walks you though the steps needed to add embedded code to your reports.

Note: Custom code can include new custom constants, variables, functions, or subroutines. You can include read-only references to built-in collections such as the Parameters collection. However, you cannot pass sets of report data values to custom functions; specifically, custom aggregates are not supported.   

The article assumes you have the following:

  • Experience in designing reports in Reporting Services
  • Both SQL Server and Reporting Services installed
  • Business Intelligence Development Studio (BIDS)

Adding Embedded Code

1) Open and existing report project from BIDS.

2) From the Solution Explorer, double click on an existing report, or simply create a new one.

3) Select Design tab, and click your mouse anywhere in the design pane.

4) From the Toolbox pane, drag and drop a TextBox object to the report designer.

reporting builder 2.0

5) From the top menu bar select Report >> Report Properties

Note: if you don't see the Report menu item, try clicking your mouse anywhere in the design view; you should then see the menu item.

reporting builder 2.0

6) The Report Properties window opens. From within the left pane, select Code.

7) Enter the following VB.NET code in the Custom Code field.

Public Function Sec(ByVal angle As Double) As Double
    ' Calculate the secant of angle, in radians.
    Return 1.0 / Math.Cos(angle)
End Function

Public Function Sinh(ByVal angle As Double) As Double
    ' Calculate hyperbolic sine of an angle, in radians.
    Return (Math.Exp(angle) - Math.Exp(-angle)) / 2.0
End Function

Public Function GetPi() As Double
    ' Calculate the value of pi.
    Return 4.0 * Math.Atan(1.0)
End Function

reporting builder 2.0

8) Click OK to save and close the Report Properties window.

9) Right click on the Text Box you added previously and select Expression...

reporting builder 2.0

10) Enter the following code in the text box:

=Code.GetPi()

reporting builder 2.0

11) Click OK to save and close the Expression window.

12) Click the Preview tab to run the report. You should see a similar result.

reporting builder 2.0

That is it! Try calling the remaining functions to test your code.

Cheers!

function reference: http://msdn.microsoft.com/en-us/library/thc0a116(VS.80).aspx

Jun 24

For this post we will walk through the steps in creating a custom assembly and referencing it from Reporting Services 2008. After we reference the assembly we will can the call the static (shared) method from a texbox field, using a custom expression.

This article assumes you have the following:

  • SQL Server 2008 and Reporting Services installed
  • Business Intelligence Development Studio (BIDS) for report development
  • Experience with C# and SQL Server Reporting Services

Create custom assembly

1) Open Visual Studio 2008 and create a new Project.

reporting builder 2.0

2) The New Project window will open; Select the Visual C# node; from the right pane select Class Library. Complete the following:

  1. In the Name field enter "rsCustomAssembly"
  2. In the Location field enter "C:\Visual Studio 2008\Projects"
  3. In the Solution field enter "rsCustomAssembly"
  4. Click OK when you are done

reporting builder 2.0

3) Delete the default class.cs file created. When prompted click OK.

reporting builder 2.0

4) Add a new class by right clicking on the solution name and selecting Add >> Class...

reporting builder 2.0

5) Name the new class Utilities.

6) Enter the code below into the class file and save it.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace rsCustomAssembly

{

    public class Utilities

    {

        /// <summary>

        ///  Sample concatenate string method; not intended for production use.

        ///  Note: the string object already provides a concatenate method - string.concat(object o)

        /// </summary>

        /// <param name="string1"></param>

        /// <param name="string2"></param>

        /// <returns></returns>

        public static string Concat(string string1, string string2)

        {

            return string1 + " " + string2;

        }

 

        public static string HelloWorld()

        {

            return "HelloWorld";

        }

    }

}

Your screen should look similar

reporting builder 2.0

7) From the top menubar you will find Build; Click this and select rsCustomAssembly from the list. The bottom status bar should presenet Build succeeded. If not, check your code again to make sure it follows the description above.

Copy the assembly to the Visual Studio Private assemblies and Report Server bin

You must copy you assembly (.dll) to the report designer and report server folders before you can use the assembly in Reporting Services. You can find your assembly by locating the bin folder in your project. For example: C:\Visual Studio 2008\Projects\rsCustomAssembly\rsCustomAssembly\bin\Debug

Note: the location is dependent on your install

For Report Designer: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies

For Report Server: C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportServer\bin 

You have completed with this step.

Create a new Report

 This step we will perform the following:

  • Create a new report
  • Reference the custom assembly
  • Add a new textbox to the report designer with a custom expression

1) Open BIDS and create a new project, like you did in 1) under "Create custom assembly".

2) Under the Project Type pane, select Business Intelligence Projects; from within the Templates pane, select Report Server Project and complete the following:

  • For the Name field enter SampleReport
  • For the Location field enter C:\Visual Studio 2008\Projects
  • For the Solution field enter SampleReport
  • Click OK

reporting builder 2.0

3) From the Solution Explorer, right click on the Reports folder and select Add >> New Item

reporting builder 2.0

The Add New Item window will open

reporting builder 2.0

4) From within the Templates pane, select Report and leave the default name of Report1.rdl

5) Click Add

Reference the Assembly

1) From the top menu bar select Report >> Report Properties

Note: if you don't see the Report menu item, try placing your cursor anywhere in the design view; you should then see the menu item.

reporting builder 2.0

2) The Report Properties window opens. From within the left pane, select References.

3) Click Add under "Add or remove assemblies".

4) Click the ellipsis right of the text box. The Add Reference window will open.

reporting builder 2.0

5) Select the Browse tab and navigate to the Report Server bin location, where you copied your .dll, as described earlier in this article under Copy the assembly to the Visual Studio Private assemblies and Report Server bin

you should see a similar value in the reference text box

reporting builder 2.0

6) Click OK to save and close the Report Properties window.

Add Expression and run report

1) Drag and drop a Text Box from the Toolbox pane on the left of your design pane. Strech the text box so you have some room for text.

reporting builder 2.0

2) Right click the text box you just added and select Expression

reporting builder 2.0

3) For the expression value enter :

=rsCustomAssembly.Utilities.Concat("Reporting", "Services")

4) Click OK to save and close the Expression window.

5) To the right of the Design tab, click Preview. You should see the following:

reporting builder 2.0

Save your work. You have completed referencing a custom assembly in SQL Server Reporting Services.

Cheers!

Jun 22

In this post we will discuss changing the format of report items or properties based on the data in the report. We will show how build conditional expressions. For example: changing a row background color based on a field value.

To make styles conditional, we’ll an expression instead of a static value for the style properties of the item. At run time, the report processor evaluates the expression and substitutes the result for the property value, just as if you had set the property to a static value at design time. When the report is rendered, the run-time value is used.

We are using the report "SalesByFiscalYear" which we had created previously in the Introduction to Report Builder 2.0 Part 2 - Creating a Report post.

Changing Font Color

To make the font color of a textbox render values in red for a field called FullName, open the Properties pane and use the following expression in the Font >> Color property:

=Switch(Fields!FullName.Value = "Jillian  Carson", "Red",  Fields!FullName.Value ="Rachel B Valdez", "Red", Len(Fields!FullName.Value) > 0, "#4c68a2")

Note: You can consider using a IIF statement to accomplish the same result.

reporting builder 2.0

 

Alternating Row Color

To alternate the background color for every other row in your table, set the BackgroundColor property for each textbox in the row to the same conditional expression.

Note: This method works for detail rows only in a table with no groups.

=IIF(RowNumber(Nothing) MOD 2, "Khaki", "White")  

reporting builder 2.0

 Run the report. Select all in the dropdown list and view report. Expand Northwest and you should see a simliar view:

reporting builder 2.0