IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from...

36
Using a Local Reporting Services 2008 Report with an ADO.NET Data Set February 9, 2009 — arcanecode SQL Server Reporting Services is an incredibly full featured reporting tool. An often asked question though is “How can I use Reporting Services without setting up a full SQL Server just to run Reporting Services?” Fortunately the folks at Microsoft thought of this, and created a version of Reporting Services that runs in Local, or what Microsoft calls Client mode. There are several ways to use client mode, you can bind the report right to the database if you wish, or to an object. However if you have an application that’s been around for a bit, or maybe you’ve been around for a bit, chances are you have a lot of ADO.NET DataSets you’d love to use for data in a report. Today we’ll look at how to bind those data sets to a SQL Server Reporting Services report. Let’s say you have created an application to work with the AdventureWorks2008 database. You user has now asked you for one last feature. They wish to display a list of Vendors in a report. They want to preview the report, print it, and be able to export it to a PDF format. Based on your experience you know that SQL Server Reporting Services would be a good choice. However your client does not have an instance of SQL Server Reporting Services running in their corporation. Thus the path is clear, use SQL Server Reporting Services in Client mode. Preliminary Work Prior to beginning our work, we’ll need to do two basic setup steps. First, if you don’t have it already, you will need to download the Adventure Works 2008 database from CodePlex. Install it following their instructions. Here is the current location for AdventureWorks2008: http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=18407 Now open up Visual Studio 2008 and create a new C# WinForms application. Note that while the ReportViewer control we’ll be using works fine in WinForms, ASP.Net, or WPF, for simplicity we’ll use a WinForms application. Give your project a meaningful name (I used ReportingServicesLocal). Create the DataSource

Transcript of IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from...

Page 1: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Using a Local Reporting Services 2008 Report with an ADO.NET Data SetFebruary 9, 2009 — arcanecode

SQL Server Reporting Services is an incredibly full featured reporting tool. An often asked question though is “How can I use Reporting Services without setting up a full SQL Server just to run Reporting Services?”

Fortunately the folks at Microsoft thought of this, and created a version of Reporting Services that runs in Local, or what Microsoft calls Client mode. There are several ways to use client mode, you can bind the report right to the database if you wish, or to an object. However if you have an application that’s been around for a bit, or maybe you’ve been around for a bit, chances are you have a lot of ADO.NET DataSets you’d love to use for data in a report. Today we’ll look at how to bind those data sets to a SQL Server Reporting Services report.

Let’s say you have created an application to work with the AdventureWorks2008 database. You user has now asked you for one last feature. They wish to display a list of Vendors in a report. They want to preview the report, print it, and be able to export it to a PDF format.

Based on your experience you know that SQL Server Reporting Services would be a good choice. However your client does not have an instance of SQL Server Reporting Services running in their corporation. Thus the path is clear, use SQL Server Reporting Services in Client mode.

Preliminary Work

Prior to beginning our work, we’ll need to do two basic setup steps. First, if you don’t have it already, you will need to download the Adventure Works 2008 database from CodePlex. Install it following their instructions. Here is the current location for AdventureWorks2008:

http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=18407

Now open up Visual Studio 2008 and create a new C# WinForms application. Note that while the ReportViewer control we’ll be using works fine in WinForms, ASP.Net, or WPF, for simplicity we’ll use a WinForms application. Give your project a meaningful name (I used ReportingServicesLocal).

Create the DataSource

Normally Reporting Services knows what tables and columns are available because you have setup a connection to a database. In this scenario however, we are going to bind the report to an in memory ADO.NET DataTable.

Page 2: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

At design time then Reporting Services does not know about the DataSet, and so we must create a surrogate for Reporting Services. Thus we’ll create a special type of XML schema definition to stand in for our not yet created DataSet.

To accomplish this, first we need to create the Data Source schema by following these steps:

1. Right click on the project in the Solution Explorer window.

2. Select Add, New Item.

3. Click on the Data leaf of the Visual C# Items branch in the Add New Item window.

4. Pick the DataSet item. Give it a meaningful name, such as VendorList.xsd.

Now we need to add a table to the DataSet.

1. In your toolbox, under DataSet find the Data Table tool and drag it onto the design surface.

2. Click the DataTable1 and rename it to Vendors.

The last step in the process is to add our columns to the Vendors DataTable we just created.

1. Right click on the name of your DataTable and pick Add, Column from the pop up menu.

2. For the first column type in VendorName. Note that if we needed to, we could now go to the properties window and change the DataType to something other than the default of System.String. For this lab, everything we’ll use is a string so this won’t be needed.

Page 3: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

