我正在使用CrystalReportViewer
和CrystalReportSource
在我的应用程序中加载和显示.rpt文件。
我的情况是:
假设某人在我的应用程序之外创建了Crystal Reports报表,并将其数据源设置为数据库。然后我在我的应用程序中使用.rpt文件,但我需要将它绑定到不同的数据库(在表结构和列名方面与原始数据库相同,但使用不同的连接字符串和用户名和密码)。
我如何在VB.NET代码中执行此操作?
目前我使用以下方式加载报告:
Public Function SetReportSource(ByVal RptFile As String) As ReportDocument
Try
Dim crtableLogoninfo As New TableLogOnInfo()
Dim crConnectionInfo As New ConnectionInfo()
Dim CrTables As Tables
Dim CrTable As Table
If System.IO.File.Exists(RptFile) Then
Dim crReportDocument As New ReportDocument()
crReportDocument.Load(RptFile)
With crConnectionInfo
.ServerName = "DRIVER={MySQL ODBC 5.1 Driver};SERVER=localhost;Port=3306;UID=root;"
.DatabaseName = gDatabaseName
.UserID = gServerUser
.Password = gServerPassword
End With
CrTables = crReportDocument.Database.Tables
For Each CrTable In CrTables
CrTable.ApplyLogOnInfo(crtableLogoninfo)
CrTable.LogOnInfo.ConnectionInfo.ServerName = crConnectionInfo.ServerName
CrTable.LogOnInfo.ConnectionInfo.DatabaseName = crConnectionInfo.DatabaseName
CrTable.LogOnInfo.ConnectionInfo.UserID = crConnectionInfo.UserID
CrTable.LogOnInfo.ConnectionInfo.Password = crConnectionInfo.Password
'Apply the schema name to the table's location
CrTable.Location = gDatabaseName & "." & CrTable.Location
Next
crReportDocument.VerifyDatabase()
SetReportSource = crReportDocument
Else
MsgBox("Report file not found...", MsgBoxStyle.Critical, proTitleMsg)
End If
Catch ex As Exception
System.Windows.Forms.MessageBox.Show("Error Found..." & vbCrLf & "Error No : " & Err.Number & vbCrLf & "Description :" & Err.Description & vbCrLf & vbCrLf & "Line no : " & Err.Erl & vbCrLf & "Procedure name : SetReportSource" & vbCrLf & "Module name : GeneralFunctions", proTitleMsg)
End Try
End Function
答案 0 :(得分:1)
这就是我做的。我在ASP.NET上使用Oracle和ODBC,但你应该能够对MySQL和ODBC做同样的事情:
作为我一直在做的遗留应用程序升级的一部分,我决定将Crystal Reports移动到Web应用程序而不是让用户通过Citrix直接在Crystal Reports XI上访问它们,这一直是他们的方法。使用。这有几个优点,主要是速度。困扰我的一个问题是如何在运行时更改登录信息,以便应用程序根据访问报告的服务器自动指向正确的Oracle数据库(开发,测试或生产)。
我找到的解决方案是将Oracle数据库连接设置为ODBC中的DSN,并连接到ODBC DSN而不是直接使用Oracle客户端。这不是唯一的方法,但它似乎是我的目的的最佳方式。
在包含Crystal Reports Viewer的页面的代码隐藏文件中,我放置了以下代码来处理呈现查看器的同一事件。
Protected Sub btnGenerate_Click(sender As Object, e As System.EventArgs) Handles btnGenerate.Click
Dim connInfo As New ConnectionInfo
Dim rptDoc As New ReportDocument
' setup the connection
With connInfo
.ServerName = "oracledsn" ' ODBC DSN in quotes, not Oracle server or database name
.DatabaseName = "" ' leave empty string here
.UserID = "username" ' database user ID in quotes
.Password = "password" 'database password in quotes
End With
' load the Crystal Report
rptDoc.Load(Server.MapPath(Utilities.AppSettingsFunction.getValue("ReportFolder") & ddlReports.SelectedValue))
' add required parameters
If pnlstartdates.Visible Then
rptDoc.SetParameterValue("REPORT_DATE", txtSingleDate.Text)
End If
' apply logon information
For Each tbl As CrystalDecisions.CrystalReports.Engine.Table In rptDoc.Database.Tables
Dim repTblLogonInfo As TableLogOnInfo = tbl.LogOnInfo
repTblLogonInfo.ConnectionInfo = connInfo
tbl.ApplyLogOnInfo(repTblLogonInfo)
Next
' Set, bind, and display Crystal Reports Viewer data source
Session("rptDoc") = rptDoc
Me.CrystalReportViewer1.ReportSource = Session("rptDoc")
CrystalReportViewer1.DataBind()
UpdatePanel1.Update()
End Sub
上面的登录信息可以很容易地存储在web.config中,而不是像上面那样硬编码。
顺便提一下,我选择将Crystal Reports Viewer放在ASP.NET AJAX更新面板中,这就是查看器的ReportSource存储在Session变量中的原因。如果您选择这样做,则必须在Init事件(而不是Load事件)中对查看器进行数据绑定才能正确显示。
Protected Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
If Not Page.IsPostBack Then
txtSingleDate.Text = Now.Date()
ElseIf Session("rptDoc") IsNot Nothing Then
Me.CrystalReportViewer1.ReportSource = Session("rptDoc")
CrystalReportViewer1.DataBind()
UpdatePanel1.Update()
End If
End Sub