Quantcast
Viewing all articles
Browse latest Browse all 9190

Re: Setting the sql statement

Hi Jan

 

I understand your problem completely but we have asked  R&D to be able to edit the SQL and they explained due to how the report Engine works it's simply not possible anymore. It would take a complete rewrite in all of our DB drivers and query dll's to be able to allow it. They did that in CR 9 when they rewrote the DB drivers and removed the SQL part of the code into separate dll's and that is when the ability was removed, it's been that way ever since.

 

One possibility is to get the SQL from the Report and then connect to your DB using a .NET and if the results from the SQL is less than 5K rows and not too many columns you could then set the Report data source to a Dataset.

As long as all of the field names are the same CR will run the report using this work flow.

 

For data larger than 5K rows, limit is due to memory resources, you could save the DS to an XML file and then set the reports data source to the XML file. We've seen 100meg XML's used so the amount of data should not be a problem, but of course there are limits to everything so test...

 

This should not affect performance much.

So the work flow would be:

 

Load the report

Get the SQL Statement

Paste it into a Dataset Query

 

Something like this should get you started:

 

//string connString = "Provider=SQLOLEDB;Data Source=MySQLServer;Database=xtreme;User ID=sa;Password=pw";

string connString = "Provider=SQLNCLI10;Server=MySQLServer;Database=xtreme;User ID=sa;Password=pw";


Detail"".""Quantity"" FROM   ""xtreme"".""dbo"".""Orders Detail"" ""Orders Detail""";

string sqlString = @"SELECT top 10*  FROM  ""xtreme"".""dbo"".""Financials"" ""Financials""";

System.Data.OleDb.OleDbConnection oleConn = new System.Data.OleDb.OleDbConnection(connString);
System.Data.OleDb.OleDbCommand cmd = oleConn.CreateCommand();
cmd.CommandText = sqlString;

System.Data.DataSet ds = new System.Data.DataSet();

OleDbDataAdapter oleAdapter = new OleDbDataAdapter(sqlString, oleConn);
//OleDbDataAdapter oleAdapter2 = new OleDbDataAdapter(sqlString2, oleConn);
DataTable dt1 = new DataTable("Financials");
//DataTable dt2 = new DataTable("Orders Detail");

oleAdapter.Fill(dt1);
//oleAdapter2.Fill(dt2);

ds.Tables.Add(dt1);
//ds.Tables.Add(dt2);
ds.WriteXml("c:\\reports\\sc2.xml", XmlWriteMode.WriteSchema);

// as long as the field names match exactly Cr has no problems setting report to a DS.
try
{
    rpt.SetDataSource(ds.Tables[0]); // incremtent [0] for more than 1 table.
    rpt.SetDataSource(ds);
}
catch (Exception ex)
{
    MessageBox.Show("ERROR: Schema Mismatch. Error reported by CR: " + ex.Message);
}

//Now check for subreport and set to same DS
foreach (CrystalDecisions.CrystalReports.Engine.Section section in rpt.ReportDefinition.Sections)
{
    foreach (CrystalDecisions.CrystalReports.Engine.ReportObject reportObject in section.ReportObjects)
    {
        if (reportObject.Kind == ReportObjectKind.SubreportObject)
        {
            CrystalDecisions.CrystalReports.Engine.SubreportObject subReport = (CrystalDecisions.CrystalReports.Engine.SubreportObject)reportObject;

            CrystalDecisions.CrystalReports.Engine.ReportDocument subDocument = subReport.OpenSubreport(subReport.SubreportName);

            subDocument.SetDataSource(ds);
        }
    }
}

 

And for XML it would use this part, not above I am saving the data and structure in the XML file so it should match what is in the report:

 

foreach (CrystalDecisions.CrystalReports.Engine.Table rptTable in rpt.Database.Tables)
{
    try
    {
        rptTable.Location = btrDataFile.ToString(); // @"D:\Atest\" + rptTable.Location + ".xml";
    }
    catch (Exception ex)
    {
        MessageBox.Show("ERROR: " + ex.Message);
    }

}

 

Only issue you may run into is sometimes XML does not have a direct field type and your original data source but you'll get an error if that happens which could be trapped and handled.

 

If you have a report that only uses 2 tables I do have code that will convert it to use a Command Object. That is the limit the engine is capable of, there is a lot of logic to be able to do this in CRD and the SDK so that is all we could get for now.

 

I hope that helps

 

Don


Viewing all articles
Browse latest Browse all 9190

Trending Articles