3. Repeat step 2, adding these column names: AddressLine1, AddressLine2, City, StateProvinceName, PostalCode

When done it should look like:

Create the Report.

Now that we have a schema, we’re ready to create the report and add the components to it. To create the report, follow these basic steps.

1. Right click on the project and select Add, New Item.

2. In the pop up window, go to the Reporting leaf under the Visual C# branch.

3. Pick “Report”, and give the report a meaningful name such as VendorList.rdlc.

Page 4: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Now that the report is created, we need to add the components and data columns to it.

1. With the blank report, drag a Table control onto the report body.

2. Open the Data Sources window by selecting Data, Show Data Sources from the Visual Studio menu.

3. You should see the VendorList DataSet, under it the Vendors DataTable, and under it the columns.

4. Drag the VendorName to the first column of the table. Next, drag the City to the second column, and the StateProvinceName to the third.

5. Right click on the column header for StateProvinceName and pick “Insert Column to the Right”.

6. Drag the PostalCode to this newly inserted column. Your report should now look something like:

Adding the Report Viewer to the Windows Form

Now that the setup tasks are complete, it’s time to get to the user interface ready. First we’ll do some basic setup of the form.

1. When you created the basic project Visual Studio created a default Windows Form, Form1.cs. Start by changing the Text property to read “Report Viewer”.

2. While we’re at it, let’s change the (Name) property to frmReportViewer.

Now add the Report Viewer control to the form.

Page 5: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

1. In the toolbox, navigate to the Reporting area, and drag a MicrosoftReportViewer control onto the form. Resize so it takes up the lower 90% or so of the form.

2. Change the name to rvwMain (or something meaningful).

Next add a button to the form. We’ll use it to trigger the report.

1. From the Common Controls area of the toolbox, drag a button control onto the form.

2. Change the (Name) property to btnDataSet.

3. Change the Text property to DataSet.

4. Double Click on the button to open up it’s code behind.

We’ll be supplying the data to the ADO.Net dataset using SQL Server, so we need to go to the top of the form and add a reference to the System.Data.SqlClient.

using System.Data.SqlClient;

Now let’s go into the btnDataSet_Click event, and add some code to fill our dataset. This code snippet will bind to our local SQL Server, create a command to do a simple select statement to a view, and fill the dataset.

/* Fill the Dataset ------------------------------------*/ string qry = "select v.Name as VendorName " + ", v.AddressLine1 " + ", v.AddressLine2 " + ", v.City " + ", v.StateProvinceName " + ", v.PostalCode " + "from Purchasing.vVendorWithAddresses v " + "order by v.Name ";

string connectionstring = @"Server=(local);" + "Database=AdventureWorks2008;Trusted_Connection=True;";

SqlConnection connection = new SqlConnection(connectionstring); SqlCommand cmd = new SqlCommand(qry, connection);

SqlDataAdapter daVendor = new SqlDataAdapter(); daVendor.SelectCommand = cmd; DataSet dsVendors = new DataSet(); daVendor.Fill(dsVendors);

Note that in the first line of our select statement, we had to use v.Name as VendorName. The column names we return from our dataset must match the column names we entered in the Data Source back in Exercise 2 Step 3. Fortunately SQL easy to use “AS” syntax makes this simple.

Page 6: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Also, even though in this example we use SQL Server, the connection could be to any Data Source such as MySQL or Oracle. The important thing is we wind up with a DataSet to bind to.

In the same btnDataSet_Click method we now need to tell the report viewer control which report to run, then where to get it’s data. To tell the ReportViewer control to use a local report (as opposed to a report residing on a Reporting Services Server) we need to set the ReportEmbeddedResource property.

rvwMain.LocalReport.ReportEmbeddedResource = "ReportingServicesLocal.VendorList.rdlc";

Note the format of the string we pass in. It has the name of the project, then a dot, then the name of the report complete with it’s rdlc extension. You should also know this is case sensitive.

Now we need to tell the report where our data really is. To do this, we’ll tell it to bind the Vendor data table from the VendorList data source to the dataset we generated in the step above.

rvwMain.LocalReport.DataSources.Add( new Microsoft.Reporting.WinForms.ReportDataSource( "VendorList_Vendors", dsVendors.Tables[0]));

We need to create a new ReportDataSource to pass into the Add method of the reports DataSources. In the constructor for the ReportDataSource we pass in two parameters. The first is the name of the DataTable we are binding to.

Note that it’s syntax is a bit odd, you have to address it with first the DataSet name, then use an underscore to append the name of the specific DataTable.

The second parameter is the specific table from the dataset to bind to. Since we only had 1 we can use the simple .Tables[0] syntax shown here. We could have also given it a specific name.

