Anatomy of a report extension

Completed

With the report extension object, you can extend existing report objects, similar to how you extend tables and pages.

Report extension object

With report extensions, you can extend an existing report by adding:

  • Columns to existing data items in the report dataset.

  • New data items.

  • Trigger implementations.

  • Information to request pages.

  • Information to a new report layout to reflect the new fields that are added with an extension.

For a report to be extended, the Extensible property must be set to true. This value is the default, which means that reports by default can be extended unless they explicitly have the Extensible property set to false.

Typing the shortcut treportext will create the basic layout for a report extension object when you are using the AL Language extension in Visual Studio Code.


reportextension Id MyExtension extends MyTargetReport
{
    dataset
    {
        // Add changes to dataitems and columns here
    }

    requestpage
    {
        // Add changes to the requestpage here
    }
}

Limitations

Inside the dataset element, syntax for modifying data is not supported, meaning that you can't add new triggers to existing data items, and you can't modify existing data items or column properties. Inside the requestpage element, you can't modify properties.

Using the OnInitReport trigger isn't supported for report extensions. The OnPreReport and OnPostReport triggers are run after the original report's equivalent triggers.

Major sections of an extension

The following image shows the major sections of a report extension object.

Screenshot of the report extension sections.

The first item in the screenshot is a new top-level object called report extension, which requires an ID that reuses the report range. The extends keyword is similar to other extension objects, and a treportext snippet supports the creation of a new report extension object.

The image also displays two properties that are supported on the report extension object:

  • WORDLayout

  • RDLCLayout

Additionally, the image shows the same top-level sections as in a normal report object, such as:

  • The dataset, which contains the data items and columns.

  • The request page, where you can add to or modify the request page.

  • A label section, which is supported now.

  • Triggers, procedures, and variables that are global to the report extension. The triggers that are supported on the report extension object are the OnPreReport() report and the OnPostReport() trigger. These triggers can't be overridden and will be called after the base report triggers. If multiple report extensions are shown on the same base report, they will be called in sequence according to the dependency graph.

Choose layouts from report extensions

When an extension deploys to a customer environment, either as an app from Microsoft AppSource or as a per-tenant extension (PTE), any report layouts in the extension also become available in the environment. However, if you want to apply a report extension layout to a specific report, you need to add installation and upgrade code in the extension.

Users will be able to choose a layout from a report extension in the Report Layout Selection page, which lists all available layouts for a given report. The Report Layout Selection page includes layouts from report extensions so that the user can choose between all available layouts.

Add columns to existing data items

Consider a scenario where you need to add columns to an existing data item. The following image represents an example of how to add columns to an existing data item.

Screenshot of an example of how to add columns to an existing data item.

A new add command is linked to a data item anchor. Within the command, you can specify the data item that you want to add to. You can add to the base report but also to data items in report extensions for that base report, meaning that you can create a dependency on other report extensions. Then, you can add columns to the data item and add columns for fields in the data item source, including extensions that you might have to that data item source.

Therefore, if you have a table and you want to create a report that has a report extension that relies on a column that isn't in the data source for the base report, you could add that report to the table for the base report though a table extension and then use that report in the report extension.

You can also add columns for variables in the report extension and access variables in the base report, provided that they're shown as protected. Now, most variables in the base reports are not marked as protected; they are typically marked as private.

To access those variables that are marked as private in base reports, you will need to file a request for the AL application on GitHub. For more information, see Visual Studio Code AL Language extension for Dynamics 365 Business Central.

You can add columns for expressions and procedures. The columns can be local and can be in the report graph; but again, they will need to be shown as protected.

The columns have the same properties as in the normal report, except that release 2021 Wave 1 doesn't support Caption, CaptionML, and IncludeCaption. These properties might be supported at a later time.

Modify existing data items

Modification of existing data items in general isn't supported through report extensions. Currently, no plans are in place to support modification of column properties. Alternatively, you can add a new column, hide the original columns from layout, and then transform the value. No plans are in place for supporting modification of base labels and for overriding existing triggers. More trigger support might be offered in later releases.

