Dynamics 365 Business Central: why not start stop using OnFindRecord or OnNextRecord triggers on pages?

OnFindRecord and OnNextRecord are two triggers available on a Page objects from ever.

The OnFindRecord trigger overrides the default page behavior and enables you to specify which record you want to display when the page opens. By default, open pages display the last record shown when the user exited the page. You can use this trigger to override the default behavior and display the first record, last record, or a specific record as defined in the Rec variable:

trigger OnFindRecord(Which: Text): Ok
begin
    ...
end;

The OnNextRecord trigger determines the next record to be displayed on a page. This trigger is executed in place of the default next record behavior:

trigger OnNextRecord(Steps: Integer): ActualSteps
begin
    ...
end;

where Steps is the number of records stepped through before displaying another record (a negative value indicates steps backwards).

These triggers was quite often used on Dynamics 365 Business Central pages, both custom and standard pages.

Now… do you remember this post? Here i talked about the impact of tableextension objects on performances, expecially on heavy tables. You should be careful on having too much extensions extending the same table if this is a table that can contain a lot of records, because you can have impacts on performances.

Microsoft was aware of this problem and with Dynamics 365 Business Central 2020 Wave 2 they released a great feature called Partial Records.

The partial records capability in Business Central allows for loading a subset of normal table fields when accessing a SQL based data source. Accessing a data source from AL code is typically done by using the record’s methods Get, Find, Next, and so on. Without using partial records, the runtime loads ALL normal fields when accessing the data source. Using the partial records feature, you can now select a set of fields and only load them.

Partial Records is not a feature that you can only use via AL code (via the SetLoadFields method) buy it’s now something that is automatically applied by the platform to certain AL objects based on their metadata. To be more precise, partial records feature is currently applied in the following objects:

  • Reports
  • List and Listpart pages
  • OData pages
  • Table relation-based lookups.

All good! So… what’s the problem here?

There’s a side note that I think few people know: OnFindRecord and OnNextRecord triggers conflict with partial record feature with List and ListPart pages, so if these triggers are defined in the metadata, the partial record feature won’t be applied.

Now, imagine the following scenario (real scenario taken from a partner that recently contacted me about performance problems). The customer has a very large Item table (lots of records) with also different extensions that adds fields to the Item table via tableextension objects. They try to open the Item List page and it’s extremely slow! No FlowFields was added to that page. Only a small subset of fields was visible on the page.

Why so slow? Why Partial Records feature doesn’t work well here?

Because on the marvellous standard Item List object, there are these two triggers:

These 2 triggers breaks Partial Records loading!

I think that these two triggers should be avoided on standard pages, expecially if these standard pages have an underlying table that can contain a lot of data. Are these two triggers really necessary here? I’m not so sure…

I suggest Microsoft to review that code and maybe remove or re-implement the usage of these triggers. They can really have a serious impact on performances. Please listen… 🙂

The same is for you: please avoid using these two page triggers on heavy loaded pages if you want to avoid performance impacts.

3 Comments

  1. I think there is a similar functionality recommended. I had just an example where i had to select Extended Texts on different filters, you could no convert into on Filter expression.
    In my case i used MarkedOnly(true), but i don’t know if this does not convert into a OnFind/OnNext in background.
    But i would require a functionality that allows me to show only selected records without using temporary records, which took me days to workaround in the same example.

    Like

  2. Can’t the compiler fetch which fields are really needed by the page, report, in code, etc.?

    and we can override with SetLoadFields. Saves a lot of work..

    Like

  3. I’ve never been a big fan of those triggers.
    However, looking at some of the standard APIs in BC (e.g. salesOrders) MS is still relying on those triggers.
    Because of that, I don’t think they’ll disappear any time soon 😞

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.