One final note, in this simple example we are only binding one data source. However it’s possible for reports to have multiple data tables contained in them. To bind each one, we would simply have created a data table for each in the XSD, then added the code to the step above to read each one in, then bound them in this step by repeating this line of code for each one.

Finally we’re ready to display the report. Simply add this line to trigger the generation of the report.:

rvwMain.RefreshReport();

Test your application.

Everything is now setup, you should be ready to run.

1. Launch the app from Visual Studio.

2. Once open, click on the DataSet button.

Page 8: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

1. Esteban Arrubla Says: March 6, 2009 at 3:02 pm

Hi, I don’t speak in english but I’d like to know something…I tried to do this example, but I have a trouble…When I do click on the Button DataSet, I have a ErrorMessage that say me this: “Se ha producido un error durante el procesamiento local de informes.No se ha especificado la definición del informe ‘ReportingServicesLocal.VendorList.rdlc’ “….what can I do?….please, I’ll be waiting for an ans…Thanks…

Reply

2. Esteban Arrubla Says: March 6, 2009 at 3:02 pm

Se me había olvidado….muchas gracias por el ejemplo, está muy bueno…

Reply

3. Esteban Arrubla Says: March 6, 2009 at 3:23 pm

Ya lo solucioné…..muchas gracias 

Reply

4. Manu Says: May 28, 2009 at 10:23 am

Buenas,

¿¿podrías poner la solución??

Gracias.

Reply

5. James Says: February 19, 2010 at 6:22 am

Page 9: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Thanks! I’ve been looking for a simple way to do reporting for ages. All the examples are to do with running reporting services, rather than this local mode.

Now for a leisurely afternoon creating stored procedures and report templates, rather than a frustrated afternoon trying to understand the MSDN 

Reply

o Ed Crane Says: January 30, 2011 at 10:04 am

Great starter article. I just wanted to add a few things that might be helpful to folks wanting to do more advanced reports.

When you have multiple datasets(really just tables), you need to be able to distinguish fields from them. With tables/matrices/lists there is a property DataSetName that you can set to the name of your dataset. Be careful, the Report Designed sometimes obliterates this property when you add new datasets. For textboxes, you have to use the First function where the first argument is the Fields!.Value and the second argument is the name of the dataset, e.g., =First(Fields!City.Value, “VendorList_Vendors”).

When you want to have dynamic control values in the header/footer regions, you can’t reference dataset fields directly. Most folks put secondary controls in the report body, tie them to the dataset fields, hide them and then tie the header/footer controls to the hidden ones in the body.

That’s sort of sloppy and I’ve heard it doesn’t always work properly. A better way is to directly manipulate the xml in the rdl/rdlc files and then calling the the LoadReportDefinition method like so: b. viewer.LocalReport.LoadReportDefinition(new MemoryStream( System.Text.ASCIIEncoding.ASCII.GetBytes(xDoc.InnerXml))); where xDoc is an XmlDocument object with the modified rdlc xml.

When it comes to dynamic images in the the header/footer, a good way to achieve this is to add dummy embedded images to the report and point your header/footer image controls to the embedded images. Once again, you modify the value of the embedded images in the rdlc xml prior to loading the report definition in the viewer. Here’s a method:

