How to Override a Form Control's Lookup Using an Extension Class in D365 F&O

Introduction

A standard control's default lookup shows every record in the related table. Often the real requirement is narrower - show only the records valid for the current context. You can't touch the base form's control methods directly, but you can intercept the Lookup event through an extension class and hand it a filtered query instead.

Understanding the Scenario

Standard form SalesTable has a control bound to SalesTable.CustAccount. The requirement is when the lookup opens, show only customers that are not blocked, filter out any CustTable record where Blocked is not "No", instead of listing every customer in the system.


[ExtensionOf(formstr(SalesTable))]

final class SalesTable_Extension

{

    [FormControlEventHandler(formControlStr(SalesTable, SalesTable_CustAccount), FormControlEventType::Lookup)]

    public void SalesTable_CustAccount_OnLookup(FormControl sender, FormControlEventArgs e)

    {

        FormControlCancelableSuperEventArgs event = e as FormControlCancelableSuperEventArgs;

        event.CancelSuperCall();


        SysTableLookup       sysTableLookup = SysTableLookup::newParameters(tableNum(CustTable), sender);

        Query                query = new Query();

        QueryBuildDataSource queryBuildDataSource;


        queryBuildDataSource = query.addDataSource(tableNum(CustTable));

        queryBuildDataSource.addRange(fieldNum(CustTable, Blocked)).value(enum2Str(CustVendorBlocked::No));


        sysTableLookup.addLookupfield(fieldNum(CustTable, AccountNum));

        sysTableLookup.addLookupfield(fieldNum(CustTable, Name));

        sysTableLookup.parmQuery(query);

        sysTableLookup.performFormLookup();

    }

}


How the Code Works

FormControlCancelableSuperEventArgs.CancelSuperCall() is the key line, without it, the base lookup still runs after your logic, and the user sees the standard unfiltered list instead of yours.
SysTableLookup::newParameters() builds a lookup bound to the target table and the control that triggered it. A plain Query with a single range on Blocked restricts the result set to non-blocked customers, the same query-building approach used anywhere else in X++, nothing lookup-specific about it. addLookupfield() sets which columns appear in the lookup grid.

Reference - 

Customize through extension and overlayering – Microsoft Learn - https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/extensibility/customization-overlayering-extensions

Comments