--- title: "Record handlers" slug: "bc-record-handlers" description: "Customize your internal document tables with record handlers and interfaces for data manipulation during RECORDGENERATOR activities." tags: ["BC", "BIS", "Business Central", "Business Integration Solutions", "Task"] updated: 2026-06-25T07:58:56Z published: 2026-06-25T09:59:17Z canonical: "docs.staedean.com/bc-record-handlers" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.staedean.com/llms.txt > Use this file to discover all available pages before exploring further. # Record handlers A record handler enables customizations for a specific table of an internal document through interfaces. The following interfaces expose data manipulation when a [RECORDGENERATOR activity](/business-central/docs/bc-recordgenerator-activity) runs: | Interface | Description | | --- | --- | | `BISIOnBeforeProcessRecord` | Executes functions or manipulates field values before the record validates and updates. An example is a general journal line that needs a special document number. In the method this interface exposes, the field values are set but not yet validated. | | `BISIOnInsertRecord` | Overrides the **Insert** trigger of a record. D365 BC runs the **OnInsert** trigger of a record by default. **Note:** the record does not insert if this trigger does not perform an explicit INSERT statement. | | `BISIOnModifyRecord` | Overrides the **Modify** trigger of a record. D365 BC runs the **OnModify** trigger of a record by default. **Note:** the record does not modify if this trigger does not perform an explicit MODIFY statement. | | `BISIOnDeleteRecord` | Overrides the **Delete** trigger of a record. D365 BC runs the **OnDelete** trigger of a record by default. **Note:** the record does not delete if this trigger does not perform an explicit DELETE statement. | | `BISIOnAfterProcessRecord` | Executes after validating the record and updating the database. Use this to update related tables or run additional functions. | ## Default record handlers Three record handlers are available out of the box: | Handler | Remarks | | --- | --- | | Base Record Handler | The default handler. | | Business Integration Solutions Reopen Document Handler | Implements `BISIOnBeforeProcessRecord`: reopens a sales or purchase document. | | Business Integration Solutions Update Released Document Handler | Implements `BISIOnBeforeProcessRecord` and `BISIOnAfterProcessRecord`: reopens a document, then releases it again after the record processes. | ## Create a custom Record Handler ### Usage Use this task when you want to override one or more triggers that run during record generation. ### Prerequisites The following prerequisites are required: - Experience developing in Microsoft Dynamics 365 Business Central AL. - Basic understanding of Business Integration Solutions. - A development license. ### Steps 1. Create a new codeunit and implement one to five interfaces: ```plaintext codeunit 50000 YourCustomHandler implements BISIOnBeforeProcessRecord, BISIOnInsertRecord, BISIOnModifyRecord, BISIOnDeleteRecord, BISIOnAfterProcessRecord {    var        // All procedures required by the implemented interfaces must be created.        // If you only need to hook into OnInsert, put your logic there and let the        // Base Connector handle the rest.        BaseConnector: Codeunit "TIC Table Connector Base"    procedure OnBeforeProcessRecord(var Rec: RecordRef): Boolean    begin        exit(BaseConnector.OnBeforeProcessRecord(rec));    end;    procedure OnInsertRecord(var Rec: RecordRef): Boolean    begin        // Add your logic for inserting a record here.        Rec.Field(YourTable.FieldNo(YourFieldNumber)).Value('New value');        exit(BaseConnector.OnInsertRecord(rec));    end;    procedure OnModifyRecord(var Rec: RecordRef): Boolean    begin        exit(BaseConnector.OnModifyRecord(rec));    end;    procedure OnDeleteRecord(var Rec: RecordRef): Boolean    begin        exit(BaseConnector.OnDeleteRecord(Rec));    end; } ``` 1. Create an enum extension that extends `BISRecordHandler`. If you already have one, skip to the next step: ```plaintext enumextension 50000 YourEnumExtension extends BISRecordHandler {    ... } ``` 1. Add a new value in the enum extension that references your custom handler from step 1: ```plaintext enumextension 50000 YourEnumExtension extends BISRecordHandler {    value(YourCustomHandlerId; YourCustomHandler)    {        Implementation =            BISIOnBeforeProcessRecord = YourCustomHandler,            BISIOnInsertRecord = YourCustomHandler,            BISIOnModifyRecord = YourCustomHandler,            BISIOnDeleteRecord = YourCustomHandler,            BISIOnAfterProcessRecord = YourCustomHandler;    } } ``` > [!NOTE] > **Note** > > You can also mix and match, use a combination of the custom handler and the base connector. This way you only implement the needed interfaces, and the base connector handles the rest by default. See the example below. ```plaintext // Enum extension example value(YourCustomHandlerId; YourCustomHandler) {    Implementation =        BISIOnBeforeProcessRecord = YourCustomHandler,        BISIOnInsertRecord = "BIS RecordHandler",        BISIOnModifyRecord = "BIS RecordHandler",        BISIOnDeleteRecord = "BIS RecordHandler",        BISIOnAfterProcessRecord = YourCustomHandler; } // Codeunit handler example codeunit 50000 YourCustomHandler implements BISIOnBeforeProcessRecord, BISIOnAfterProcessRecord {    procedure OnBeforeProcessRecord(var RecRef: RecordRef): Boolean    begin        // Execute your logic here.    end;    procedure OnAfterProcessRecord(var RecRef: RecordRef): Boolean    begin        // Execute your logic here.    end; } ``` 1. Go to your **Record Generator** activity setup page and select the **Design** action for the linked document. 2. On the document design page, select the table node where you want to use the new record handler. ![RecordHandler](https://cdn.document360.io/da662430-6a41-47b1-8c7e-7e4ac37a9756/Images/Documentation/BIS_RecordHandlerSetup.png) ## Upgrading custom connectors The following is an example of a legacy custom connector with the `OnInsertRecord` hook: ```plaintext codeunit 50000 "DemoCustomConnector" {    procedure OnInsertRecord(var Rec: Item): Boolean    begin        // Your custom logic    end } ``` To upgrade this connector: 1. Make the custom connector implement `BISIOnInsertRecord`. 2. Implement the `OnInsertRecord(var RecRef: RecordRef)` procedure by calling the legacy `OnInsertRecord(var Rec: Item)`, or calling the default BISRecordHandler if the table is not supported by your logic: ```plaintext codeunit 50000 DemoCustomConnector implements BISIOnInsertRecord {    procedure OnInsertRecord(var RecRef: RecordRef): Boolean    var        Rec: Record Item;        Result: Boolean;    begin        if RecRef.Number() <> Database::Item then            exit(BISRecordHandler.OnInsertRecord(RecRef));        RecRef.SetTable(Rec);        Result := OnInsertRecord(Rec);        RecRef.GetTable(Rec);        exit(Result);    end;    procedure OnInsertRecord(var Rec: Item): Boolean    begin        // Your custom logic    end } ``` > [!NOTE] > **Note** > > Make sure to update `RecRef` again before exiting, using the `RecRef.GetTable` procedure. 3. Add the codeunit to an enum extension extending `BISRecordHandler`: ```plaintext enumextension 50000 "DemoRecordHandler" extends BISRecordHandler {    value(50000; DemoHandler)    {        Caption = 'Demo Record Handler';        Implementation = BISIOnBeforeProcessRecord = "BIS RecordHandler",                     BISIOnInsertRecord = DemoCustomConnector,                     BISIOnModifyRecord = "BIS RecordHandler",                     BISIOnDeleteRecord = "BIS RecordHandler",                     BISIOnAfterProcessRecord = "BIS RecordHandler";    } } ``` > [!NOTE] > **Note** > > One codeunit can implement several interfaces. [Also see the Custom Connector approach](/business-central/docs/bc-custom-connector) ## Related - [RECORDGENERATOR activity](/bc-recordgenerator-activity.md) - [Custom connector](/bc-custom-connector.md)