public void SetHeaderImage(XmlDocument xDoc, string name, byte[] imgData, string format){XmlElement elem = null;XmlNode img = SelectSingleNode(xDoc.ChildNodes[1], “//Report/EmbeddedImages/EmbeddedImage[@Name='" + name + "']“);if (img != null)

Page 10: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

{elem = (XmlElement)SelectSingleNode(img, “./MIMEType”);elem.InnerText = format;elem = (XmlElement)SelectSingleNode(img, “./ImageData”);elem.InnerText = Convert.ToBase64String(imgData);}}

and here’s a helper method for selecting the right node:

public XmlNode SelectSingleNode(XmlNode start, string path){XmlNamespaceManager nsmgr = new XmlNamespaceManager(start.OwnerDocument.NameTable);nsmgr.AddNamespace(“rptDef”, “http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition”);if (path.StartsWith(“//”))path = “/” + path.Substring(1).Replace(“/”, “/rptDef:”);else if (path.StartsWith(“.//”))path = “./” + path.Substring(2).Replace(“/”, “/rptDef:”);elsepath = path.Replace(“/”, “/rptDef:”);

XmlNode node = start.SelectSingleNode(path, nsmgr);return node;}

Now you can have truly dynamic headers/footers.

For optional report sections, many folks use subreports, but I’ve heard that can be slow. Instead, I put all of my report sections inside Rectangle controls in the report body and manipulate the xml once again. Depending on what sections the user wants to see, I cut out the unwanted sections and adjust the elements based on the cumulative elements. Be careful: the report designer usually removes the element for the top-most control (when it’s located at position 0,0) and the element for the bottom-most control.

I hope this helps out some folks who want to do some cool stuff with client-side RS reporting.

Cheers!

Reply

Page 11: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Ed Crane Says: January 30, 2011 at 10:12 am

Whoa, the reply mechanism doesn’t seem to like angle brackets. It butchered the following:

“Depending on what sections the user wants to see, I cut out the unwanted sections and adjust the elements based on the cumulative elements. Be careful: the report designer usually removes the element for the top-most control (when it’s located at position 0,0) and the element for the bottom-most control.”

It should have been (with angle brackets around Top and Height):

“Depending on what sections the user wants to see, I cut out the unwanted sections and adjust the Top elements based on the cumulative Height elements. Be careful: the report designer usually removes the Top element for the top-most control (when it’s located at position 0,0) and the Height element for the bottom-most control.”

Also, set the BorderStyle to None for the rectangle controls (report sections).

6. Kritul Tulsidas Rathod Says: April 10, 2011 at 7:54 am

Hi There is just a small improvement here …I followed the steps mentioned in the article and was able to get desired result. However, I learned that once the report has been loaded with the data it doesn’t change the value.

My requirement was to add a text box along with the button to refresh the report. when user put some integer value in the text box and hit the button the data should be refreshed by using that integer value as filter (where clause in the query (variable: qry here).

Since the rvwMain.LocalReport.DataSources is a collection the report implicitly takes the first added source as the source to refresh the report in subsequent button clicks.

To resolve this issue I just cleared the DataSources collection of the LocalReport to get the desired result.Here is how to do it.

rvwMain.LocalReport.DataSources.Clear();rvwMain.LocalReport.DataSources.Add(…);

Just thought share it with everyone hoping that it might help the readers.

Page 12: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Thanks,Kritul

Reply

7. Agustin Says: April 12, 2011 at 12:19 pm

Muchas gracias por el ejemplo, ¡me fue de gran ayuda!

Reply

Leave a Reply

Enter your comment here...

Guest

Log In

Log In

Log In

Email (required)(Not published)

Name (required)

Website

 Notify me of follow-up comments via email.

 Notify me of new posts via email.

« Scott Hanselman Takes Over   MSN

Tracking down SQL Server Integration Services issues with   Collation  »

Blog at WordPress.com. Theme: Garland by Stefan Nagtegaal and Steven Wittens.

Page 13: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Blog Statso 2,676,609 hits

Pageso About Arcane   Code

o Arcane   Lessons

o Arcane   Links

the web applications.

Data flow in .NET applicationsTo understand where the problems come from with this beautiful feature added to Visual Studio .NET we need to understand how the data is transferred from the data provider (SQL Server) to CrystalReportViewer Object. Imagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. Then we conduct the data from dataset to CrystalReportViewer object to be displayed.

SQL Server -> SQLConnection -> SQLDataAdaptor -> DataSet -> CrystalReportDocument -> CrystalReportViewer -> ASP .NET web

Hey, what's going on here!? Yes, in .NET application Crystal Report Document reads the data from dataset, NOT directly from data provider and this is the key point to Crystal Report integration with .NET. As a result to open Crystal Reports into a web page we need to follow these steps:

Populating DataSet in the same way that we do it in ADO .NET Disconnected scenario.Creating the CrystalReportDocument Object and introducing populated DataSet as it's report source.

Redirecting the generated report to CrystalReportViewer web control that is provided by ASP .NET.

Let's do it

Ingredients:1. Visual Studio .NET or Visual Studio 2003

2. SQL Server 7.0/2000 (If you use MSDE you need to restore Northwind Database, it is not included in MSDE)

3. Microsoft windows XP Professional or 2000 (If you have problems running this code on Windows 2003 server send contact us)

Recipe

1. Preparing SQL Server to run ASP .NET Application

Open the SQL Server Enterprise manager, Expand SQL Server Group -> Computer Name -> Security. Then right-click on logins and New Login... . On General tab click on ellipses in front of the name textbox. Select ASPNET and click on Add, the press OK to add ASPNET account to logins. Then click on Database Access tab and check Northwind in the list. Press OK and make sure if the <ComputerName>\ASPNET account ( add <ComputerName>\IIS_WPG in windows 2003 server instead) is added to logins list. You don't need to give any other permission. Public user has read and write permission to Northwind Database.

Page 14: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

2. Creating a New ASP .NET web application

Run the visual Studio .NET and Create a new project. In the project types select Visual Basic Projects, and for the template select ASP .NET Web Application. Change the location to http://localhost/CrystalRepSample and click OK.

3. Connecting the application to Northwind Database in SQL Server and filling the DataSet with Northwind data.

Open the server explorer (Ctl+Alt+S), right-click on Data Connections, and then Add Connection, for the server name type localhost or (local) or the SQL Server instance name. Select Use windows NT Integrated security and then select Northwind from Select the database on the server.

In the server explorer expand the newly created connection to Northwind, expand the Tables and the drag the products table and drop it on the form. This creates an SQL ServerConnection object to Northwind asServerConnection1, and the SQLDataAdaptor1 to pump the data to the DataSet that we are just about to create.

Right-click on the SQLDataAdaptor1 and click on Generate DataSet... and then in the Generate Dataset dialog box just accept the defaults and click OK. The DataSet11 will be added to your form.

Double-Click on the Webform1 that will open the webform in code view. In the page load event add the proper code to populate the dataset using SQLDataAdaptor1 as following:

     SqlDataAdapter1.Fill(DataSet11, "Products")

Now we have a dataset with data that we can provide the data to report designer.4. Creating the report with Crystal Designer

In the project menu select Add New Item...

In the templates box select Crystal Report, change the name to rpProducts.rpt and and click Open.

To save the time just accept the Report Expert and standard report and press OK.

In the Standard report expert dialog box in the available data sources expand project data. Expand ADO .NET DataSets and expand CrystalRepSample.DataSet1, you will find Products table in there. Select it and click insert table. Then click Next.

 In the Fields tab just select some fields and click Add.

Just click on Finish button and your report is ready.

At the moment we have a report that reads data from an ADO .NET DataSet

5. Creating the web interface to present report

Open the Webform1.aspx in design mode.

Click on a white space on the form and the in the properties window set the pageLayout to FlowLayout. (This step is very important because we are using as Web Custom Control)

Go to the toolbox and click on Web Forms then select CrystalReportViewer from the list and drag and drop it in the webform1.aspx. CrystalReportViewer1 will be added to the form.

6. Providing the data to report

Page 15: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Open webform1.aspx in Code View and go to Page_Load sub.

AFTER the line of code that you have already added, add the following code

Dim cr As New rpProducts() ' Creates the ReportDocument object

cr.SetDataSource(DataSet11) ' Defines the source of data for report which is DataSet11

CrystalReportViewer1.ReportSource = cr ' Makes the ReoprtViewer web control to know it's report source

CrystalReportViewer1.DataBind() ' You need to remind CrystalReportViewer1 that there is some data. Update the interface 

7. Building and testing the application

Just press Ctl +F5 to build and run the application.

Back to articles list

 

Crystal Reports in ASP.NET

Crystal Reports is the standard reporting tool for Visual Studio .NET used to display data of presentation quality. You can display multiple-level totals, charts to analyze data, and much more in Crystal Reports. Creating a Crystal Report requires minimal coding since it is created in Designer interface. It is available as an integrated feature of Microsoft Visual Studio .NET, Borland Delphi, and C#Builder.

Advantages of Crystal Reports

Some of the major advantages of using Crystal Reports are:

Page 16: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

1. Rapid report development since the designer interface would ease the coding work for the programmer.

2. Can extend it to complicated reports with interactive charts and enhance the understanding of the business model

3. Exposes a report object model, can interact with other controls on the ASP.NET Web form

4. Can programmatically export the reports into widely used formats like .pdf, .doc, .xls, .html and .rtf

Implementation Models

Crystal Reports need database drivers to connect to the data source for accessing data. Crystal Reports in .net support two methods to access data from a data source:

The Pull Method

When this model is used to access data from the data source, the database driver directly retrieves the data from the data source. This model does not require the developer to write code for creating a connection and retrieving data from the data source. It is the Crystal report that manages the SQL commands for connecting by using the specified driver.

The Push Method

When this model is used to access data from data source, the developer writes the code to connect to the data source and retrieve data. The data from the data source is cached in dataset and multiple crystal reports accesses data from the dataset. The performance can be optimized in this manner by using connection sharing and manually limiting the number of records that are passed on to the report.

Crystal Reports Types

Crystal Report Designer can load reports that are included into the project as well as those that are independent of the project.

Strongly-typed Report

Page 17: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

When you add a report file into the project, it becomes a "strongly-typed" report. In this case, you will have the advantage of directly creating an instance of the report object, which could reduce a few lines of code, and cache it to improve performance. The related .vb file, which is hidden, can be viewed using the editor's "show all files" icon in the Solution Explorer.

Un-Typed Report

Those reports that are not included into the project are "un-typed" reports. In this case, you will have to create an instance of the Crystal Report Engine's "ReportDocument" object and manually load the report into it.

Creating Crystal Reports

You can create a Crystal Report by using three methods:

1. Manually i.e. from a blank document2. Using Standard Report Expert3. From an existing report

Using Pull Method

Creating Crystal Reports Manually.

We would use the following steps to implement Crystal Reports using the Pull Model:

1. Create the .rpt file (from scratch) and set the necessary database connections using the Crystal Report Designer interface.

2. Place a CrystalReportViewer control from the toolbox on the .aspx page and set its properties to point to the .rpt file that we created in the previous step.

3. Call the databind method from your code behind page.

I. Steps to create the report i.e. the .rpt file

1) Add a new Crystal Report to the web form by right clicking on the "Solution Explorer", selecting "Add" --> "Add New Item" --> "Crystal Report".

Page 18: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

2) On the "Crystal Report Gallery" pop up, select the "As a Blank Report" radio button and click "ok".

Page 19: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

3) This should open up the Report File in the Crystal Report Designer.

4) Right click on the "Details Section" of the report, and select "Database" -> "Add/Remove Database".

