Crystal Reports Online Training

Learn Online, Anytime, Anywhere

Step-by-step online tutorials.

20.04 Opening a Report

Opening a Report

How you open a report is dependent upon how you installed RAS. We will create code templates that open a report and return a reference to it that you can use in your program. But before we do that, let’s look at the code that will control this process by declaring the appropriate report object variables and assigning the report to the viewer.

Listing 20-1 is a template for opening a report and modifying the report using the ReportClientDocument object. The code to modify the report isn’t included because we’ll cover those details later in the chapter. This is just a simple template that demonstrates how to get access to both report objects and preview the report afterwards. We’ll add more complexity with each new topic discussed.

Listing 20-1. Template for working with the ReportClientDocument
[VB.NET]
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim myReportDocument As CrystalDecisions.CrystalReports.Engine.ReportDocument = Nothing
Dim rcd As CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument = Nothing
OpenReportClientDocument("C:\myReport.rpt", myReportDocument, rcd)
'Insert code to modify the report here
CrystalReportViewer1.ReportSource = myReportDocument
End Sub
[C#]
private void Form1_Load(object sender, EventArgs e)
{
CrystalDecisions.CrystalReports.Engine.ReportDocument myReportDocument = null;
CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument rcd = null;
RAS_SDK.OpenReportClientDocument(@"C:\myReport.rpt", ref myReportDocument, ref rcd);
//…insert code to modify the report using the rcd object variable…
crystalReportViewer1.ReportSource = myReportDocument;
}

This code instantiates a ReportDocument object and a ReportClientDocument object. Both of these are passed to the method OpenReportClientDocument(), shown in Listing 20-2. When it returns, the two objects each have their own copy of the report in memory. You can modify the ReportClientDocument object to add any new report objects to it. The last step passes the ReportDocument object to the ReportSource property of the report viewer. This displays it to the user with any changes you made to the ReportClientDocument.

If you are not using InProc RAS, you will only be working with ReportClientDocument object. You do not need to declare and instantiate a ReportDocument object. When this is the case, you can assign a reference to the ReportClientDocument object directly to the viewer. Replace the viewer code with this:

CrystalReportViewer1.ReportSource = rcd.ReportSource

InProc RAS SDK

The InProc RAS SDK is used when your reporting solution isn’t working with larger enterprise software. When using InProc RAS, you open the report as you normally would, with a ReportDocument object. There are various ways of doing this depending upon your application and all them work with RAS. All the code samples throughout this book work without any changes. With RAS installed, the .NET ReportDocument class has a new property called ReportClientDocument. This is used to pass a reference of the currently open report to the RAS.

Listing 20-2. Create a ReportClientDocument using the ReportDocument object
[VB.NET]
Public Shared Sub OpenReportClientDocument(ByVal ReportFilePath As String, ByRef myReportDocument As CrystalDecisions.CrystalReports.Engine.ReportDocument, ByRef rcd As CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument)
'Use the ReportDocument object to load the report
myReportDocument = New CrystalDecisions.CrystalReports.Engine.ReportDocument()
myReportDocument.Load(ReportFilePath)
'Pass the report from the ReportDocument to the rcd
rcd = myReportDocument.ReportClientDocument
End Sub
[C#]
public static void OpenReportClientDocument(string ReportFilePath, ref CrystalDecisions.CrystalReports.Engine.ReportDocument myReportDocument,
ref CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument rcd)
{
//Use the ReportDocument object to load the report
myReportDocument = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
myReportDocument.Load(ReportFilePath);
//Pass the report from the ReportDocument to the rcd
rcd = myReportDocument.ReportClientDocument;
}

This is a generic method you can use in any report to get a reference to a new RAS ReportClientDocument using the report’s fully qualified file path. The first couple of lines simple use the Load() method of the ReportDocument to open the report and load it into memory. The last line passes a reference of the report to the ReportClientDocument object variable, rcd. Notice that the aregument list for the method references the ISCDReportClientDocument interface rather working directly with the class name. It’s important to remember that you have to use the class interface when declaring the variables, and use the class name when instantiating the object.

Since both objects are passed to the method by reference, the calling method can use these objects to make changes to them or print the report.

Using Unmanaged RAS

Open a report using unmanaged RAS is more efficient than using InProc RAS. This is because InProc RAS requires two steps to open a report. The first is to load it into memory and the second passes the report reference to RAS. When using unmanaged RAS you only need to call the ReportClientDocument.Open() method. This immediately loads it into RAS and it i ready for use. Let’s look at the code that does this.

Listing 20-3. Open a report using unmanaged RAS.
[VB.NET]
Public Shared Sub OpenReportClientDocument(ByVal ReportFileName As Object, ByRef rcd As CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument)
'Pass the report from the ReportDocument to the rcd
rcd = New CrystalDecisions.ReportAppServer.ClientDoc.ReportClientDocument
rcd.Open(ReportFileName, 1)
End Sub
[C#]
public static void OpenReportClientDocument(object ReportFilePath, ref CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument rcd)
{
//Pass the report from the ReportDocument to the rcd
rcd = new CrystalDecisions.ReportAppServer.ClientDoc.ReportClientDocument();
rcd.Open(ref ReportFilePath, 1);
}

As you can see, the code is similar to the InProce RAS listing, but it’s shorter. It simply instantiates the ReportClientDocument object and calls the Open() method to load the report into memory. One important thing to note is that the rcd variable is declared using the interface, but it is instantiated using the class name. This is because you can’t use the New keyword with an interface class.

Using Managed RAS

Managed RAS opens reports that are managed by your enterprise software. As you can see, this code is much more involved than the presious code samples. It requires you to login to the enterprise software, query the server, and create the ReportClientDocument object. The detailed notes are shown within the code listing.

Listing 20-4. Open a report using managed RAS.
[VB.NET]
Public Shared Sub OpenReportClientDocument(ByVal ReportFileName As Object, ByRef rcd As CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument)
Dim mySessionMgr As New CrystalDecisions.Enterprise.SessionMgr
Dim myEnterpriseSession As CrystalDecisions.Enterprise.EnterpriseSession
Dim myReportAppFactory As CrystalDecisions.ReportAppServer.ClientDoc.ReportAppFactory
Dim myInfoStore As CrystalDecisions.Enterprise.InfoStore
Dim myInfoObjects As CrystalDecisions.Enterprise.InfoObjects
Dim myInfoObject As CrystalDecisions.Enterprise.InfoObject
Dim myEnterpriseService As CrystalDecisions.Enterprise.EnterpriseService
Dim mySampleReportName As String
Dim myObject As Object
'Logon to the enterprise server using your credentials and server info
myEnterpriseSession = mySessionMgr.Logon("administrator", "", "localhost", "secEnterprise")
myEnterpriseService = myEnterpriseSession.GetService("InfoStore")
myInfoStore = New CrystalDecisions.Enterprise.InfoStore(myEnterpriseService)
'Instantiate the sample report and query for the Id in the Enterprise CMS
mySampleReportName = ReportFileName
myInfoObjects = myInfoStore.Query("Select SI_ID From CI_INFOOBJECTS Where SI_NAME='" + mySampleReportName + "' And SI_INSTANCE=0")
myInfoObject = myInfoObjects(1)
'Create the ReportAppFactory that is based on the enterprise session
myObject = myEnterpriseSession.GetService("", "RASReportFactory").Interface
myReportAppFactory = CType(myObject, CrystalDecisions.ReportAppServer.ClientDoc.ReportAppFactory)
'Use the OpenDocument method to instantiate the ReportClientDocument object
rcd = myReportAppFactory.OpenDocument(myInfoObject.ID, 0)
End Sub
[C#]
public static void OpenReportClientDocument(string ReportFilePath, CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument rcd)
{
CrystalDecisions.Enterprise.SessionMgr mySessionMgr;
mySessionMgr = new CrystalDecisions.Enterprise.SessionMgr();
CrystalDecisions.Enterprise.EnterpriseSession myEnterpriseSession;
CrystalDecisions.ReportAppServer.ClientDoc.ReportAppFactory myReportAppFactory;
CrystalDecisions.Enterprise.InfoStore myInfoStore;
CrystalDecisions.Enterprise.InfoObjects myInfoObjects;
CrystalDecisions.Enterprise.InfoObject myInfoObject;
CrystalDecisions.Enterprise.EnterpriseService myEnterpriseService;
Object myObject;
//Logon to the enterprise server using your credentials and server info
myEnterpriseSession = mySessionMgr.Logon("administrator", "", "localhost", "secEnterprise");
myEnterpriseService = myEnterpriseSession.GetService("InfoStore");
myInfoStore = new CrystalDecisions.Enterprise.InfoStore(myEnterpriseService);
//Instantiate the sample report and query for the Id in the Enterprise CMS
myInfoObjects = myInfoStore.Query("Select SI_ID From CI_INFOOBJECTS Where SI_NAME='" + ReportFilePath + "' And SI_INSTANCE=0");
myInfoObject = myInfoObjects[1];
//Create the ReportAppFactory that is based on the enterprise session
myObject = myEnterpriseSession.GetService("", "RASReportFactory").Interface;
myReportAppFactory = (CrystalDecisions.ReportAppServer.ClientDoc.ReportAppFactory)myObject;
//Use the OpenDocument method to instantiate the ReportClientDocument object
rcd = myReportAppFactory.OpenDocument(myInfoObject.ID, 0);
}