Scott on Writing

Musings on technical writing...

Binding a Strongly-Typed Collection to a Crystal Report

Prior to today you could count the number of hours I've used Crystal Reports on one hand.  Despite that, I'm working on a project now where my client needs to be able to print invoices based on the data collected through a Web application I've already created for him.  Namely, he needs a PDF document that corresponds to some pretty specific dimensions, and already has bought Crystal Reports and wants to use that.  (He also needs a number of Web-based reports through CR as well.)

To start off my journey into Crystal Reports, I started creating some simple reports through the templates provided by the Crystal Report Designer that ships with Visual Studio .NET.  While it was pretty easy to create elegant reports based on database data, this application is designed into distinct layers, with an application logic layer and business objects used to represent the logical entities of the system (rather than direct SQL queries and whatnot).  My challenge, then, was to figure out how to have CR let me bind a custom, strongly-typed collection to the report rather than going straight to the database.

Not having much luck, I popped over to the ASP.NET Crystal Reports Forum, which I hadn't used before, and asked my questionRichard Dudley was kind enough to answer my question by providing a number of great links, this one solving the problem at hand (see the (currently) second to last message in the thread, the one from rjdudley), in conjunction with the CR document Reporting Off ADO.NET DataSets.  Essentially what I did was this:

  1. Create a strongly-typed DataSet, designing the schema to correspond to the particular invoice information I needed to display on the report (date, description of work performed, hours, rate, total, etc.).  I called this InvoiceDataSet.
  2. Next, I created an ASP.NET page that would display the invoice in PDF format, called ViewInvoice.aspx.  This page accepted a parameter through the querystring, indicating the ID of the invoice to display.
  3. Next I added a Crystal Report to my Project named InvoiceReport.  In the wizard, I opted to base my data from an ADO.NET DataSet in the Project, selected the strongly-typed DataSet I had created in step 1, and added all rows.  I then played with the Designer to get it to look like I wanted (added some fields that computed sums, added some boilerplate “Thank you for your business“ platitudes, etc., etc.).
  4. Now, to bind the custom strongly-typed collection to the Crystal Report, I used the following code:

    'Create an instance of the report (remember, InvoiceReport is the name of the report I created)
    Dim invReport As New InvoiceReport

    'Create an instance of the strongly-typed DataSet
    Dim ds As New InvoiceDataSet

    'Populate the DataSet - DAL is my data access layer class, GetInvoiceActivities gets all of the activities
    'for an invoice.  invID is a local variable that contains the invoice ID passed in through the querystring
    Dim invoiceActivities As ActivityList = DAL.GetInvoiceActivities(invID)

    For Each act As Activity In invoiceActivities
        'Adds a new row to the strongly-typed DataSet.  My DataSet was created having
        'columns for description, the date, the rate, the hours, and the total due (the reason I
        'have a total due and not just compute it via rate * hours is that some activities are billed
        'at a flat rate, so the actual amount due is just rate * 1, regardless of hours; this is all
        'done at the application layer level, though, not here in the presentation layer).
        ds.Invoice.AddInvoiceRow(act.Description, act.Date, act.Rate, act.Hours, act.TotalDue)
    Next

    'Finally, we assign the DataSet to the report!
    invReport.SetDataSource(ds)
  5. At this point if you want to display the report in HTML, simply add a CrystalReportViewer control to your page and assign the control's ReportSource property the invReport object.  However, if you want to display the report as PDF, you can use the code over at this USENET post by Steve Volp to stream the PDF directly to the browser (no need to save the PDF locally on the Web server's file system).

Since I have a good deal of Crystal Reports in my future, I think I'll pick up a copy of Brian Bischof's Crystal Reports for .NET.  On an aside, I had lunch with Brian a year or so ago and talked about, among other things, self-publishing.  Interestingly, Crystal Reports for .NET is a self-published work by Brian.  So you can buy it knowing that you're directly supporting the author, rather than just supporting him 10%.  :-)

posted on Thursday, October 07, 2004 4:56 PM

Feedback

# re: Binding a Strongly-Typed Collection to a Crystal Report 10/7/2004 5:36 PM Richard Dudley

Glad you got it working!

Two things to note about ExportToStream:

1) It actually does spool the export to disk, in a temporary directory outside of the web root. While this won't junk up your web dir with exported files, you will run into a permissions error if you use impersonation.

2) ExportToStream, despite being a documented feature, is considered an undocumented feature by Business Objects. I have some summary on this blog post:
http://dotnetjunkies.com/WebLog/richard.dudley/archive/2004/05/26/14543.aspx

# Using Crystal Reports for .NET 10/7/2004 9:52 PM Armando Andrade

Well I have been using CR.NET for about 4 months, working to develop differnt kinds of reports for the company´s ERP (Great Plains), we started developing the reports in Crystal 8.5 and now we are using version 9. I don´t know if it´s the same with all the programmers but we have run into lot of troubles using CR.NET, sometimes the reports won´t even show up. It´s kinda strange. What we do is to develop a simple wrapper class to develop the reports, i don´t know if you would like (scott) to send the source code, so your readers could check it out and make it a better class. In our current portal we are using the skMenu with a great result.....
Thank You.

# re: Binding a Strongly-Typed Collection to a Crystal Report 10/8/2004 10:05 AM Jason Pacheco

