Introduction to Subreports 288
Understanding Linked Versus Unlinked Subreports 292
Considering Subreport Execution Time and Performance 295
Using Variables to Pass Data Between Reports 297
Emulating Nested Subreports 300
Crystal Reports in the Real World—Multiple Subreports 301
The first 11 chapters of this book introduced you to the design of individual reports using single aggregated datasets. Crystal Reports provides further flexibility and reporting capabilities through the use of additional reports embedded directly within an original main report. These embedded reports, referred to as Subreports, provide enhanced value extending your reporting solutions into an expanded domain that will be explored in this chapter.
The next two sections provide you with
Crystal Reports provides the capability to embed multiple Crystal Reports within a single existing main report to allow for increased flexibility in report creation. Think of these Subreports as entire reports within reports, which can contain their own data sources, formatting, and record selections. The embedded Subreports can be created from existing Crystal Reports files or can be dynamically created at report design time using the insert Subreport functionality. When presenting a report that contains one or more Subreports to business users, the Subreports can be displayed either in-place, providing a seamless integration, or on-demand, minimizing the amount of required up-front report processing.
A few particular reporting problems are difficult to solve without the use of Subreports. Some of the most common problems and a specific example of each are listed here:
Data presented in Subreports is often related to the data presented in the associated main report, but it does not have to be. Subreport data can be a twist on the main report’s information or sourced from a completely different database.
Adding a Subreport to your main report is as easy as adding any other Crystal Reports object. After selecting the Subreport option from the Insert menu, you are presented with the Insert Subreport dialog (see Figure 12.1).
To explore one of the many challenges solved by using Subreports, let’s solve the hypothetical reporting problem faced by the Chief Operating Officer (COO) of Maple Leaf Bikes Corporation. This COO wants a single report that highlights the recently acquired company’s (Xtreme) top-selling products in one bar chart and additionally highlights the company’s top selling sales reps in a corresponding pie chart. The two charts are sourced from the same sales information but have no direct relation or links to each other. To resolve this request, complete the following steps:
As mentioned in the previous sections, Subreports are Crystal Reports in their own right, and as such they have their own Design tab in the Crystal Reports Designer. To format the details of a Subreport, it is necessary to open the Design tab for that Subreport from within the Designer of the main report. This can be accomplished by right-clicking on a Subreport and selecting the Edit Subreport option. Figure 12.3 displays the tabs for both the sample’s main report and the Subreport.
With that introduction to Subreports, you should begin to see some of the flexibility and power that they offer in solving difficult reporting (and even dashboard-related) problems. The next few sections explore this in more detail.
The hypothetical COO scenario just explored highlights an example of an unlinked Subreport. In Crystal Reports terminology, this means that the parent, or main, report did not have any specific data connections (or links) to its related child report (the Subreport). Unlinked Subreports are completely independent from their main reports and do not rely on the main report for any data. Many reporting problems in which multiple views of the same or different data sources are required in a single presentation can be resolved with unlinked Subreports. If a requirement exists to share data between the parent/main report and its Subreport, linked reports provide the answer.
Contrary to unlinked Subreports, linked Subreports are bound (or linked) to the data in their associated main report. The links are defined in the Link tab of the Insert Subreport dialog shown in Figure 12.4.
The Link tab enables you to link report, database, or formula fields in the main report to fields in the Subreport and enables you to filter the Subreport based on the data passed in from the main report.
The Available Fields section of the Links dialog enables you to select the field from the main report to be linked on. More than one field can be selected for linking. After at least one field has been selected, a separate Field Links section appears at the bottom of the Links tab. For each linked field, a parameter in the involved Subreport must be selected to receive and hold that information. These parameters can be pre-existing parameters predefined in the Subreport, or they can be a parameter that is automatically created for each field you have selected to link. (These are automatically created in the Subreport with the prefix ?Pm-
.)
Finally, for each linked field from the main report, a data filter can be created in the Subreport based on that parameter. This is accomplished by checking the Select Data in Subreport Based on Field check box and selecting the report field, database field, or formula field in the Subreport that you want to have filtered based on the linked parameter from the provided drop-down box. In effect, checking this box creates a selection filter in your Subreport that is based on the selected filter field and the selected parameter field.
To explore a reporting solution with linked Subreports, solve the hypothetical reporting problem faced by the same COO of Maple Leaf Bikes Corporation. The COO now wants a single report that highlights the company’s top-selling product types in one bar chart (similar to the previous example), enables drill-down into the actual products, and produces a list of suppliers for each product type to be available for review—essentially, a Supplier’s listing Subreport linked to the main report based on the Product Type Name. To accomplish this, follow these steps:
'?Pm-Product_Type.Product Type Name'
for the link on the Subreport.The COO can now make an informed analysis on whether his firm has too much reliance on a small number of suppliers, and you have learned some of the benefits of a linked Subreport.
Unlike the initial sample report presented in this chapter where we placed the Top Sales Rep Subreport in the Report Header and it ran once for the entire main report, the Product Suppliers Subreport is run multiple times—in fact, once for every product type. This is the case because the Subreport was placed in the Group Header of the main report, and it therefore is executed for each different group in the main report. This is important to note with respect to performance, specifically when your databases and reports become large.
There are two types of Subreports—In-Place and On-Demand. Both of the sample reports created previously in this chapter have been In-Place Subreports. An In-Place Subreport is virtually indistinguishable from the main report components when viewed because it is run at the same time as the main report. In-Place Subreports are displayed as components of the main report like any other report object and require no special business user interaction to view them. On-Demand Subreports, on the contrary, are not executed at the same time as the main report and require user interaction to be viewed.
All In-Place Subreports on a main report are run at the execution time of the main report. In the two examples presented in this chapter, this has clearly not caused any performance problems, but as you might imagine, it could on larger databases and reports. Imagine running the last sample report (with the Product Suppliers Subreport in every Group Header) for a large conglomerate with thousands of products. The Product Suppliers Subreport would need to run thousands of times to complete the presentation of the main report. Moreover, the thousands of supplier Subreports would be unlikely to be used by any given business user and would therefore have run extraneously. An elegant solution to that problem is the use of On-Demand Subreports.
Unlike In-Place Subreports, On-Demand Subreports only execute when a user requests them. They lie dormant until that time. The performance benefits to On-Demand reports are clear; however, it does come at the expense of a less seamless integration than In-Place Subreports and a small delay in viewing because the Subreport executes dynamically after being requested.
Taking the last example, follow these steps to make the Product Suppliers Subreport an On-Demand Subreport:
'Supplier List'
(do include the apostrophes) in the Text Editing area. Click on the Save and Close button, and you should now have a main report that resembles Figure 12.7 where the Supplier List link dynamically runs the involved Subreport if and only if a report consumer requests it.Careful consideration should be given to report design when deciding between In-Place and On-Demand Subreports. There is a trade-off between the seamless integration of In-Place Subreports and the performance benefits of On-Demand Subreports that must be considered in addition, of course, to the specific requirements of the business users’ overall experience.
The examples up to this point in the chapter that involve passing data between a main report and a Subreport have worked exclusively through the Subreport Linking tab or dialog. Although the functionality provided there is certainly powerful, circumstances might require more flexible passing of data between the main report and the Subreport or the passing of data the other way—from a Subreport to a main report.
With the use of variables, it becomes possible to pass data between the main report and any of the Subreports or even among different Subreports in the same main report. By declaring the same shared variable in formulas in both the main report and at least one Subreport, data can be exchanged back and forth fluidly, and each report can leverage information from the other in a very flexible manner.
Using Subreports and variables to pass data back to a main report from a Subreport is an effective way to capture important summarizations or external information to your main report that is not possible otherwise because of the default groupings of the main report. A simple example in this chapter’s last sample report would be the inclusion of a count on the number of suppliers for each product. Using only the default groupings provided in the main report (By Product), this count would be impossible to calculate. By using a Subreport, however, that count can be calculated external to the main report (in a Subreport), shared using variables, and eventually displayed on the main report.
To explore the power of shared variables, follow these steps to modify this chapter’s last sample report:
When passing shared variables from a Subreport to a main report, the involved Subreport cannot be set to On-Demand. The reason, of course, is that Subreports are not run until specifically requested by the business user. Therefore, their associated variables are not set until that time, making them unusable in the main report.
Assign Supplier Count
. In this formula, declare a shared numeric variable called SupplierCount
and then assign this variable to equal the Supplier Summary created in the last step. (Reminder: You can access the summary created in step 3 for use in your formula by double-clicking on it.) The formula definition should resemble Figure 12.8.Place Supplier Count
. In this formula, declare the same shared numeric variable—SupplierCount
—and make this variable the output of this formula. Figure 12.9 shows what this formula should look like.It is important that this Formula is placed in the Group Footer of the Product Type Name Group. This strategic placement ensures that the Supplier List Subreport for the involved Product Type has already completed (as it is in the Group Header) and has set the shared SupplierCount
variable appropriately. Careful consideration needs to be given when using variables to ensure they are evaluated at the time and in the order desired.
In addition to the Top to Bottom and Left to Right default evaluation times of Crystal Reports, the EvaluateAfter()
and a few other functions discussed in the Multi-Pass reporting section in Chapter 4, “Understanding and Implementing Formulas,” are useful in ensuring the desired reporting results.
Supplier Count
, hide the Details section on the main report and with a little creative formatting and group sorting, the final result should resemble Figure 12.10.Perhaps not the prettiest report ever designed, this quick example does begin to convey the power and importance of shared variables in report design.
As you discover the power of variables, you will begin to leverage this programming feature in increasingly complex ways. The Supplier Count example just provided is a relatively simple example that scratches the surface of the power of variables. Another variable-based technique that can be used to circumvent some common reporting challenges is to use variables to manage Running Totals. The flexibility provided within the Formula Editor and with variables enables you to create flexible condition-based running totals.
Based on the title of this section, you can deduce that it is not possible to nest Subreports—why else would you need to emulate that behavior? Crystal Reports does not currently support Subreports within Subreports. Report Hyperlinks and Report Parts do, however, provide a flexible method in advanced navigation between and within reports. This form of flexible navigation can be used to emulate nested Subreports and was covered in Chapter 9, “Custom Formatting Techniques.”
I can’t figure out how to format the details of a Subreport.
Open the Design tab for that Subreport from within the Designer of the main report. This can be accomplished by right-clicking on a Subreport and selecting the Edit Subreport option.
I would like to enable report viewers (or end users) to be able to dynamically send updates back to a source database—can subreports help me accomplish this?
Using a clever combination of subreports and SQL commands, you can provide this capability to your end users. You can add On-Demand subreports to your main report and have each of the On-Demand subreports based on a SQL command that includes an INSERT SQL statement that writes back to a datasource. An example SQL command could be
Each time a report-viewing end user requests that the on-demand subreport run, this SQL statement will be executed and update the involved datasource. To make this data updating process more dynamic, the preceding example could have the inserted values fields replaced with dynamic data fields from the report (for example, Customer ID or Employee ID).
As discussed earlier in the chapter, a single report often needs to show data from different and frequently unrelated pieces of information. In the next example, the main report shows both customer and supplier information with two separate Subreports and each of them for a given geographic location using the main report’s regional grouping hierarchy as a filter on the underlying Subreports. You will create a main report for the hierarchical geographic structure of Country, Region, and City hierarchy and then add one Subreport to show customer information and another Subreport for supplier information. Because there is no relationship between suppliers and customers, at least one of these pieces of information must come from a Subreport. For this sample, both elements come from a Subreport to highlight the capability to use multiple Subreports in a single main report. Follow these steps to explore this capability:
Preview the report and notice on Page 13 (Canada) that there is different and unrelated information for both Suppliers and Customers listed and that the information for both is specific to the location context.