5) In the "Database Expert" pop up window, expand the "OLE DB (ADO)" option by clicking the "+" sign, which should bring up another "OLE DB (ADO)" pop up.

6) In the "OLE DB (ADO)" pop up, Select "Microsoft OLE DB Provider for SQL Server" and click Next.

Page 20: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

7) Specify the connection information.

8) Click "Next" and then click "Finish"

9) Now you should be able to see the Database Expert showing the table that have been selected

10) Expand the "Pubs" database, expand the "Tables", select the "Stores" table and click on ">" to include it into the "Selected Tables" section.

Note: If you add more than one table in the database Expert and the added tables have matching fields, when you click the OK button after adding the tables, the links between the added tables is displayed under the Links tab. You can remove the link by clicking the Clear Links button.

Page 21: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

11) Now the Field Explorer should show you the selected table and its fields under the "Database Fields" section, in the left window.

12) Drag and drop the required fields into the "Details" section of the report. The field names would automatically appear in the "Page Header" section of the report. If you want to modify the header text then right click on the text of the "Page Header" section, select "Edit Text Object" option and edit it.

13) Save it and we are through.

Page 22: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

II. Creating a Crystal Report Viewer Control

1) Drag and drop the "Crystal Report Viewer>" from the web forms tool box on to the .aspx page

