2011-06-02 74 views
1

我正在使用CrystalReportViewerCrystalReportSource在我的应用程序中加载和显示.rpt文件。将MySQL连接字符串动态更改为Crystal Reports

我的情况是这样的:

说一个人创建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 

回答

1

这是我做到了。我在ASP.NET上使用了带有ODBC的Oracle,但您应该可以对MySQL和ODBC执行相同的操作:

作为传统应用程序升级的一部分,我一直在做,我决定将Crystal Reports移动到一个Web应用程序,而不是让用户通过Citrix直接在Crystal Reports XI上访问它们,这是他们一直使用的方法。这有几个优点,首要的就是速度。困扰我的一个问题是如何在运行时更改登录信息,以便应用程序根据从哪个服务器访问报表,自动指向正确的Oracle数据库(开发,测试或生产)。

我找到的解决方案是将ODBC数据库连接设置为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