IncludeCaption versus FIELDCAPTION
Captions are sent as parameters and in the language of the user. In some cases, for example in document reports, you may want the captions to be in the language of the recipient, not in the language of the user. To do that, you use the FIELDCAPTION
function, and add the caption to the dataset as an extra column. Then, you can determine the language via C/AL code.
Note
Keep in mind that adding captions to the dataset with FIELDCAPTION
increases the size of the dataset, so only do this when it is really necessary. In previous versions of Dynamics NAV, captions were added by default in the dataset, so using IncludeCaption
and labels is a performance improvement.
An example of the use of FIELDCAPTION
can be found in most document reports:
- Sales: Quote
- Order: Confirmation
- Sales: Invoice
- Sales: Credit Memo
- Sales: Shipment
Examples of the FIELDCAPTION
function are shown in the following screenshot:
How is the dataset flattened?
At runtime, a report dataset consists of rows and columns. If you only have one data item, then the columns in the dataset designer become the columns of the runtime dataset and the rows from the data item (or table) become the rows in the dataset. In this situation, the runtime dataset looks the same as when you simply run the table.
If you combine multiple data items, then the data items at design time can be indented, or not, and this results in a different dataset at runtime. Since the runtime dataset is two dimensional, consisting of rows and columns, information is repeated over multiple rows.
In this section, I will explain and demonstrate how the runtime, flat, dataset is generated, using indented or non-indented data items.
Using multiple data items in a report is a common pattern in most reports and understanding how the multi-data-item dataset at design time is converted into the flat two-dimensional dataset at runtime is very important. Understanding this process is, in my opinion, the most important part of RDLC report development, because it determines how you build the layout and which filters you need to apply in the RDLC layout.
Unrelated tables or multiple data items, without indentation
As an example, let's start with a dataset that consists of two data items, Vendor and Customer:
When we run this report and display the dataset with the About This Report feature, it shows this:
In the dataset there is a column for every column in the report dataset designer: No_Vendor, Name_Vendor, No_Customer, Name_Customer.
When the report processes the data items it starts with the first one (on top), which is Vendor
. For all vendors, it fetches their No
and Name
and adds it to the dataset. The customer columns remain empty. Then, after the Vendor
data item has been completely processed, the system starts with the Customer
data item and does the same. The result sets of the two data items then follow each other in the dataset, stuck together.
Now imagine that I need to create a request page for this report to include an option to display details. Then, I would create a variable HideDetails
, add it to the request page, and also add it to the dataset. If I added this variable to the dataset as an extra column, then we would have a problem. Are we going to add it to the Customer or Vendor data item? If we add it to the customer data item, it will be available at runtime, but not in the vendor rows. Now, as this is a variable that contains a constant value, we only need it once and there's no point in repeating its value on every row, because that would increase the size of the dataset and so decrease performance.
The solution is to include an extra data item that will only add one row to the dataset. To do this, you can use the integer table, as shown in the following screenshot:
Then the dataset becomes this:
The integer data item adds one row at the end of the dataset and this contains the value of the HideDetails
variable.
Note
The expression SORTING(Number) WHERE(Number=CONST(1))
in the DataItemTableView
property of the Integer
data item makes sure that the outer data item produces exactly one row from the Integer
table.
Use the following expression to retrieve this value in the layout of the report:
Unless you add the integer data item as the first data item in the report dataset designer, the row is added to the beginning and the expression becomes this:
Remember that we have an extra row in the dataset containing our variable HideDetails
. This row should be filtered out in the tables in the layout that display the Vendors and Customers.
Note
An example of this report is available in the object: Packt - CH01-2
Using an integer data item, and filtering it to add one or more rows in the dataset, is a common pattern in report design. Instead of filtering on a constant value, you can also set the filter on the integer data item via the C/AL code in the integer data item OnPreDataItem
trigger. In that way, you can set it at runtime, depending on an option in the request page. In document reports, this is usually how the NoOfCopies
option is implemented. I will come back to this pattern in the Chapter 5, Document Reports.
Related tables or multiple data items with indentation
Let's create a report with a dataset that contains two data items as an example: Customer and Customer Ledger Entry.
Note
In document reports, this pattern is applied a lot, because, in a document report, we have many data items that need to be visualized in different tables (or sections) of the report.
The Customer Ledger Entry needs to be linked to the Customer, so for each customer we can see their individual entries. Linking data items is done by indenting them in the report dataset designer and then, in the indented data item setting, the link fields in the property DataItemLink
, as follows:
Then, when you run the report, the dataset becomes:
Customers that don't have ledger entries are shown, but the ledger entry columns are empty. Customers that have ledger entries are shown and, for every ledger entry, there's a row in the resulting dataset.
As you can see, if a customer has multiple ledger entries, then, for every ledger, a row is added to the dataset and the columns for the customers are repeated on each of these rows. This is called the flattening of the dataset, the columns of the parent record are repeated for every child record.
To filter out customers that don't have ledger entries, you can use the PrintOnlyIfDetail
property. You need to set this on the top data item, in this example, the Customer
:
The property PrintOnlyIfDetails
specifies whether to print data in a report for the parent data item when the child data item does not generate any output. If there are more than two data items, then the report iterates through each parent child relationship in the same way.
Note
An example of this report is available in the object: Packt - CH01-3
If you are going to create a layout for this dataset and you want to see the ledger entries per customer, you do this by creating a group in the table and grouping on Customer No
.
This is a very common design for the datasets in Dynamics NAV reports. It is used with header and line tables, master and ledger tables, and also in document reports.
Tip
If you omit the DataItemLink and DataItemLinkReference between the Customer and Customer Ledger Entry table, which effectively disconnects the two tables, then the resulting dataset is much larger, since it includes all possible combinations of headers and lines, with absolutely no regard to their possible table relations.
When using multiple data items with indentation, you can also apply the technique of including an integer data item. In that case, investigate the resulting dataset before you create the report layout because, depending on the result, you might want to move the integer data item to the top or bottom to get a better dataset.