2) Open the properties window for the Crystal Report Viewer control.

3) Click on the [...] next to the "Data Binding" Property and bring up the data binding pop-up window

4) Select "Report Source".

5) Select the "Custom Binding Expression" radio button, on the right side bottom of the window and specify the sample .rpt filename and path as shown in the fig.

6) You should be able to see the Crystal Report Viewer showing you a preview of actual report file using some dummy data and this completes the inserting of the Crystal Report Viewer controls and setting its properties.

Note: In the previous example, the CrystalReportViewer control was able to directly load the actual data during design time itself as the report was saved with the data. In this case, it will not display the data during design time as it not saved with the data - instead it will show up with dummy data during design time and will fetch the proper data only at run time.

7) Call the Databind method on the Page Load Event of the Code Behind file (.aspx.vb). Build and run your .aspx page. The output would look like this.

Page 23: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Using a PUSH model

1. Create a Dataset during design time.

2. Create the .rpt file (from scratch) and make it point to the Dataset that we created in the previous step.

3. Place a CrystalReportViewer control on the .aspx page and set its properties to point to the .rpt file that we created in the previous step.

4. In your code behind page, write the subroutine to make the connections to the database and populate the dataset that we created previously in step one.

5. Call the Databind method from your code behind page.

I. Creating a Dataset during Design Time to Define the Fields of the Reports

1) Right click on "Solution Explorer", select "Add" --> select "Add New Item" --> Select "DataSet"

Page 24: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

2) Drag and drop the "Stores" table (within the PUBS database) from the "SQL Server" Item under "Server Explorer".

Page 25: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

3) This should create a definition of the "Stores" table within the Dataset

The .xsd file created this way contains only the field definitions without any data in it. It is up to the developer to create the connection to the database, populate the dataset and feed it to the Crystal Report.

II. Creating the .rpt File

4) Create the report file using the steps mentioned previously. The only difference here is that instead of connecting to the Database thru Crystal Report to get to the Table, we would be using our DataSet that we just created.

5) After creating the .rpt file, right click on the "Details" section of the Report file, select "Add/Remove Database"

