AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1837&pId=-1
Understanding the Crystal Reports Object Model
page
by Jeff McWherter
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 21207/ 48

Introduction

Many of the reporting applications that I have worked on have had many business rules that called for complex logic to manipulate specific aspects of the reports. In order to maintain the business rules easily, we want to abstract as many of these business rules out of the report as we can, and include them in external code before the report is rendered. In this article we will discuss the business objects (no pun intended) that Crystal Reports 2008 includes and how you can harness the power to create reports that are dynamic and customized for your needs.

Common Programmability Tasks

The Crystal Reports reporting API is very large, and handles many business use cases for enterprise and small business reporting applications. The two major objects that developers work with for rendering Crystal Reports with an application are the CrystalReportViewer and the ReportDocument. There are two types of CrystalReportViewer objects within Crystal Reports 2008. One is found inside of CrystalDescisions.Windows.Form assembly and is used for WinForms, and the other is found inside of CrystalDescisions.Web and is used for ASP.NET.

Getting Data to Your Reports

The first methods that developers are most likely to run into within the Crystal Reports object model are the methods that actually get the data to the ReportDocument.

Data Source

The DataSource property of the ReportDocument object has four overloads allowing a developer to pass in a Dataset, DataReader, Datatable or an IEnumerable containing the set of data that will be reported on.

