In an n-tier application using Crystal Reports, it is necessary to populate reports from offline DataSets instead of using a direct DB connection. This class allows feeding a Crystal Report with 1 or more DataSets (in the case of subreports, you can have the DataSets in the same order as they appear in the main Crystal Report).
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.Shared
Public Class CCrystalUtilities
Public Shared Function GetReportDocument(ByRef oRpt As ReportDocument, ByRef dsDataSets() As DataSet) As ReportDocument
' this function accepts a Path to a report and an array of DataSets to use
' to fill the report (in the case of nested reports, we need to use multiple
' datasets per report)
Dim iDataSetNum As Integer
' set the main report's DataSource
oRpt.SetDataSource(dsDataSets(iDataSetNum))
iDataSetNum += 1
Dim mySection As Section
Dim mySections As Sections
Dim myReportObject As ReportObject
Dim myReportObjects As ReportObjects
Dim mySubReportObject As SubreportObject
Dim mySubRepDoc As New ReportDocument()
'Declare all of the sections of the main report
mySections = oRpt.ReportDefinition.Sections
'Loop through the sections in the main report to find the
'subreport(objects)
'then open the subreport and set the datasource to the subreport()
For Each mySection In mySections
myReportObjects = mySection.ReportObjects
For Each myReportObject In myReportObjects
If myReportObject.Kind = ReportObjectKind.SubreportObject Then
'Subreport Found - convert the report to a sub report type
mySubReportObject = CType(myReportObject, SubreportObject)
'Set the specific instance of this subreport
mySubRepDoc = mySubReportObject.OpenSubreport(mySubReportObject.SubreportName)
mySubRepDoc.SetDataSource(dsDataSets(iDataSetNum))
iDataSetNum += 1
End If
Next
Next
' return the complete report
Return oRpt
End Function
End Class