2011-06-02 76 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