In this article, a minor revision of one originally written in December 2005, I talk about the utter frustration of trying to develop with Crystal Reports. For a product that has such a high market share - and which has maintained market leadership for such a long time - Crystal Reports sure gets a whole bunch of things wrong. It’s not all bad, however. Each of my complaints can be easily addressed - and I’m giving the ideas away.

For Free. Yes, you read that right. I would be more than pleased to see the issues I describe here addressed and solved in the next version of Crystal Reports. I’m not going to hold my breath, though.

Updated July 2011: I’ve disabled commenting on this piece as it’s being targeted by reporting vendors trying to lift the profile of their own products - which misses the entire point of the article. It’s not about how badly people need to find an alternative to Crystal Reports, it’s about how badly Crystal Reports treats the developers trying to use it.


I seem to be developing (no pun intended) a reputation as something of a Jack of all trades - able to turn my hand to almost any tool in an effective way.

The latest such tool has been Crystal Reports. The experience has been far from joyful. In fact, it has been something of an ordeal.

My complaint is not that Crystal Reports is unable to get the job done, but that it makes the job needlessly tedious and complicated.

With a few simple, but highly significant, improvements the whole process of being a Crystal Reports Developer would become spectacularly more productive. This is especially the case for enterprise environments where there are hundreds or thousands of reports to manage.

Here is a semi-random list of the most significant drawbacks - together with some simple solutions - as I see them at least. This article is incomplete. There are a whole heap of other things about Crystal Reports I would love to see improved. I had to stop somewhere though.

The Problem of Presentation

Why do I have to define the presentation of every field independently?

Whether creating a new report or editing an existing one, every field and every label in a Crystal Report has to be individually formatted, by hand. If any form of conditional formatting is used, the details need to be entered anew for every use. For new fields, copy & paste represents a useful shortcut, but when the focus turns to tweaking the presentation of things that already exist, well, tedious is a polite term to describe the amount of fiddly work required.

Consistency is an important aspect of report design. Not only consistency within a report, but between reports. All the reports related to a single system should demonstrate a high level of consistency - each report should use the same fonts, at the same sizes, use the same formats for dates and currency values, and apply the same rules for rounding and aggregating values.

At the moment, Crystal Reports provides no support for helping a developer achieve this desired level of consistency. The entire process is manual - and error prone. I’ve seen reports that use the Tahoma, Verdana and Arial fonts on the same line item - the original developers were attempting to match the fonts to achieve a consistent look and feel, but because Crystal Reports makes it so hard to do so, they failed.

Solving the problem of presentation

Provide a mechanism for separating content from presentation.

The concept of separating content from presentation is hardly new. Some history:

  • Microsoft Word has had Styles since at least Word 97 (maybe earlier - a colleague indicated Word 95). Each style defines the formatting to apply to a different part of the document, based on the semantics of the text - this is a heading; that is a quote.

  • HTML started with the idea of semantic mark-up in 1991 - and it copied the idea from SGML. In both languages, the content is marked up with tags that describe meaning, not presentation. This should be emphasized; that is a hyperlink.

  • CSS is a newer standard that allows fine control of presentation, but in a way that is well separated from the content itself.

  • Earlier still, the Model-View-Controller design pattern emerged from the Smalltalk community in the 1980’s. Under MVC, the model captures the business domain, while the view takes care of the look and feel.

I want to be able to define styles (for both fields and labels) that get reused across multiple reports. Heck, I’d settle for styles reused within a single report.

For example, let me define a field style called “currency” with these characteristics:

  • 40 mm wide;
  • Tahoma 10pt;
  • 2 decimal places with a period separator;
  • Leading “$” immediately to the left of the first digit;
  • Digit groups of 3, with comma separators; and
  • Right justified.

Once defined, this style could be applied to a dozen fields within my report, and they all would be consistently displayed. Any changes to the style (say, making all the fields 45mm wide) would be automatically propagated, with any problems caused (say, by fields that now overlap) being highlighted for easy resolution.

Conclusion: It is time that semantic mark-up made its way into mainstream reporting tools. As the market leader, Crystal Reports could be leading the way.

The problem of errors

When something goes wrong, tell me about it.

Don’t ever leave me looking at a blank report simply because something went wrong. Worse, don’t give me a report with missing pages and no warning.

Even when previewing within Crystal Developer (when it is safe to presume the user isn’t a complete dimwit), Crystal Reports has a nasty habit of silently failing. Sometimes, all you see on screen is a blank window with nothing at all. No diagnostic message, no error dialog, no indication of failure, no picture of an empty page, no buttons, nothing. I’ve come to call this the Gray screen of Death.

When this happens, development becomes a battle of wits with the machine - requiring me, the developer, to intuit (or guess) the nature of the problem - instead of an exercise in providing business value.

On the rare occasions when Crystal Reports is kind enough to actually admit that something may have gone wrong, the information supplied is meagre at best. Most of the time, the only clue is a cryptic error number, requiring a trip to Google for explanation.

Solving the problem of errors

Failure should be obvious.

When something goes wrong and the report can’t be generated, tell me about it. I care about my reports and about the data in those reports. Don’t lie to me and let me rely on reports that contain inaccurate or incorrect information - tell the truth and generate reports I can rely upon to make sound business decisions.

