Stupid Crystal Reports tricks

Been developing with Crystal Reports since 1995-ish first as a direct connection into SQL Server 4.5 & 6 (my goodness, ages ago!). Then as a VB6 developer, embedded reports into a Report Viewer using .dsr files. With embedded reports, its a whole different ball game since I'm only passing it recordsets rather than allowing Crystal to connect to the database (I do use database connections to pull in the data schema to design the reports.)

Those are the good ol' days, doing some hand-wrangling, hair-pulling sessions trying to get my stored procedures to work with Crystal Reports.

Now, I've been tasked to upgrade AACTS from VB into .NET using C#. While Crystal Reports has been under different ownerships, first its own, then Seagate, then now Business Objects -- wonder why tho' -- and now Microsoft the most ideal acquirer has gone out to make its own Reporting Services product several years back. Again, wonder why?

Regardless of what I said above, I'm a sucker for punishment and am now working on Crystal Reports XI R2.

Well, the news is... I fared no better, still doing that "hand-wrangling, hair-pulling" sessions. Some workarounds in place to make that happen after searching over and over to make things work.

One example, if you have a parameters in the report and is populating the report using System.Data.DataSet. Yes, DataSets are bloated, but on the other hand, returning, say, 5 tables/resultsets from a stored procedure can be arguably more efficient since its only one roundtrip to the database?

I built a wrapper class to get parameters into the report:


public class ParametersHelper
{
// Wrapper to help populate the parameters if user wants to export the
// hash - Stores all the parameters in key/value pairs
public ParameterFields FillParameterFields(Hashtable hash)
{
ParameterFields pfields = new ParameterFields();
foreach (DictionaryEntry entry in hash)
{
ParameterField pfield = new ParameterField();
ParameterDiscreteValue disValue = new ParameterDiscreteValue();

disValue.Value = entry.Value;
pfield.Name = entry.Key.ToString(); // Parameter Name
pfield.CurrentValues.Add(disValue);
pfields.Add(pfield);
}
return pfields;
}
}

To use it:


Report1 r1 = new Report1();
r1.Load();
r1.SetDataSource(ds.Tables[0]);
if (hash.Count > 0)
{
crystalReportViewer1.ParameterFieldInfo = ph.FillParameterFields(hash);
for (int i = 0; i < r1.ParameterFields.Count; i++)
{
r1.DataDefinition.ParameterFields[i].ApplyCurrentValues(crystalReportViewer1.ParameterFieldInfo[i].CurrentValues);
}
}
this.crystalReportViewer1.ReportSource = r1;
this.crystalReportViewer1.Show();

[sorry if it is cutting off, just copy-paste it into Notepad then you'll see the code in all its glory.]