Before EVOLVE 9.0, sub-reports required additional scripting, making them difficult to implement. With the 9.0 release, you can more easily add Sub-Report(s) to a report. However, designing reports with one or more sub-reports requires careful planning and a clear understanding of how various data types relate to one another. I have attached a working sample model and report that contains two sub-reports. The main report counts and displays families. The first sub-report pulls ancillary information from a data table based on the Family and Type. The second sub-report sums and totals the ancillaries. But first, let's review some concepts used in creating these sub-reports.
Understanding Data Relationships
A data relationship refers to the association between data elements. These relationships define how data in a table or dataset relates to data in another.
Types of Data Relationships
One-to-One - Each record in a table or dataset corresponds to exactly one record in another. For Example, a Revit Element and the Element Id - each element in a Revit model has a unique Element Id.
One-to-Many - One Record in a table or dataset is related to multiple records in another. For example, Family and Types - a Revit Family can have multiple Types, but each Type is tied to only one Family. NOTE: This report uses a One-to-Many relationship, where the element's Family and Type parameter value matches one or more values in the data table.
Many-to-Many - Records in one table or dataset are related to multiple records in another, and vice versa. For example, Levels and Families - a Family may be placed on a Level, which can contain multiple families.
Self-Referencing - Data within the same table or dataset can relate to itself. For example, a Family may have a parameter that defines its usage. The parameter allows users to filter elements to categorize them within the project.
Binding Parameters
Binding parameters in the Sub-Report function enables communication between the main report and the sub-report. This process links a parameter in the sub-report to a specific value (field or parameter) in the main report. By passing these values, the sub-report can dynamically adapt to the context of the main report, filtering or customizing the displayed data as needed. This ensures that the sub-report presents relevant information matching the details or conditions defined in the main report.
NOTE: Fields from the main report are bound to report parameters from the counts sub-report.
GetGlobal functions
The "GetGlobal" functions allow data to be stored globally and accessed across different reports. In this report, the stored values are dynamically populated with data from the data table, quantities in the main report, and accumulated values in sub-reports.
SetGlobalNumber(Name,Value)
To set, a Name and Value must be supplied. The Name can be manually specified or dynamically populated with a field or parameter value. The Value can be manually specified or dynamically populated with a field or parameter value, and the data type is numerical.
Example 1 - SetGlobalNumber('Test1', '1')
Example 2 - SetGlobalNumber('Test2', [Length])
GetGlobalNumber(Name)
To retrieve, a Name must be supplied.
Example 1 - GetGlobalNumber('Test1')
Based on the above SetGlobalNumber expression in Example 1, this GET would return 1.
Example 2 - GetGlobalNumber('Test2')
Based on the above SetGlobalNumber expression in Example 2, this GET would return the current value in the [Length] parameter.
SetGlobalString(Name,Value)
To set, a Name and Value must be supplied. The Name can be manually specified or dynamically populated with a field or parameter value. The Value can be manually specified or dynamically populated with a field or parameter value, and the data type is a string.
Example A - SetGlobalString('TestA', 'SomeTextHere')
Example B - SetGlobalString('TestB', [Family and Type])
GetGlobalString(Name)
To retrieve, a Name must be supplied.
Example A - GetGlobalString('TestA')
Based on the above SetGlobalString expression in Example A, this GET would return SomeTextHere.
Example B - GetGlobalString('TestB')
Based on the above SetGlobalString expression in Example B, this GET would return the current value in the [Family and Type] parameter.
ClearGlobalValues()
If the Name is known, specific Global values may be defined. However, if the Name is dynamically populated, leaving the field blank clears all global values.
Example 1 - ClearGlobalValues('Test1')
In this example, only the stored value for Test1 (GetGlobalNumber) is cleared.
Example 2 - ClearGlobalValues()
In this example, all Global values are cleared.
NOTE: This report does not use the Get/SetGlobaString functions.
Download the attached file, extract the contents, and place the files in the following directory:
C:\Temp\SubReportsIMPORTANT: The files MUST be placed into this directory, as all configurations are pointing to this directory.
Running the main report
From Revit 2023, navigate to C:\Temp\SubReports and open the eV_SampleModel_SubReports_FIN_R23.rvt file.
From the EVOVLE tab, in the Utilities ribbon, click Reports Manager.
From the Reports Manager window, in the grid, select the eV_Sample Sub Report_MainReport_FIN report and click Run Report.
The Preview window opens, and the report is displayed.
The image below is the main Sample Sub Report with the instances of each sub-report denoted.
For a more in-depth look at configuring Sub-Reports, check out the link in the Relevant Articles section below. The article is a walk-through on how this report is set up and configured.