Give me the information I (or my technical support) need to have when attempting to fix the underlying cause. Make sure to include some context for the error. If a sub-report was being generated, tell me its name so I know where to look. If a special query was being run for a crosstab, tell me which one. Make it easy for me to lodge a useful fault report with my help or service desk. For example, including an email button would make it easy for me to ask for help - and if the resulting email included an attachment of detailed diagnostic information, so much the better.

Most of all, let me see the pages of the report that were generated. The content may be useful from a business perspective. It will be useful from a diagnostics perspective. But: don’t let me make the mistake of thinking the results are valid or complete - use a watermark or something else to make it clear that the report is suspect.

Conclusion: Error reporting should be robust, informative and reliable. End users must be able to rely on their reports being correct.

The problem of database connections

Why are the details of the database connection replicated so many times? Why must those details always be kept inside the report?

Most (if not all) enterprise systems that employ Crystal Reports have many reports - dozens, if not hundreds. Having connection information replicated in every report becomes a logistical nightmare.

Consider (1): It is good practice to regularly change sensitive passwords, to prevent unauthorized access to restricted information. This is as true for databases as for other systems. But which DBA is going to do this if a dozen, or a hundred, or five hundred reports need updating as a result?

True, using integrated security, where the users machine or network credentials are passed through to the database server, can be a solution for this - but it’s only a partial solution as there are circumstances (and products) where this kind of approach is simply impractical.

Consider (2): One of the standard tenets of software development is that changes should be thoroughly tested before being deployed to production. This requires that the testing of the report should occur against a test system. The point of testing is not only to ensure the report works, but also that the load of running the report won’t have any deleterious effects on production. Importantly, the report that is deployed to production should be the same report that was tested - if the report has been modified (say, to change the database connection) then the results of testing become suspect.

Crystal Reports seems to take delight in firmly welding itself to the original data source, making this kind of multiple environment use perversely difficult.

Before someone jumps down my throat, I do know about the set location menu item. Two observations:

(a) It doesn’t work reliably - sometimes redirecting only some tables, giving reports with a mixture (say) of development & test information;

(b) Making the change involves editing the report, akin to editing the source code of a regular application and recompiling just before go-live.

Solving the problem of database connections

Allow connection information to be externalised.

I know that there are good reasons to have the connection information embedded … in some scenarios.

That said, make it optional. There should be an option to externalize connection information for sharing across multiple reports. With some form of externalised connection information in place, the database connections of an entire collection of reports (say, in the same directory) can be updated in one go.

The first impact of this is to lower the cost of adopting good security practices such as changing database passwords regularly.

A second, less obvious impact is that deployment of a report from a test environment into production becomes a simple file copy, rather than requiring the report to be changed, eliminating a route by which production errors can be introduced.

Conclusion: Redeployment of a report from one database to another (with an identical schema) can, and should, be trivial.

The problem of hidden information

Why do I have to hunt out the way the report is configured?

There is no one single way to see how a given Crystal Report works. Database connection information is one place; the predicates for the database selection are another; fields, formulas and parameters in a third, and so on and on and on.

Worse, even when you’re looking at just one thing - say, the formulas that have been defined - you don’t get to see all the definitions in one go. You have to open a separate dialog for each item to see its definition.

It’s like programming in C# but being forced to open a new window to see the type of each variable that has been defined. Worse, you’re forced to close those windows before you can change any of the code, and none of the variables has a sensible name.

In order to understand a report, a developer has to manually check out all the different dialogs, inspect each one, and remember what they’ve seen.

Solving the problem of hidden information

Support a Text based file format (like XML).

Contrast this with more conventional development environments where everything is stored in text files that can be read and understood. All the information about the program is in those files - there are no important details only accessible in obscure dialog XJ42.

The same should apply to Crystal Reports - having some kind of text based format would allow for all of the existing tools for change management to be applied.

Imagine …

  • Being able to compare two versions of a report and see what had been changed;
  • Being able to copy and paste field definitions between reports to guarantee consistency;
  • Being able to do a formal code inspection of the changes made to a report;
  • Being on site at a client and being able to fix a faulty report on the spot with a text editor;

OK, enough with the Imagineering. I hope you get the point. It’s not original, by the way - The Pragmatic Programmer persuasively argues the merits of storing all data in text based formats for exactly these reasons.


Crystal Reports is a very effective product that dominates both the mind-share and market-share of the enterprise reporting space.

In this article, I’ve identified four areas where the Crystal Reports makes life difficult for the very developers who are responsible for creating the reports themselves:

  • Presentation
  • Errors
  • Database Connections
  • Hidden Information

For each of these areas, I’ve described one possible approach to making improvements - new features that would provide quantum leap in the productivity and output quality of Crystal Reports Developers.

I believe that putting some effort into making the lives of its developers easier would directly result in increased use of Crystal Reports - and that would lead directly to greater sales - greater revenue.


blog comments powered by Disqus
Next Post
Huffman User Interfaces  30 Mar 2008
Prior Post
Lambda Events  22 Mar 2008
Related Posts
Browsers and WSL  31 Mar 2024
Factory methods and functions  05 Mar 2023
Using Constructors  27 Feb 2023
An Inconvenient API  18 Feb 2023
Method Archetypes  11 Sep 2022
A bash puzzle, solved  02 Jul 2022
A bash puzzle  25 Jun 2022
Improve your troubleshooting by aggregating errors  11 Jun 2022
Improve your troubleshooting by wrapping errors  28 May 2022
Keep your promises  14 May 2022
March 2008