Modifying Subreports
Modifying the properties of a subreport is the same as modifying the properties of any report. Throughout this book there is code for modifying report objects such as the fields, groups and formatting, and there is code for setting login information. Every line of the code samples can be used on a subreport without making any changes. This is because subreports are also derived from the ReportDocument class just like the main report is.
The only difference with modifying subreports is how you get a reference to them. When you add a subreport to the main report, it is derived from the class SubReportObject. But the SubreportObject class doesn’t let you modify the report objects. Instead, you have to instantiate the subreport as a new ReportDocument object variable. Use this object variable to modify the all properties and objects of the subreport.
There are two ways of getting a reference to subreport objects. The first way is to call the ReportDocument.OpenSubreport() method and pass it the subreport name. The second way is looping through the ReportObjects collection of the main report and finding each subreport. Referencing the subreport by name is much easier because you only have to call a single method. But that doesn’t mean that looping through the ReportObjects collection is frivolous. There is a reason for using both methods.
Use the OpenSubreport() method when you want to modify the properties of only one of the subreports. For example, you could have a subreport with salary information and it gets suppressed if the user doesn’t have permission to view it.
Looping through the ReportObjects collection is used when you want to apply the same modification to all the subreports. As each subreport is found, call a method which performs an operation on it and then returns back to look for more subreports. An example of this is setting the login credential for every subreport.
Let’s look at a couple examples to see how it all works. The first example opens a subreport using the subreport’s name.
Dim MyReport As New CrystalReport1
Dim MySubReport As CrystalDecisions.CrystalReports.Engine.ReportDocument
Dim MyReportObject As CrystalDecisions.CrystalReports.Engine.ReportObject
Dim MyTextObject As CrystalDecisions.CrystalReports.Engine.TextObject
MySubReport = MyReport.OpenSubreport("Sales Subreport")
MyReportObject = MySubReport.ReportDefinition.ReportObjects.Item("Text3")
MyTextObject = CType(MyReportObject, CrystalDecisions.CrystalReports.Engine.TextObject)
MyTextObject.ObjectFormat.EnableSuppress = True
CrystalReportViewer1.ReportSource = MyReport
After declaring the necessary variables, the first line of code calls the OpenSubreport() method of the report. This method takes the name of the subreport and instantiates a new ReportDocument object for the subreport. Notice that the variable MySubReport is declared as a ReportDocument class. In this example I used “Sales Subreport”, but you should replace this with the name of your subreport.
At this point, the variable MySubReport is just like any ReportDocument object variable that is used throughout this book. Modify its properties as you normally would. For example purposes I get a reference to the Text3 object and suppress it. The last step is assigning the main report object variable to the viewer so that the user can preview it.
As you can see, using the OpenSubreport() method is very simple. But there is one part that could cause you some confusion: figuring out the report name. The subreport has multiple names depending upon what part of the report designer you are looking at. The most obvious way of getting the report name is to look at the report object on the designer.
Figure 15-15. The subreport object in the designer.
In Figure 15-15 the subreport’s name is Sales Subreport. Luckily, if you get the name in this way, then you are correct. The tricky part is if you look in the Properties Window. The name is listed here as Subreportx (e.g. Subreport1). This is not the name that should be passed to the OpenSubreport() method. To make things even more unusual, try double-clicking on the subreport to open it in the designer. Then look at the Properties Window under the Report property. The Report property for the subreport lists the main report’s name, not its own name.
The second way of referencing a subreport is to loop through the ReportObjects collection and find each subreport. The next example uses this technique to clear the record selection formula of all subreports.
Dim MySubReport As CrystalDecisions.CrystalReports.Engine.ReportDocument
Dim MySubReportObject As CrystalDecisions.CrystalReports.Engine.SubreportObject
Dim MyReportObject As CrystalDecisions.CrystalReports.Engine.ReportObject
Dim MyReport As New CrystalReport1
For Each MyReportObject In MyReport.ReportDefinition.ReportObjects
If MyReportObject.Kind = CrystalDecisions.[Shared].ReportObjectKind.SubreportObject Then
MySubReportObject = CType(MyReportObject, CrystalDecisions.CrystalReports.Engine.SubreportObject)
MySubReport = MyReport.OpenSubreport(MySubReportObject.SubreportName)
MySubReport.RecordSelectionFormula = ""
End If
Next
CrystalReportViewer1.ReportSource = MyReport
Listing 15-15 gets a reference to each report object in the ReportObjects collection. It tests the Kind property to see if the object is a subreport. If it is, assigns the report object to a variable by explicitly casting it as the SubreportObject class. You need to cast it as the SubreportObject class because this class has a property called SubreportName. Pass the SubreportName property to the main report’s OpenSubreport() method. The object variably MySubReport is a ReportDocument object that holds the subreport. Just like the last listing, you can now modify the properties of the subreports using the properties and methods of the ReportDocument class. This example clears the record selection formula so that none of the subreports use any filtering. Once all the report objects have been examined and all the subreports have been modified, assign the main report object variable to the ReportSource property of the viewer so that the report can be previewed.