In recent years with Object-Relational Mappers (ORM's) becoming more popular, the ability to pass an IEnumerable to the ReportDocument has become a very important option when generating reports.

SetParameterValue

The SetParameterValue is another common method that is used when getting data to Crystal Reports. The SetParameterValue sets the value of a parameter that is used within the report. I have learned through the creation of many Crystal Reports that it is best to have the data filtered before it gets to Crystal Reports. The DataSource that is passed to the report should only contain the data that should be shown in the report. Databases, such as SQL server, are much faster at filtering data then the Crystal Reports API.

Write XML Schema

This tip is not contained within the Crystal Reports Object model, but it is a tip that is relevant to getting data to the report. There is a handy method found on a DataSet object that will create an XML schema for the data contained in the DataSet. This schema contains information about the fields and the tables contained in the DataSet.

Listing 1: Using the WriteXmlSchema method

DataSet reportDataSet = FunctionThatGetsReportDataSet;
reportDataSet.WriteXmlSchema(@"C:\Report.xsd"); 

Listing 2: Example XML Schema

<?xml version="1.0" standalone="yes"?>
<xs:schema id="ArrayOfEmployee" xmlns="" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="ArrayOfEmployee" msdata:IsDataSet="true" 
  msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Employee">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="FirstName" type="xs:string" minOccurs="0" />
              <xs:element name="LastName" type="xs:string" minOccurs="0" />
              <xs:element name="Address" type="xs:string" minOccurs="0" />
              <xs:element name="City" type="xs:string" minOccurs="0" />
              <xs:element name="State" type="xs:string" minOccurs="0" />
              <xs:element name="PostalCode" type="xs:string" minOccurs="0" />
              <xs:element name="Role" type="xs:string" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

This XML schema can then be used within the Crystal Reports IDE as a data connection to render the fields to allow you to create a report.

Figure 1: Selecting the ADO.NET XML type as a connection type

Figure 2: ADO.NET XML connection with the XML schema selected

Figure 3: Field Explorer with the XML schema imported

Receiving Summary Information

Many reports have a variety of summary information saved within the report. In most cases the summary information is set during design time using the Crystal Reports IDE or the tools provided within Visual Studio. There may be times when you need to set the summary information at run time and the Crystal API provides a set of properties to accomplish this.

Listing 3: Report summary options

using (ReportDocument report = new ReportDocument())
{                
    report.Load(pathToReport);
    report.SetDataSource(reportData);
 
    report.SummaryInfo.ReportAuthor = "Jeff McWherter";
    report.SummaryInfo.ReportComments = 
        "Lists all customers for each year";
    report.SummaryInfo.ReportSubject = "Customers by Year";
    report.SummaryInfo.ReportTitle = "Customers by Year";
    report.SummaryInfo.KeywordsInReport = "Customers Year earnings";
}

Exporting

The default Crystal Report Viewer provides functionality to export a Crystal Report. Often times the functionality provided needs to be extended, or in some cases limited; in this situation you would most likely create your own export page using code similar to what is shown below.

The example below will get a set of data from the database, pass it to the report object, and then create an export of the report. Notice that the report is not rendered on the screen.

Listing 4: Exporting a Report programmatically

using (ReportDocument reportToExport = new ReportDocument())
{
    reportToExport.Load(pathToReport);
    reportToExport.SetDataSource(reportData);
    reportToExport.ExportOptions.ExportDestinationType =       
        CrystalDecisions.Shared.ExportDestinationType.DiskFile;
    
    reportToExport.ExportOptions.ExportFormatType =           
        CrystalDecisions.Shared.ExportFormatType.PortableDocFormat;
    reportToExport.ExportOptions.DestinationOptions = options;
    reportToExport.Export();
}

The Report Object model provides functionality to create exports in the following formats:

·         PDF

·         HTML 3.2 and HTML 4.0

·         MHTML

·         Microsoft Excel (97-2003)

·         Microsoft Excel (97-2003) Data-only

·         Microsoft Word (97-2003)

·         Microsoft Word (97-2003) - Editable

·         ODBC

·         Record Style - Columns with spaces and Record Style - Columns without spaces

·         Report Definition

·         Rich Text Format (RTF)

·         Separated Values (CSV)

·         Tab Separated Text (TTX)

·         Text

·         XML

·         XML Legacy

Suppressing Report Sections

Many times developers need to hide (suppress) a section of a Crystal Report. If the logic for this task were placed on the Crystal Report, it would make most sense to place it in a function. When I develop Crystal Reports, I try to keep Crystal Reports functions to a minimum. This makes the reports easier to maintain, and keeps business logic out of the report itself. Crystal Reports allows you to name sections to aid in finding them programmatically. When you open a Crystal Report in the Visual Studio IDE, the Crystal Reports tools provided there allow you to set the Name property on a section.

Figure 4: Name property of a section of a Crystal Report within Visual Studio

Listing 5: Suppressing a section programmatically

using (ReportDocument report = new ReportDocument())
{
    report.Load(pathToReport);
    report.SetDataSource(reportData);
 
    report.ReportDefinition.Sections["MySection"]
        .SectionFormat.EnableSuppress = true;
    crvViewer.ReportSource = report;
}

The Crystal Reports Viewer (Web Control)

Table 1: Selection of common properties worth describing

BestFitPag

For showing the report as-is or with scroll-bars.

DisplayBottomToolbar

Should the bottom toolbar be shown in the viewer, this defaults to true.

DisplayGroupTree

For showing the Group Tree on the left-hand side of the viewer.

HasPrintButton

Should the viewer show the button to display the dialog that will print the report, this defaults to true.

HasRefeshbutton

Should the viewer show the button that refreshes the data for the report, this defaults to true.

HasSearchButton

Should the viewer show the options that allow for searching in a report, it defaults to true.

HasZoomFactorList

Should the zoom features be shown, defaults to true

Height

Height of the report viewer control

Width

Width of the report viewer control

HasCrystalReportsLogo

Should the Crystal reports logo be shown in the toolbar, this defaults to true.

SeparatePages

For displaying a report in separate pages or one long page

ToolbarImagesFolderURL

Path to the images that are used for the toolbars, often times developers will override these images to match the style of their applcation

Dynamic Images

I was recently working with a client who felt that the charting component of Crystal Reports 2008 was not "elegant" enough. The client and I found a charting control that fit our needs, which would render the chart as a PNG. Before the report was rendered we called the charting control with our data to create the PNG, and then used logic similar to the example below to dynamically change an image.

Listing 6: Code to add the chart path to a dataset

DataSet chartData = new DataSet();
DataTable chartTable = new DataTable();                     
chartTable.Columns.Add("ChartImagePath");
            
// build the chart and set the image path to the ChartImagePath field
chartTable.Rows.Add(new object[] { 
GetChartPath(ref chartCustomers) });
            
chartData.Tables.Add(chartTable);
chartData.AcceptChanges();

Adding a dynamic image to your report

• Add an image to your report.

• Right click on the image and selecte "Format Graphic."

• On the "Picture Tab," Click the formula button (X+2 button).

• Create a formula to pull the chart image path from the dataset.

Figure 5: Graphic location

 

Figure 6: Graphic location formula

http://aspalliance.com/ArticleFiles/1787/image011.jpg

Conclusion

This article is just a brief exploration of the Crystal Reports Object model. With each version of Crystal Reports the API becomes more powerful, adding new features to allow you to control the finest details of a report programmatically. Using the tips in this article as a starting point, you should be able to start manipulating reports via code.


Product Spotlight
Product Spotlight 

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-05-10 5:47:28 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search