Add new data items to existing data items

Occasionally, you might not want to add to an existing data item but would rather add one or more new data items. This action is possible with Business Central.

The following code example shows a new section for adding data items.

Screenshot of a code example with a new section for adding data items.

To add nested in target dataitem, use the following values:

  • addfirst()

  • addlast()

To add next to target dataitem, use the following values:

  • addbefore()

  • addafter()

This example includes an addfirst() value. You can add data items to the existing base report or to a report extension in the graph. The members are similar to normal report data items. The same properties are available, including the ability to set up the link between the data item and the parent data item. The same triggers are provided, and you can insert one data item or a whole graph of nested data items at one time.

This example shows two data items being inserted into the anchor. The same column support exists as in regular data items. Business Central doesn't support the addition of new root data items. You can insert new root data items in one of the existing data items. If you try that approach, you will get a compiler error, as shown in the following screenshot.

Screenshot of a compiler error caused by the addition of new root data items.

Extend the request page

Extending the request page is supported. The following screenshot shows an example of a request page.

Screenshot of a request page that you might want to extend.

No properties are available on the request page in a report extension. The layout section is similar to a normal page because the request page is basically a page, meaning that the request page extension is similar to a page extension.

The layout sections are similar to page extensions:

  • addafter()
  • addbefore()
  • addfirst()
  • addlast()
  • modify()
  • moveafter()
  • movebefore()
  • movefirst()
  • movelast()

Therefore, you can move around fields and add fields to the request page of a report extension. Then, the fields that you can add to the request page are similar to a normal report request page.

You can add the following items in a report extension or protected members in the dependency graph.

  • Columns

  • Variables

  • Expressions

  • Procedures

The triggers on the request page are similar to a report request page, meaning that triggers exist on the request page node. Triggers will also be available for new fields and modified fields. The call sequences work similar to normal pages.

Triggers that are called afterward will be called after the triggers that were called on the base object, and the other triggers will basically replace or override the rest.

Triggers on the requestpage node include:

  • OnAfterGetCurrRecord
  • OnAfterGetRecord
  • OnClosePage
  • OnDeleteRecord
  • OnInsertRecord
  • OnModifyRecord
  • OnNewRecord
  • OnOpenPage
  • OnQueryClosePage

Triggers on new requestpage fields include:

  • OnAfterLookup
  • OnAssistEdit
  • OnControlAddIn
  • OnDrillDown
  • OnLookup
  • OnValidate

Triggers on modify request page fields include:

  • OnAfterLookup
  • OnAfterValidate
  • OnAssistEdit
  • OnBeforeValidate
  • OnDrillDown
  • OnLookup

Add layouts

If you want to add a layout as a part of a report extension, the process will work similar to a normal report. You can add one RDLC and one Word layout in a report extension object. Adding a layout to a report extension is not mandatory. It's important to know that extensibility of the layout isn't supported. You can only substitute a report layout.

In Visual Studio Code, when you create a report extension, you might often want to use the base report layout as a starting point. To use that approach, you will need to go to the client, download the report layout, and then add it into your report extension.

The layers that are part of the report extension will be deployed with the parent application and will display as built-in layouts. These new layouts won't be assigned to the report automatically. You will need to select and set them manually in the Report Layout Selection page, or you could write installation code to automate this task.

Screenshot of a built-in report layout dialog.

Other report extensions might extend the same report, which could override your installation code. It's only possible to select layout types that are supported by the base report.

The Report Layout Selection (and Custom Report Layout) page doesn't list the parent extension for available layouts.

What happens on uninstall

When you uninstall a report extension, the layout is hidden from the user interface. Specifically, when you uninstall the report extension, it will no longer be available in that previous location for you to select. However, the custom layouts will remain available. If you have a custom layout that uses some of the columns in a report extension, and you uninstall the report extension, you will get a runtime error when running the report. Then, you will need to manually fix that error in the layout.