当Crystal Reports仍支持ActiveX时,我们会生成使用ODBC数据源指向Access或SQL数据库的水晶报表。在运行时,我们将更改报告以使用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)有关
答案 0 :(得分: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
答案 1 :(得分:0)
您只需使用此方法登录所需的任何Crystal Report。
只需传递参数:
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)