2397203 - Set Location to a MDB database file using relative path up one folder - ..\Access.mdb does not work

SAP Knowledge Base Article - Public

2397203 - Set Location to a MDB database file using relative path up one folder - ..\Access.mdb does not work

Symptom

The issue we are having is since updating to 13.0.17, we are unable to change the connection information on the report using the method SetConnection.

This is not an issue on every report. From my investigation, it appears to happen on reports with a large number of sub reports.

The report is designed using relative pathing to the MDB file. In CR DEsigner you will see the path showing like this:

..\Access.mdb

What this should do is redirect the Database engine to move up one folder from the EXE in .NET Application and find the database file in that folder.

When attempting to do so it pops up a message indicating the database cannot be found or if viewed it will continually prompt for log on info.

NOTE: if it is a secure Access MDB file it will continually prompt for User name and password.

Environment

Crystal Reports for Visual Studio SP 17 and SP 18

Resolution

R&D have confirmed there is an issue with Relative Pathing and should have this resolved in SP 19 due out in January 2017 which can be downloaded from the following link:

https://blogs.sap.com/2010/12/07/sap-crystal-reports-developer-version-for-microsoft-visual-studio-updates-runtime-downloads/

This issue has now been resolved: Incorrect parameter used when call function _bstr_t

NOTE: must set both Server and Database properties to "..\access.mdb"

NOTE 2: this was only fixed using the ClientDocument (Engine) and not when using RAS ( Report Application Server) and ReplaceConnection() We will create an Enhancement Request and once R&D has a look at it we will determine which SP it will be in if possible.

// Engine
CrystalDecisions.CrystalReports.Engine.ReportObjects crReportObjects;
CrystalDecisions.CrystalReports.Engine.SubreportObject crSubreportObject;
CrystalDecisions.CrystalReports.Engine.ReportDocument crSubreportDocument;
CrystalDecisions.CrystalReports.Engine.Database crDatabase;
CrystalDecisions.CrystalReports.Engine.Tables crTables;

CrystalDecisions.Shared.TableLogOnInfo tLogonInfo;

try
{
    foreach (CrystalDecisions.CrystalReports.Engine.Table rptTable in rpt.Database.Tables)
    {
        tLogonInfo = rptTable.LogOnInfo;
        tLogonInfo.ConnectionInfo.ServerName = @"..\access.mdb";
        tLogonInfo.ConnectionInfo.DatabaseName = @"..\access.mdb";
        tLogonInfo.ConnectionInfo.UserID = "admin";
        tLogonInfo.ConnectionInfo.Password = "YourPassword";
        tLogonInfo.TableName = rptTable.Name;

        dtStart = DateTime.Now;

        try
        {
            rptTable.ApplyLogOnInfo(tLogonInfo);
        }
        catch (Exception ex)
        {
            MessageBox.Show("ERROR: " + ex.Message);
        }
    }
}

    // check for subreports
    //set the crSections object to the current report's sections
    CrystalDecisions.CrystalReports.Engine.Sections crSections = rpt.ReportDefinition.Sections;

    //loop through all the sections to find all the report objects
    foreach (CrystalDecisions.CrystalReports.Engine.Section crSection in crSections)
    {
        crReportObjects = crSection.ReportObjects;
        //loop through all the report objects to find all the subreports
        foreach (CrystalDecisions.CrystalReports.Engine.ReportObject crReportObject in crReportObjects)
        {
            if (crReportObject.Kind == CrystalDecisions.Shared.ReportObjectKind.SubreportObject)
            {
                //you will need to typecast the reportobject to a subreport
                //object once you find it
                crSubreportObject = (CrystalDecisions.CrystalReports.Engine.SubreportObject)crReportObject;

                //open the subreport object
                crSubreportDocument = crSubreportObject.OpenSubreport(crSubreportObject.SubreportName);

                CrystalDecisions.CrystalReports.Engine.Database crSubDatabase;
                CrystalDecisions.CrystalReports.Engine.Tables crSubTables;

                //set the database and tables objects to work with the subreport
                crSubDatabase = crSubreportDocument.Database;
                crSubTables = crSubDatabase.Tables;

                //loop through all the tables in the subreport and
                //set up the connection info and apply it to the tables
                try
                {
                    foreach (CrystalDecisions.CrystalReports.Engine.Table subrptTable in crSubreportDocument.Database.Tables)
                    {
                        tLogonInfo = subrptTable.LogOnInfo;
                        tLogonInfo.ConnectionInfo.DatabaseName = @"..\access.mdb";
                        tLogonInfo.ConnectionInfo.ServerName = @"..\access.mdb";
                        tLogonInfo.TableName = subrptTable.Name;
                        tLogonInfo.ConnectionInfo.UserID = "admin"
                        tLogonInfo.ConnectionInfo.Password = "YourPassword";

                        try
                        {
                            subrptTable.ApplyLogOnInfo(tLogonInfo);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("ERROR: " + ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("SubReport ERROR: " + ex.Message);
                }
            }
        }
    }

 

Keywords

crystal reports, relative path, ..\access.mdb, cr for vs, crystal reports for visual studio, prompt for log on info , KBA , BI-RA-CR-SDK , SDK related, including Java/.NET etc. , BI-DEV-NET , BI Software Development Kits (SDKs) - .NET or Other , Problem

Product

SAP Crystal Reports, developer version for Microsoft Visual Studio