I'm trying to find a way where the database name and the server name can be dynamic.

I'm developing an application which uses C# and crystal reports. Both application and the reports use the same database which is setup on a separate database server. This application now needs to be deployed elsewhere, where the database name and the server name may not be the same as what is used while developing.
I can use easily edit the config file for the application accordingly to change the name of server and database to look for, but i cant find a way to edit the these details for the crystal reports.

The reports were built using the crystal reports within Visual Studio 2005. 'Database expert' is used for connecting to the database and designing the query.

Is there any way to have these parameters set dynamically through a config file or code for crystal reports?

Im using C#. I've tried using ConnectionInfo for the report and for the tables etc in the code but it doesn't work.. Please help!!

Thanks.

Recommended Answers

All 14 Replies

Use ReportDocument property of CrystalReportSource class/control.

I've tried using ConnectionInfo for the report and for the tables etc in the code but it doesn't work.. Please help!!

You are on the right track. Post the code you are using for your ConnectionInfo so we can see what's missing.

Try this logic to setup each of your tables connection information. You will need to include using CrystalDecisions.CrystalReports.Engine

public void ViewReport(FileInfo crFileInfo) // path\filename.rpt
        {
            ConnectionInfo crConnectionInfo = new ConnectionInfo();
            crConnectionInfo.ServerName = "YOUR SERVER NAME";
            crConnectionInfo.DatabaseName = "YOUR DATABASE NAME";
            crConnectionInfo.UserID = "YOUR DATABASE USERNAME";
            crConnectionInfo.Password = "YOUR DATABASE PASSWORD";

            // CrystalReportViewer control
            crViewer.ReportSource = ReportSourceSetup(crFileInfo, crConnectionInfo);
            crViewer.Refresh();
        }

        ReportDocument ReportSourceSetup(FileInfo crFileInfo, ConnectionInfo crConnectionInfo)
        {
            ReportDocument crDoc = new ReportDocument();
            TableLogOnInfos crTableLogonInfos = new TableLogOnInfos();
            TableLogOnInfo crTableLogonInfo = new TableLogOnInfo();
            Tables crTables;

            crDoc.Load(crFileInfo.FullName);

            // Each table in report needs to have logoninfo setup:
            crTables = crDoc.Database.Tables;
            foreach (CrystalDecisions.CrystalReports.Engine.Table crTable in crTables)
            {
                crTableLogonInfo = crTable.LogOnInfo;
                crTableLogonInfo.ConnectionInfo = crConnectionInfo;
                crTable.ApplyLogOnInfo(crTableLogonInfo);
            }

            return crDoc;
        }

Thanks for the code!! This works. I have been trying the exact same thing. The only difference was that instead of ReportDocument, i was using an object of the report itself.

For example if the report is 'DemoReport.rpt' with the associated DemoReport.cs, i was doing something like this:

DemoReport rpt = new DemoReport();

ConnectionInfo crConnectionInfo = new ConnectionInfo();
crConnectionInfo.ServerName = "Server_Name";
crConnectionInfo.DatabaseName = "Database_Name";
crConnectionInfo.IntegratedSecurity = true;

TableLogOnInfos crTableLogonInfos = new TableLogOnInfos();
TableLogOnInfo crTableLogonInfo = new TableLogOnInfo();
Tables CrTables;
CrTables = rpt.Database.Tables;

foreach (CrystalDecisions.CrystalReports.Engine.Table crTable in crTables)
{
                crTableLogonInfo = crTable.LogOnInfo;
                crTableLogonInfo.ConnectionInfo = crConnectionInfo;
                crTable.ApplyLogOnInfo(crTableLogonInfo);
}
crystalReportViewer1.ReportSource = rpt;
crystalReportViewer1.Refresh();

I think getting the tables from the Database using an object of the report was causing the problem.
With the solution you provided, there is one problem. I have to copy each and every report manually at the machine the application will be deployed. The installation files does not include the reports in rpt format. Its embedded within the application.
Can this be done using the report object and not the path so that i dont have to copy the rpt files manually in each machine the application is installed?

Thanks!

Thanks for the code!! This works. I have been trying the exact same thing. The only difference was that instead of ReportDocument, i was using an object of the report itself.

...

Can this be done using the report object and not the path so that i dont have to copy the rpt files manually in each machine the application is installed?

Hi, I think you only need to upcast your report object to a ReportDocument. So in the example I gave, you could just substitute the FileInfo with a ReportDocument by using a cast instead of calling ReportDocument.Load method:

crDoc = (ReportDocument) MyReportObject;

Here is a link to MSDN topic on: Binding to an Embedded Report

Did this work?

DemoReport rpt = new DemoReport(); // your embedded document
            ReportDocument crDoc = (ReportDocument)rpt; // upcast
            ReportSourceSetup(crDoc, crConnectionInfo); // table logon info setup

        public void ReportSourceSetup(ReportDocument crDoc, ConnectionInfo crConnectionInfo)
        {
            // Each table in report needs to have logoninfo setup:
            Tables crTables = crDoc.Database.Tables;
            foreach (CrystalDecisions.CrystalReports.Engine.Table crTable in crTables)
            {
                TableLogOnInfo crTableLogonInfo = crTable.LogOnInfo;
                crTableLogonInfo.ConnectionInfo = crConnectionInfo;
                crTable.ApplyLogOnInfo(crTableLogonInfo);
            }
        }