6) In the "Database Expert" window, expand "Project Data" (instead of "OLE DB" that was selected in the case of the PULL Model), expand "ADO.NET DataSet", "DataSet1", and select the "Stores"table.

7) Include the "Stores" table into the "Selected Tables" section by clicking on ">" and then Click "ok"

Page 26: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

8) Follow the remaining steps to create the report layout as mentioned previously in the PULL Model to complete the .rpt Report file creation

III. Creating a CrystalReportViewer Control

9) Follow the steps mentioned previously in the PULL Model to create a Crystal Report Viewer control and set its properties.

Code Behind Page Modifications: 10) Call this subroutine in your page load event:

    Sub BindReport()        Dim myConnection As New SqlClient.SqlConnection()        myConnection.ConnectionString = "server= (local)\NetSDK;database=pubs;Trusted_Connection=yes"        Dim MyCommand As New SqlClient.SqlCommand()        MyCommand.Connection = myConnection        MyCommand.CommandText = "Select * from Stores"        MyCommand.CommandType = CommandType.Text        Dim MyDA As New SqlClient.SqlDataAdapter()        MyDA.SelectCommand = MyCommand        Dim myDS As New Dataset1()        'This is our DataSet created at Design Time              MyDA.Fill(myDS, "Stores")        'You have to use the same name as that of your Dataset that you created during design time        Dim oRpt As New CrystalReport1()        ' This is the Crystal Report file created at Design Time        oRpt.SetDataSource(myDS)        ' Set the SetDataSource property of the Report to the Dataset        CrystalReportViewer1.ReportSource = oRpt

Page 27: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

        ' Set the Crystal Report Viewer's property to the oRpt Report object that we created    End Sub

Note: In the above code, you would notice that the object oRpt is an instance of the "Strongly Typed" Report file. If we were to use an "UnTyped" Report then we would have to use a ReportDocument object and manually load the report file into it.

Enhancing Crystal Reports

Accessing filtered data through Crystal reports

Perform the following steps for the same.

1. Generate a dataset that contains data according to your selection criteria, say "where (cost>1000)".

2. Create the Crystal Report manually. It would look like this.

3. Right Click Group Name fields in the field Explorer window and select insert Group from the shortcut menu. Select the relevant field name from the first list box as shown.

Page 28: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

The group name field is created, since the data needs to be grouped on the basis of the cat id say.

4. A plus sign is added in front of Group Name Filed in the field explorer window. The Group Name Field needs to be added to the Group Header section of the Crystal Report. Notice this is done automatically.

5. Right Click the running total field and select new. Fill the required values through > and the drop down list.

Page 29: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

6. Since the count of number of categories is to be displayed for the total categories, drag RTotal0 to the footer of the report.

Create a formula

Suppose if the report required some Calculations too. Perform the following steps:

1. Right Click the formula Fields in the field explorer window and select new. Enter any relevant name, say percentage.

2. A formula can be created by using the three panes in the dialog box. The first pane contains all the crystal report fields, the second contains all the functions, such as Avg, Sin, Sum etc and the third contains operators such as arithmetic, conversion and comparison operators.

3. Double click any relevant field name from the forst pane, say there's some field like advance from some CustOrder table. Then expand Arithmetic from the third pane and double click Divide operator.

4. Double click another field name from the first which you want to use as divisor of the first field name already selected say it is CustOrder.Cost.

5. Double Click the Multiply from third pane and the type 100.

6. The formula would appear as {CustOrder.Advance}/{ CustOrder.Cost} * 100.

7. Save the formula and close Formula Editor:@Percentage dialog box.

8. Insert the percentage formula field in the details pane.

9. Host the Crystal report.

Exporting Crystal reports

Page 30: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

When using Crystal Reports in a Web Form, the CrystalReportViewer control does not have the export or the print buttons unlike the one in Windows Form. Although, we can achieve export and print functionality through coding. If we export to PDF format, Acrobat can handle the printing for us, as well as saving a copy of the report.

You can opt to export your report file into one of the following formats:

o PDF (Portable Document Format)o DOC (MS Word Document)

o XLS (MS Excel Spreadsheet)

o HTML (Hyper Text Markup Language - 3.2 or 4.0 compliant)

o RTF (Rich Text Format)

To accomplish this you could place a button on your page to trigger the export functionality.

When using Crystal Reports in ASP.NET in a Web Form, the CrystalReportViewer control does not have the export or the print buttons like the one in Windows Form. We can still achieve some degree of export and print functionality by writing our own code to handle exporting. If we export to PDF format, Acrobat can be used to handle the printing for us and saving a copy of the report.

Exporting a Report File Created using the PULL Model

