Skip to Content

How to change data povider programmatically using .net

We would like to programmatically change the data provider used by a report. Currently we are using ODBC and we no longer want to depend on the this middleware. Is possible to programmatically change the objects within the report's report document object to use a direct data connection or OLE DB connection? We would rather not change them through Crystal Report's designer if possible due to the number of reports that we would have to change.

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

5 Answers

  • Best Answer
    Jul 05, 2017 at 09:43 PM

    CR 2008 runtime is not supported in VS 2010 or above.

    To get the runtime for CR 2011 and above go here:

    https://wiki.scn.sap.com/wiki/display/BOBJ/Crystal+Reports%2C+Developer+for+Visual+Studio+Downloads

    Update all references to version 13.

    On the WIKI page there is a demo app for setting log on info and using RAS and ReplaceConnection();

    Don

    Add comment
    10|10000 characters needed characters exceeded

    • Hi Don, OK.

      Couple of questions.

      1) How do I close all of these other threads that I have opened so that there is just one thread of conversation (this one) ?

      2) What is in the "Installation Package for Visual Studio IDE" ?

      3) Will I be able to programmatically change my database provider type with this installation?

      4) Does it require licensing for installation? If so our legal department will need to review the contract prior to the download.

      Thank you

  • Jun 29, 2017 at 01:16 PM

    Here's some C# sample code to get you started. You'll probably have to tweak this, though.

        private void updateLogon(ReportDocument newRpt, string alias)
        {
          for (int i = 1; i <= newRpt.Database.Tables.Count; i++)
          {
            ConnectionInfo cInfo = newRpt.Database.Tables[i].LogOnInfo.ConnectionInfo;
            cInfo.AllowCustomConnection = true;
            cInfo.ServerName = alias;
            cInfo.UserID = _rptUser;
            cInfo.Password = _rptPW;
            newRpt.Database.Tables[i].Location = _rptPrefix + "." + newRpt.Database.Tables[i].Name;
          }
          ///TODO: finish setting this up
            //if necessary, set the database driver
            if (_updateDriver && (_dbDriver != DBDrivers.SQL_Server))
            {
              switch (_dbDriver)
              {
                case DBDrivers.Oracle:
                  newRpt.ReportLogons[j].CustomServerType = CeReportServerType.ceServerTypeOracle;
                  break;
                case DBDrivers.DB2:
                  newRpt.ReportLogons[j].CustomServerType = CeReportServerType.ceServerTypeDB2;
                  break;
                case DBDrivers.ADO:
                  newRpt.ReportLogons[j].CustomServerType = CeReportServerType.ceServerTypeUserSpecified;
                  newRpt.ReportLogons[j].CustomDatabaseDLLName = "crdb_ado.dll";
                  break;
                case DBDrivers.BTrieve:
                  newRpt.ReportLogons[j].CustomServerType = CeReportServerType.ceServerTypeUserSpecified;
                  newRpt.ReportLogons[j].CustomDatabaseDLLName = "crdb_p2bbtrv.dll";
                  break;
                case DBDrivers.ODBC:
                  newRpt.ReportLogons[j].CustomServerType = CeReportServerType.ceServerTypeUserSpecified;
                  newRpt.ReportLogons[j].CustomDatabaseDLLName = "crdb_odbc.dll";
                  break;
                case DBDrivers.OLAP:
                  newRpt.ReportLogons[j].CustomServerType = CeReportServerType.ceServerTypeUserSpecified;
                  newRpt.ReportLogons[j].CustomDatabaseDLLName = "crdb_olap.dll";
                  break;
                case DBDrivers.XML:
                  newRpt.ReportLogons[j].CustomServerType = CeReportServerType.ceServerTypeUserSpecified;
                  newRpt.ReportLogons[j].CustomDatabaseDLLName = "crdb_xml.dll";
                  break;
              }
            }
          }
        }
    
    
    

    -Dell

    Add comment
    10|10000 characters needed characters exceeded

  • Jun 29, 2017 at 05:41 PM

    See question about code below

    Add comment
    10|10000 characters needed characters exceeded

    • Hi Dell thanks for replying.

      We use crystal reports designer 2013 to develop the reports. I am using Visual studio 2013 and the .net SDK. The replace connection method has an overload when I bring it up in my test application. The Replace connection overload is available from the sample code below. I wonder how to get the old connection from the report and Why types of new connection objects the ReplaceConnection method will take.

      ReportDocument rpt = newReportDocument();

      rpt.Load("file path to crystal 13 report");

      CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument rptClientDoc;

      rptClientDoc = rpt.ReportClientDocument;

      object oldconn = "to be defined from report";

      object newconn = "new connection to be defined for the report";

      object parameterfields = "parameter fields";

      rptClientDoc.DatabaseController.ReplaceConnection(oldconn, newconn, parameterfields);

      Thanks Ben
  • Jul 19, 2017 at 03:28 PM

    On the download page there is a link for a parameter test app:

    https://blogs.sap.com/2016/02/17/how-to-parameters-in-crystal-reports-for-visual-studio-net/

    It has a ReplaceConnection button, use it to set the info and the DB connection info is retrieved via the Load() routine:

    // get the DB name from the report
    CrystalDecisions.CrystalReports.Engine.Database crDatabase;
    CrystalDecisions.CrystalReports.Engine.Tables crTables;
    crDatabase = rpt.Database;
    crTables = crDatabase.Tables;
    int dbx = 0;
    btnSQLStatement.Text += "\nMain Report Table count: " + rpt.Database.Tables.Count.ToString();

    foreach (CrystalDecisions.CrystalReports.Engine.Table crTable in crTables)
    {
    if (crDatabase.Tables.Count != 0)
    {
    CrystalDecisions.Shared.NameValuePair2 nvp2 = (NameValuePair2)rpt.Database.Tables[dbx].LogOnInfo.ConnectionInfo.Attributes.Collection[1];
    btnSQLStatement.Text += "\nRPT Data Source Info: \n" + " Server Name: " + rpt.Database.Tables[dbx].LogOnInfo.ConnectionInfo.ServerName.ToString() + "\n Database Name: " + nvp2.Value.ToString() + "\n Table Name: " + rpt.Database.Tables[dbx].Name.ToString();
    if (rpt.Database.Tables[dbx].LogOnInfo.ConnectionInfo.UserID != null)
    btnSQLStatement.Text += "\n User ID: " + rpt.Database.Tables[dbx].LogOnInfo.ConnectionInfo.UserID.ToString() + "\r\n";
    dbx++;
    }
    else
    btnSQLStatement.Text += "No Data source or not found\r\n";
    }

    Now search for subreports and get it's connection properties.

    It's in the private void ReplaceConnection_Click... routine.

    Don

    Add comment
    10|10000 characters needed characters exceeded

    • Hi Don, could you explain the statement

      [dbx].LogOnInfo.ConnectionInfo.ServerName.ToString() + "\n Database Name: " + nvp2.Value.ToString() + "\n Table Name: " + rpt.Database.Tables[dbx].Name.ToString();

      to me. I have never seen an integer referenced in code like this in over the 13 years I have been coding in C#

      Thanks

  • Jul 21, 2017 at 03:09 PM

    Not sure what you are referring to, please explain? They are all labels or indexes as I see them...

    Add comment
    10|10000 characters needed characters exceeded