Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member200290
Contributor
0 Kudos

A question that keeps popping up from our .NET developer community is "How do I report off of my .NET classes or objects?" with Crystal Reports. Now recently it has changed to "How do I report off of PONO/POCO objects?".

In the support team we have not had the opportunity to explore this fully, so would give the less-then-satisfactory answer "Build the report off of an XSD file and put your data in a .NET DataTable object" because we knew that would work.

Since POCO/PONO has been a buzz word flying around our forums lately I took some time to investigate this and see how or if we work with non-dataset objects inside of Visual Studio .NET. Spoiler: We DO!

Before we go further I should explain my definition of what a POCO or PONO is. The acronym stands for Plain Old C#/CLR/NET Objects.  I found there are varying definitions of these objects and I am settling on this: POCOs are classes that contain no functionality required of a Common Language Runtime (CLR) or Framework. For example the code for the definition of a POCO in VB .NET should allow you to copy and paste it into VB 6 and it would still be valid. It should be easily represented in another language like Java as a POJO. As I said this is simplified and if you have any comments concerning this <u>please</u> provide feedback. For the rest of this blog I will just refer to this type of data as their basic type, class.

Crystal Reports is a reporting tool that expect to be reporting off of a table of indeterminate number of rows but with fixed amount of columns. So to report off of a class, the class should represent a row of data. What this means is that any properties that are not simple data types, such as numbers, dates and strings will not be available to Crystal. This means you couldn't report off of sub-classes.

Let's take the following simple classes:

class owner
{
        public string Name;
        public int Age;
}
class car
{
        public string Make;
        public string Model;
        public int Year;
        Owner TheOwner;
}

These are simple classes and Crystal can report off of both of them. The class Car would work but the property "TheOwner" would not be able to be read by Crystal.

How would you create a report off of this in the first place? The answer depends if you are in in the standalone Crystal designer or the VS .NET designer:

  • VS .NET Designer: You can follow the Crystal Designer above or even easier when you are in the Database Expert expand Project Data->.NET Objects and you will get a list of your available classes. Select your class and added it to Selected Tables box. You will then be able to add the properties/members of the class to your report just like they are database fields.


Once you have your report designed then the next step is passing this to the ReportDocument and ReportClientDoc objects. This is the step where most people got stuck. The methods to use would be ReportDocument.SetDataSource for Crystal Reports or ReportClientDoc.DatabaseController.SetDataSource for RAS. As these methods do not take a class object directly we need to make use of an intermediary Collection object. Just create a collection object to handle the same type as your class, add your class variable to it and then call SetDataSource to this collection. The collection has to have at least one item in it to work. Here is a sample based on the Car class above:

//Create three "car" objects from form input by user
car Car1 = new car ();
Car1.Make = "Ford";
Car1.Model = "Windstar";
Car1.Year = 2000;
car Car2 = new car();Car2.Make = "Ford";
Car2.Model = "Pinto";
Car2.Year = 1976;
car Car3 = new car();
Car3.Make = "Dodge";
Car3.Model = "Colt";Car3.Year = 1996;
// To make available to Crystal Reports place these in a Collection container
Collection cars = new Collection<car>();
cars.Add(Car1);
cars.Add(Car2);
cars.Add(Car3);
//Pass the data to the report and view it
CarReport1 myCarReport = new CarReport1();
myCarReport.SetDataSource(cars);
crystalReportViewer1.ReportSource = myCarReport;
5 Comments