Here the Crystal Report takes care of connecting to the database and fetching the required records, so you would only have to use the below given code in the Event of the button.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e AsSystem.EventArgs) Handles Button1.Click        Dim myReport As CrystalReport1 = New CrystalReport1()        'Note : we are creating an instance of the strongly-typed Crystal Report file here.         Dim DiskOpts As CrystalDecisions.Shared.DiskFileDestinationOptions = NewCrystalDecisions.Shared.DiskFileDestinationOptions        myReport.ExportOptions.ExportDestinationType = CrystalDecisions.[Shared].ExportDestinationType.DiskFile        ' You also have the option to export the report to other sources        ' like Microsoft Exchange, MAPI, etc.                 myReport.ExportOptions.ExportFormatType = CrystalDecisions.[Shared].ExportFormatType.PortableDocFormat        'Here we are exporting the report to a .pdf format.  You can        ' also choose any of the other formats specified above.          DiskOpts.DiskFileName = "c:\Output.pdf"        'If you do not specify the exact path here (i.e. including        ' the drive and Directory),        'then you would find your output file landing up in the        'c:\WinNT\System32 directory - atleast in case of a        ' Windows 2000 System

Page 31: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

        myReport.ExportOptions.DestinationOptions = DiskOpts        'The Reports Export Options does not have a filename property        'that can be directly set. Instead, you will have to use        'the DiskFileDestinationOptions object and set its DiskFileName        'property to the file name (including the path) of your  choice.        'Then you would set the Report Export Options        'DestinationOptions property to point to the        'DiskFileDestinationOption object.          myReport.Export()        'This statement exports the report based on the previously set properties.     End Sub

Exporting a Report File Created Using the PUSH Model

Using Push Model, the first step would be to manually create connections and populate the Dataset, and set the Report's "SetDataSource" property to the required Dataset (in the same manner as shown in the Push Model example before). The next step would be to call the above given Export.

Crystal Reports alternatives

Many people found Crystal Reports hard to learn and use and they are seeking for simpler alternatives. I suggest you to try Stimulsoft reports especially if you work with complex reports. Stimulsoft is much easier to use but also easier to deploy with your application since you deploy only one more .NET assembly, written in C#. In some areas (designer, working with different data sources, subreports) it is even better than Crystal.

f you have to create a report in Crystal Reports from multiple data sources or provide multiple views of the data, you may find sticky situations because CR does not allow you to have multiple Detail sections in a single report. For example, say you have to display data from two tables on the same report page. Now say, you create two Detail sections and bind each Detail section with a table, you will find second table records repeating within the first table records. 

For example, if I want to generate a report that looks like Figure 1.

Report Header  - Page Header       o Detail - Data from Customers table       o Detail - Data from Orders table  - Page FooterReport Footer

Figure 1.

Page 32: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

To do this, you will have to create two details sections on the same level, not recursive.

The work around for this is using sub reports. What we do is to create two sub reports, one for Customers and one for Orders. These sub reports have nothing but a single Detail section.

Now we create two Page Header sections on the main report and put a sub report on each Page Header sections. The new report looks like Figure 2.

Report Header  - Page Header 1      o Sub Report 1  - Page Header 2      o Sub Report 2      o Detail Section (Hide it)  - Page FooterReport Footer

Figure 2.

In the above format in Figure 2, we treat each sub report as a separate report. Now you can bind each sub report with a separate DataSet or DataTable. 

For example, if we have data coming in a DataSet from two tables-Customers and Orders, the following code binds each DataTable to a separate sub report: 

Dim report As New DynamicReportreport.SetDataSource(ds)report.Subreports.Item("SubReport1").SetDataSource(ds.Tables("Customers"))report.Subreports.Item("SubReport2").SetDataSource(ds.Tables("Orders"))CrystalReportViewer1.ReportSource = reportCrystalReportViewer1.DataBind()

Similarly, your data can be coming from multiple data sources; you can bind as many as sub reports with different data sources.

Note: In the above code, DynamicReport is the class name of crystal report. For example, if you have a crystal report called "MyReport.rpt" and you add this report to the VS.NET project, you will see a class "MyReport.cs" or "MyReport.vb" depending on the language you choose. Make sure you change DynamicReport with your class name "MyReport".

Page 33: IT/C#/C#-NOTES/Reporti…  · Web viewImagine we are using ADO .NET to get a subset of data from SQL Server and store it in a DataSet. ... Borland Delphi, ... (MS Word Document)

Summary

In this article, we learned how to create multiple sub reports and bind them with multiple data source using DataSet. Using the same approach, you can get data from multiple data sources in a single report.