How to change Crystal reports connection properties in code?

18,196

I realize this question is 3 years old and the OP probably already moved on, but maybe this can help someone else looking for answers.

This is a full example of loading a Report from VB.NET changing the connection info and other stuff like Parameter values, taken and simplified from a working application used daily for reporting from multiple datasources:

Private Sub ReportGo()
        'Main Report 
        Dim crxRpt As New CrystalDecisions.CrystalReports.Engine.ReportDocument
        'Subreport objects, if you need them
        Dim crxSubrpt1 As New CrystalDecisions.CrystalReports.Engine.ReportDocument, crxSubrpt2 As New CrystalDecisions.CrystalReports.Engine.ReportDocument
        'Parameter fields objects and values, if you need them
        Dim crxPar1 As New CrystalDecisions.Shared.ParameterField
        Dim crxVal1 As New CrystalDecisions.Shared.ParameterDiscreteValue

        'Load report file
        crxRpt.Load("myreport.rpt")

        'Load subreports, if you have them. Otherwise comment these lines
        crxSubrpt1 = crxRpt.OpenSubreport("MySubr1")
        crxSubrpt2 = crxRpt.OpenSubreport("MySubr2")

        'Login Main Report
        Dim myTables As CrystalDecisions.CrystalReports.Engine.Tables = crxRpt.Database.Tables
        crxRpt.SetDatabaseLogon("Username", "Password", "Servername", "Database") 
        Dim crConnInfo1 As CrystalDecisions.Shared.ConnectionInfo = New CrystalDecisions.Shared.ConnectionInfo
        crConnInfo1.DatabaseName = "Database"
        crConnInfo1.UserID = "Username"
        crConnInfo1.Password = "Password"
        crConnInfo1.ServerName = "Servername"

        'If your report uses more than one datasource, then uncomment and add the other login info here: 
        'crxRpt.SetDatabaseLogon("Username2", "Password2", "Servername2","Database2")
        'Dim crConnInfo2 As CrystalDecisions.Shared.ConnectionInfo = New CrystalDecisions.Shared.ConnectionInfo
        'crConnInfo2.DatabaseName = "Database2"            
        'crConnInfo2.UserID = "Username2"
        'crConnInfo2.Password = "Password2"
        'crConnInfo2.ServerName = "Servername2"

        For Each myTable As CrystalDecisions.CrystalReports.Engine.Table In myTables
            Dim myTableLogonInfo As CrystalDecisions.Shared.TableLogOnInfo = myTable.LogOnInfo
            If myTable.LogOnInfo.ConnectionInfo.DatabaseName = "Database" Then
                myTableLogonInfo.ConnectionInfo = crConnInfo1
                myTable.ApplyLogOnInfo(myTableLogonInfo)
            Else
                'This here only applies if you have more than one datasource
                'myTableLogonInfo.ConnectionInfo = crConnInfo2
                'myTable.ApplyLogOnInfo(myTableLogonInfo)
            End If
        Next

        'Subreport Login. Comment this section if you don't use them
        crxSubrpt1.SetDatabaseLogon("Username", "Password","Servername", "Database")
        'again, only if you use 2 datasources
        'crxSubrpt1.SetDatabaseLogon("Username2", "Password2", "Servername2", "Database2")
        crxSubrpt1.RecordSelectionFormula = "Subreport 1 Selection formula goes here"
        crxSubrpt2.SetDatabaseLogon("Username", "Password","Servername", "Database")
        'again, only if you use 2 datasources
        'crxSubrpt2.SetDatabaseLogon("Username2", "Password2", "Servername2", "Database2")
        crxSubrpt2.RecordSelectionFormula = "Subreport 2 selection formula goes here"

        Dim mySections As CrystalDecisions.CrystalReports.Engine.Sections = crxRpt.ReportDefinition.Sections
        For Each mySection As CrystalDecisions.CrystalReports.Engine.Section In mySections
            Dim myReportObjects As CrystalDecisions.CrystalReports.Engine.ReportObjects = mySection.ReportObjects
            For Each myReportObject As CrystalDecisions.CrystalReports.Engine.ReportObject In myReportObjects
                If myReportObject.Kind = CrystalDecisions.Shared.ReportObjectKind.SubreportObject Then
                    Dim mySubreportObject As CrystalDecisions.CrystalReports.Engine.SubreportObject = CType(myReportObject, CrystalDecisions.CrystalReports.Engine.SubreportObject)
                    Dim subReportDocument As CrystalDecisions.CrystalReports.Engine.ReportDocument = mySubreportObject.OpenSubreport(mySubreportObject.SubreportName)
                    Dim mytablessub As CrystalDecisions.CrystalReports.Engine.Tables = subReportDocument.Database.Tables
                        For Each myTable As CrystalDecisions.CrystalReports.Engine.Table In mytablessub
                            Dim myTableLogonInfo As CrystalDecisions.Shared.TableLogOnInfo = myTable.LogOnInfo
                            If myTable.LogOnInfo.ConnectionInfo.DatabaseName = "Database" Then
                                myTableLogonInfo.ConnectionInfo = crConnInfo1
                                myTable.ApplyLogOnInfo(myTableLogonInfo)
                            Else
                                'Only if you use 2 datasources
                                'myTableLogonInfo.ConnectionInfo = crConnInfo2
                                'myTable.ApplyLogOnInfo(myTableLogonInfo)
                            End If
                        Next
                    End If
                Next
            Next
        End If

        'If the report uses Parameter fields, uncomment this and fill as appropiate
        'crxVal1.Value = "Parameter 1 Value" 
        'crxPar1.Name = "Parameter 1 name" 
        'crxPar1.CurrentValues.Add(crxVal1)
        'crxPar1.HasCurrentValue = True

        'Apply main report selection formula
        crxRpt.RecordSelectionFormula = "Main report selection formula goes here"
        crxRpt.Refresh()


        'Now, if you preview the report in your VB app with a CrystalReportViewer, uncomment this:
        'YourForm.CristalReportViewer.ReportSource = crxRpt 

        'If you use Parameter fields...
        'YourForm.CrystalReportViewer.ParameterFieldInfo.Clear()
        'YourForm.CrystalReportViewer.ParameterFieldInfo.Add(crxPar1)

        'Finally, if you need to export the report automatically
         CrxRpt.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, "Yourfile.pdf")

End Sub
Share:
18,196

Related videos on Youtube

Robo
Author by

Robo

Updated on April 15, 2022

Comments

  • Robo
    Robo about 2 years

    Back when Crystal Reports still supports ActiveX, we have crystal reports that were built to use ODBC data source point to an Access or SQL database. In run time, we would change the report to use OLE DB (ADO) instead of ODBC, change the server name, database name, username, password to ones specific to the user, and run the report, it worked fine.

    Now that Crystal Reports 2008 no longer supports ActiveX, we're trying to do the same thing in .NET, but without success.

    Here's the code so far:

    Public Function ChangeConnectionInfo() As ReportDocument
            Dim boReportDocument As New ReportDocument
            '**EDIT** Change the path and report name to the report you want to change.
            boReportDocument.Load("c:\CustomerListSQL.Rpt", OpenReportMethod.OpenReportByTempCopy)
    
            'Create a new Command Table to replace the reports current table.
            Dim boTable As New CrystalDecisions.ReportAppServer.DataDefModel.CommandTable
    
            'boMainPropertyBag: These hold the attributes of the tables ConnectionInfo object
            Dim boMainPropertyBag As New PropertyBag
            'boInnerPropertyBag: These hold the attributes for the QE_LogonProperties
            'In the main property bag (boMainPropertyBag)
            Dim boInnerPropertyBag As New PropertyBag
    
            'Set the attributes for the boInnerPropertyBag
            boInnerPropertyBag.Add("Auto Translate", "-1")
            boInnerPropertyBag.Add("Connect Timeout", "15")
            boInnerPropertyBag.Add("Data Source", "K2")
            boInnerPropertyBag.Add("General Timeout", "0")
            boInnerPropertyBag.Add("Initial Catalog", "DBNAME")
            boInnerPropertyBag.Add("Integrated Security", "True")
            boInnerPropertyBag.Add("Locale Identifier", "5129")
            boInnerPropertyBag.Add("OLE DB Services", "-5")
            boInnerPropertyBag.Add("Provider", "SQLOLEDB")
            boInnerPropertyBag.Add("Tag with column collation when possible", "0")
            boInnerPropertyBag.Add("Use DSN Default Properties", "False")
            boInnerPropertyBag.Add("Use Encryption for Data", "0")
    
            'Set the attributes for the boMainPropertyBag
            boMainPropertyBag.Add("Database DLL", "crdb_ado.dll")
            boMainPropertyBag.Add("QE_DatabaseName", "DBNAME")
            boMainPropertyBag.Add("QE_DatabaseType", "OLE DB (ADO)")
            'Add the QE_LogonProperties we set in the boInnerPropertyBag Object
            boMainPropertyBag.Add("QE_LogonProperties", boInnerPropertyBag)
            boMainPropertyBag.Add("QE_ServerDescription", "K2")
            boMainPropertyBag.Add("QE_SQLDB", "True")
            boMainPropertyBag.Add("SSO Enabled", "False")
    
            'Create a new ConnectionInfo object
            Dim boConnectionInfo As New CrystalDecisions.ReportAppServer.DataDefModel.ConnectionInfo
            'Pass the database properties to a connection info object
            boConnectionInfo.Attributes = boMainPropertyBag
            'Set the connection kind
            boConnectionInfo.Kind = CrConnectionInfoKindEnum.crConnectionInfoKindCRQE
            '**EDIT** Set the User Name and Password if required.
            'boConnectionInfo.UserName = "UserName"
            'boConnectionInfo.Password = "Password"
            'Pass the connection information to the table
            boTable.ConnectionInfo = boConnectionInfo
    
            'Get the Database Tables Collection for your report
            Dim boTables As CrystalDecisions.ReportAppServer.DataDefModel.Tables = _
               boReportDocument.ReportClientDocument.DatabaseController.Database.Tables    
    
            'For each table in the report:
            ' - Set the Table Name properties.
            ' - Set the Command table's command text.
            ' - Set the table location in the report to use the new modified table
            For Each boReportTable In boTables
                boTable.Name = boReportTable.Name
                boTable.QualifiedName = "DBNAME.dbo." + boReportTable.Name 'boReportTable.QualifiedName
                boTable.Alias = boReportTable.Alias    
                boReportDocument.ReportClientDocument.DatabaseController.SetTableLocation(boReportTable, boTable)
            Next
    
            'Verify the database after adding substituting the new table.
            'To ensure that the table updates properly when adding Command tables or Stored Procedures.
            boReportDocument.VerifyDatabase()
    
            Return boReportDocument
        End Function
    

    The code works until it gets to boReportDocument.VerifyDatabase(), that's when I get a 'Log On Failed' error.

    I tried using the code in here as well:

    Dynamically change the connection of a Crystal Report

    That didn't work either, I don't know whether it has to do with switching from ODBC to OLE DB (ADO)

  • Lzh
    Lzh almost 10 years
    Any idea how to set the port?
  • KalaNag
    KalaNag almost 9 years
    The ServerName property should accept "192.168.1.1,1234", where 1234 is the port number. Note the colon after the IP/server name.