Thanks for that. But im afraid that doesnt work. The typecasting from an object to ReportDocument doesnt work properly and the application crashes.

Is there anything else that anyone can suggest? Otherwise i guess i will have to manually copy all the rpt files along with the installation.

In the last example I gave, I used your DemoReport() object without knowing exactly how you defined it. Post or attach your DemoReport.cs file so I can see how you are defining your ReportDocument object.

The code for the .cs file for the report is basically auto generated. It was not modified at all.

namespace Portal {
    using System;
    using System.ComponentModel;
    using CrystalDecisions.Shared;
    using CrystalDecisions.ReportSource;
    using CrystalDecisions.CrystalReports.Engine;
    
    
    public class JobDetails2 : ReportClass {
        
        public JobDetails2() {
        }
        
        public override string ResourceName {
            get {
                return "JobDetails2.rpt";
            }
            set {
                // Do nothing
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public CrystalDecisions.CrystalReports.Engine.Section Section1 {
            get {
                return this.ReportDefinition.Sections[0];
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public CrystalDecisions.CrystalReports.Engine.Section Section2 {
            get {
                return this.ReportDefinition.Sections[1];
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public CrystalDecisions.CrystalReports.Engine.Section GroupHeaderSection1 {
            get {
                return this.ReportDefinition.Sections[2];
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public CrystalDecisions.CrystalReports.Engine.Section Section3 {
            get {
                return this.ReportDefinition.Sections[3];
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public CrystalDecisions.CrystalReports.Engine.Section GroupFooterSection1 {
            get {
                return this.ReportDefinition.Sections[4];
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public CrystalDecisions.CrystalReports.Engine.Section Section4 {
            get {
                return this.ReportDefinition.Sections[5];
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public CrystalDecisions.CrystalReports.Engine.Section Section5 {
            get {
                return this.ReportDefinition.Sections[6];
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public CrystalDecisions.Shared.IParameterField Parameter_Job_Number {
            get {
                return this.DataDefinition.ParameterFields[0];
            }
        }
    }
    
    [System.Drawing.ToolboxBitmapAttribute(typeof(CrystalDecisions.Shared.ExportOptions), "report.bmp")]
    public class CachedJobDetails2 : Component, ICachedReport {
        
        public CachedJobDetails2() {
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public virtual bool IsCacheable {
            get {
                return true;
            }
            set {
                // 
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public virtual bool ShareDBLogonInfo {
            get {
                return false;
            }
            set {
                // 
            }
        }
        
        [Browsable(false)]
        [DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Hidden)]
        public virtual System.TimeSpan CacheTimeOut {
            get {
                return CachedReportConstants.DEFAULT_TIMEOUT;
            }
            set {
                // 
            }
        }
        
        public virtual CrystalDecisions.CrystalReports.Engine.ReportDocument CreateReport() {
            JobDetails2 rpt = new JobDetails2();
            rpt.Site = this.Site;
            return rpt;
        }
        
        public virtual string GetCustomizedCacheKey(RequestContext request) {
            String key = null;
            // // The following is the code used to generate the default
            // // cache key for caching report jobs in the ASP.NET Cache.
            // // Feel free to modify this code to suit your needs.
            // // Returning key == null causes the default cache key to
            // // be generated.
            // 
            // key = RequestContext.BuildCompleteCacheKey(
            //     request,
            //     null,       // sReportFilename
            //     this.GetType(),
            //     this.ShareDBLogonInfo );
            return key;
        }
    }
}

In the last example I gave, I used your DemoReport() object without knowing exactly how you defined it. Post or attach your DemoReport.cs file so I can see how you are defining your ReportDocument object.

I also tested with the default CrystalReport generated file that derives from ReportClass (as embedded resource), which also derives from ReportDocument , and my cast allows it to setup each tables connection info, but I didn't change the values for the new ConnectionInfo object because I didn't need to. I'm not sure why yours would crash from doing this. Is it crashing during this setup, or not until executing a Refresh() ?

The application is crashing when i am trying to retrieving the Database tables through the report on the following statement:

crTables = crDoc.Database.Tables;

Im getting the error message as follows:
CrystalDecisions.CrystalReports.Engine.LoadSaveReportException: Unable to find the report in the manifest resources. Please build the project, and try again.

I would suggest doing a search on that error to determine what could be the cause. I don't think that code should pose a problem if everything else is in sync.

Regards.

please, give me solution for i have develop c# windows application with oracle forms are running well but crystal reports with OLEDB(ADO) connection does not display on client machine please give me solution its very urgentClick Here

You can dynamically pass logon parameters to crystal reports.

crConnectionInfo.ServerName = "YOUR SERVER NAME";
crConnectionInfo.DatabaseName = "YOUR DATABASE NAME";
crConnectionInfo.UserID = "YOUR DATABASE USERNAME";
crConnectionInfo.Password = "YOUR DATABASE PASSWORD";

CrTables = cryRpt.Database.Tables ;
foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in CrTables)
{
    crtableLogoninfo = CrTable.LogOnInfo;
    crtableLogoninfo.ConnectionInfo = crConnectionInfo;
    CrTable.ApplyLogOnInfo(crtableLogoninfo);
}

compete code.... Crystal Reports Dynamic Login

Johnson

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.