Thank god. You hit this right on the head. I amd designing a web application for the US Navy and I have had this issue in the back of my head from day one of architecture design. The application is an intranet and I knew I was going to need considerable reporting capabilities, so naturally I thought of Crystal Reports. However, I also knew that Crystal Reports didn't offer the ability to bind off of custom objects. Well it was just early this week that I finally hit the point where I needed to start building reports and I wanted to stream them to the browser as PDF reports. So I just started my cruisade to solve the issue of binding reports to custom objects. Its like your post on the ASP.NET forum came out of the heavens or something, that made my day and saved me weeks of researching. Thank you.

One question though. Prior to building the reports, did your architecture contain any strongly-typed data sets in the Domain Layer? Or were they purely 100% custom objects? I am trying to determine if you created the strongly typed data set specifically to use as a basis for the report.

# re: Binding a Strongly-Typed Collection to a Crystal Report 10/8/2004 10:19 AM Scott Mitchell

Jason, I don't use strongly-typed DataSets in my architecture. I created them specifically for the report. And these strongly-typed DataSets don't necessarily reflect my logical entities within the system, but rather provide just the schema needed for the particular report.

# re: Binding a Strongly-Typed Collection to a Crystal Report 10/8/2004 10:52 AM Jason Pacheco

Thank You! That was the perfect answer for me! You don't know how great you just made my whole day, and how much work you just saved me in research hours. I think I'll take the rest of the day off and I'll still be ahead, ha.

Just as an aside, it sounds like my application and the one that is the topic of your blog entry are both somewhat similar in purpose as well as architecture. I'm wondering if you could please comment on why you used a completely custom middle-layer for the application in the first place. I know why I used them, but I am still a neophyte in the arena. I was wondering what kind of architectural considerations drew you to using a completely custom domain layer and moving away from the DataSets/DataReaders that are so prevalent in architectures involving ADO.NET. Lastly, I am interested in any other tradeoffs/issues that you ran into having a custom-built domain layer or other things that I may run into later on in the game.

# Crystal Reports Tip for the Day 10/8/2004 1:00 PM Scott on Writing

# CR .NET 2005 To Support Custom Collections and Dataviews 10/29/2004 6:14 AM Richard Dudley

CR .NET 2005 To Support Custom Collections and Dataviews

# Crystal Reports Book for .NET 10/29/2004 10:41 AM Scott on Writing

# re: Binding a Strongly-Typed Collection to a Crystal Report 5/5/2005 2:52 PM Lily

Thanks for the example. I used it in the windows form. However, I got "Unable to find the report in the manifest resources. Please build the project and try again.". I did set the BuildAction to embeded resources, but it does not help. I can see the dataset from the datagrid control.

I am using .NET framework 1.1 and VS 2003. Any help would be appreciated.

# re: Binding a Strongly-Typed Collection to a Crystal Report 8/8/2005 10:28 AM newmem

I was able to bind a strongly-typed dataset to a crtsyal report. But I need to include sub-reports in the main report.
I did not have any success with assigning a dataset to a sub-report. any pointers or example would be great.

Thanks in advance.

# re: Binding a Strongly-Typed Collection to a Crystal Report 11/1/2005 5:53 AM mlacy

I have a similar issue with binding data to a subreport at runtime. I am also getting the "Unable to find the report in the manifest resources" error. Any help would be greatly appreciated.

# re: Binding a Strongly-Typed Collection to a Crystal Report 2/9/2006 8:31 PM Eric Stump

just a question - our application uses CR for quite a few on-line reports and forms, all of which are data driven. We only use strong typed collections for special cases. The rest of them use stored procedures directly attached to the reports. Is there a reason to use the typed colelctions instead of stored procs?

Title:  
Name:  
Url:
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments   

Add To Your Reader

My Links

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<May 2008>
SMTWTFS
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Comment Stats

DayTotal% of Total
Sunday 1866.8%
Monday 37913.9%
Tuesday 45316.7%
Wednesday 50418.5%
Thursday 53519.7%
Friday 49418.2%
Saturday 1666.1%
Total 2717100.0%

Hour1Total% of Total
12:00 AM 652.4%
1:00 AM 682.5%
2:00 AM 622.3%
3:00 AM 742.7%
4:00 AM 572.1%
5:00 AM 1033.8%
6:00 AM 1084.0%
7:00 AM 1585.8%
8:00 AM 1716.3%
9:00 AM 1475.4%
10:00 AM 1716.3%
11:00 AM 1816.7%
12:00 PM 1886.9%
1:00 PM 1696.2%
2:00 PM 1605.9%
3:00 PM 1324.9%
4:00 PM 1073.9%
5:00 PM 923.4%
6:00 PM 913.3%
7:00 PM 963.5%
8:00 PM 833.1%
9:00 PM 782.9%
10:00 PM 792.9%
11:00 PM 772.8%
Total 2717100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 5.54144
Monday 5.22339
Tuesday 4.28419
Wednesday 7.67637
Thursday 6.90607
Friday 5.48411
Saturday 5.33160
Total 5.842717

Hour1 Entry MadeAvg.Total
12:00 AM 5.0035
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 7.0035
8:00 AM 5.35107
9:00 AM 6.32278
10:00 AM 6.47246
11:00 AM 4.41181
12:00 PM 6.88330
1:00 PM 3.00111
2:00 PM 5.41222
3:00 PM 8.64285
4:00 PM 4.0589
5:00 PM 5.92154
6:00 PM 4.52113
7:00 PM 9.67174
8:00 PM 9.80147
9:00 PM 5.05111
10:00 PM 5.4265
11:00 PM 4.5732
Total 5.842717

Learn More About Comment Stats
1 - All times GMT -8...


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles