【问题标题】:How to change Crystal reports connection properties in code?如何在代码中更改 Crystal 报表连接属性?
【发布时间】:2010-02-01 23:21:33
【问题描述】:

当 Crystal Reports 仍然支持 ActiveX 时,我们已经构建了使用 ODBC 数据源指向 Access 或 SQL 数据库的 Crystal 报表。在运行时,我们会将报表更改为使用 OLE DB (ADO) 而不是 ODBC,将服务器名称、数据库名称、用户名、密码更改为特定于用户的名称,然后运行报表,它工作正常。

现在 Crystal Reports 2008 不再支持 ActiveX,我们正尝试在 .NET 中做同样的事情,但没有成功。

到目前为止的代码如下:

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

代码一直有效,直到它到达 boReportDocument.VerifyDatabase(),这就是我收到“登录失败”错误的时候。

我也尝试使用这里的代码:

Dynamically change the connection of a Crystal Report

那个也没用,不知道是不是和从ODBC切换到OLE DB(ADO)有关

【问题讨论】:

    标签: .net vb.net crystal-reports connection


    【解决方案1】:

    我意识到这个问题已经 3 年了,并且 OP 可能已经继续前进,但这也许可以帮助其他人寻找答案。

    这是从 VB.NET 加载报告的完整示例,更改了连接信息和其他内容(例如参数值),取自并简化了日常用于从多个数据源报告的工作应用程序:

    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
    

    【讨论】:

      【解决方案2】:

      您可以简单地使用此方法登录任何您想要的水晶报表。

      只需传递您的参数:

       Public Sub LogOn(ByVal poReport As CrystalDecisions.CrystalReports.Engine.ReportDocument, ByVal strServer As String, ByVal strTable As String, ByVal strUsername As String, ByVal strPassword As String)
          Dim loConnInfo As New CrystalDecisions.Shared.ConnectionInfo
          loConnInfo.ServerName = strServer
          loConnInfo.DatabaseName = strTable
          loConnInfo.UserID = strUsername
          loConnInfo.Password = strPassword
          loConnInfo.IntegratedSecurity = False
          Dim loTables As CrystalDecisions.CrystalReports.Engine.Tables
          Dim loTable As CrystalDecisions.CrystalReports.Engine.Table
          Dim loTableLogonInfo As CrystalDecisions.Shared.TableLogOnInfo
          loTables = poReport.Database.Tables
      
          For Each loTable In loTables
              loTableLogonInfo = loTable.LogOnInfo
              loTableLogonInfo.ConnectionInfo.UserID = strUsername
              loTableLogonInfo.ConnectionInfo.Password = strPassword
              loTableLogonInfo.ConnectionInfo.ServerName = strServer
              loTableLogonInfo.ConnectionInfo.DatabaseName = strTable
              loTableLogonInfo.ConnectionInfo.IntegratedSecurity = False
              loTable.ApplyLogOnInfo(loTableLogonInfo)
          Next
      End Sub
      

      然后这样称呼它:

      LogOn(yourReportDocument, serverPath, databaseName, userName, password)
      

      【讨论】:

      • 知道如何设置端口吗?
      • ServerName 属性应该接受“192.168.1.1,1234”,其中 1234 是端口号。注意 IP/服务器名称后面的冒号。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多