web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested Answer

How to make lookup code generic and not repetitive?

(1) ShareShare
ReportReport
Posted on by
Hi,
 
I have added a field on three different tables. And I want the lookup to be the same for this field in all places.
 
I had to create an initialized event handler for the three forms to registerOverride the method.
And I had to create three classes to write the lookup method for each one.
Which means two clases for each field.
This is the approach i followed and it works fine.
 
 
So the lookup code is the same for all, but the difference is the table value i take from formDataSource.cursor()
 
Is there a way to make it generic and not repetitive? Can i reduce the 6 classes?
Categories:
I have the same question (0)
  • Suggested answer
    Waed Ayyad Profile Picture
    9,039 Super User 2025 Season 2 on at
    Hi,
     
    Maybe you can create one class for the lookup and use it in all 3-event handler classes, regarding lookup fields since the 3 lookups have the same fields, maybe you can create view that has union query (of three tables) and use it the lookup method override.
     
     
    Thank,
    Waed Ayyad
    If this helped, please mark it as "Verified" for others facing the same issue
     
  • Martin Dráb Profile Picture
    237,805 Most Valuable Professional on at
    First of all, make sure you need a custom lookup at all and you can't simply get a lookup generated for you from table relations.
     
    If a custom lookup is necessary, the best approach may be creating a lookup form and associating it with the EDT used by your three fields. Then you can remove all your code. You can see an example on ItemId EDT; notice that its FormHelp property is set to InventItemIdLookupSimple.
     
    If you need code, realize that a single event handler method can be decorated with several attributes (such as FormEventHandler), therefore you can create a single class for all three events, calling the same method in the same class. Therefore you really need just a single class, not six.
     
    I don't know what you mean by "the difference is the table specified in SysTableLookup", because you said that you "want the lookup to be the same for this field in all places". If the lookup should be the same, the table specified in SysTable lookup must be the same too. If the tables are different, you'll have three different lookups, but you surely can share the common logic and use parameters for the parts that differ.
  • CU04051814-0 Profile Picture
    on at
    Hi Martin,

    I've edited the question, but maybe u didn't see it, i meant to say "but the difference is the table value i take from formDataSource.cursor()" Otherwise the code is the same

    Here's the current code for one of them
    ** please note that the view has a table inside that is shared between all companies
       public void newFieldLookup(FormStringControl _formControl)
        {
            SysTableLookup      sysTableLookup          = SysTableLookup::newParameters(tableNum(View), _formControl);
            FormRun             formRun                 = _formControl.formRun();
            FormDataSource      salesQuotationLine_ds   = formRun.dataSource(formDataSourceStr(SalesQuotationProjTable, SalesQuotationLine));
            SalesQuotationLine  salesQuotationLine      = salesQuotationLine_ds.cursor();
            Query               query                   = new Query();
    
            QueryBuildDataSource qbds = query.addDataSource(tableNum(View));
            qbds.addRange(fieldNum(View, CustomLegalEntity)).value(queryValue(salesQuotationLine.DataAreaId));
            if(salesQuotationLine.ItemId)
            {
                qbds.addRange(fieldNum(View, CustomItemId)).value(queryValue(salesQuotationLine.ItemId));
            }
            if(salesQuotationLine.AANewId)
            {
                qbds.addRange(fieldNum(View, NewId)).value(queryValue(salesQuotationLine.AANewId));
            }
     
            QueryBuildDataSource inventTableDataSource = qbds.addDataSource(tableNum(InventTable));
            inventTableDataSource.relations(false);
            inventTableDataSource.addLink(fieldNum(View, CustomItemId), fieldNum(InventTable, ItemId));
            inventTableDataSource.joinMode(JoinMode::InnerJoin);
            inventTableDataSource.addRange(fieldNum(InventTable, DataAreaId)).value(queryValue(salesQuotationLine.DataAreaId));
     
            sysTableLookup.addLookupfield(fieldNum(View, NewField));
            sysTableLookup.addLookupfield(fieldNum(View, Name));
            sysTableLookup.addLookupfield(fieldNum(View, Category));
     
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
        }
     
    }

    First question: I don't think a form would work in this case right?


    Second Question: You said that i can create one class for the three events. But isn't it a best practice to create one event handler class for each form datasource?
     
    public class SalesQuotationProjTableForm_SalesQuotationLineDSEventHandler
    {
    
        [FormDataSourceEventHandler(formDataSourceStr(SalesQuotationProjTable, SalesQuotationLine), FormDataSourceEventType::Initialized)]
        public static void SalesQuotationLine_OnInitialized(FormDataSource _sender, FormDataSourceEventArgs _e)
        {
            var overrides = SalesQuotationProjTableFormExtensionOverrides::construct();
     
            _sender.object(fieldNum(SalesQuotationLine, AANewField)).registerOverrideMethod(methodStr(FormDataObject, lookup),
                methodStr(SalesQuotationProjTableFormExtensionOverrides, newFieldLookup), overrides);
     
        }
    }

    I need the lookup code to be on formdatasource level.
  • Martin Dráb Profile Picture
    237,805 Most Valuable Professional on at
    First question: I don't think a form would work in this case right?
    Answer: Why do you think so? To me, it sounds quite simple. You would create a lookup form and just apply some ranges based on the value from args.record().
     
    Second Question: You said that i can create one class for the three events. But isn't it a best practice to create one event handler class for each form datasource?
    Answer: It's a common scenario, but I'm not aware any best practice that would prevent us from using this feature. But we do have best practices like "don't repeat yourself".
     
    You can find examples in code from Microsoft, e.g. in AssetPostingLayerExtendedEventHandler class:
    [FormDataSourceEventHandler(formDataSourceStr(LedgerJournalSetup, LedgerJournalName), FormDataSourceEventType::Activated),
     FormDataSourceEventHandler(formDataSourceStr(LedgerJournalTable, LedgerJournalTable), FormDataSourceEventType::Activated),
     FormDataSourceEventHandler(formDataSourceStr(AssetBookTable, AssetBookTable), FormDataSourceEventType::Activated),
     FormDataSourceEventHandler(formDataSourceStr(AssetAcceleratedDepDocument_JP, AssetDocumentAcceleratedDepTable_JP), FormDataSourceEventType::Activated)]
    public static void onDataSourceActivated(FormDataSource _sender, FormDataSourceEventArgs _e)
     
  • CU04051814-0 Profile Picture
    on at
    Hi Martin,

    I created a new form by duplicating "InventItemIdLookupSimple" and put my view as a datasource to it.
    I also linked my EDT to this new form.

    Now to which method I shall write the lookup code to handle the three tables by using args.record()?

    the example u sent me for ItemId uses a long class "InventItemIdLookupSimple" shall i do the same?
     
    [Form]
    public class AANewFieldLookupSimple extends FormRun
    {
        //boolean             mcrSkipInventLookupItem;
    
        void init()
        {
            if (!element.args())
            {
                throw error(strfmt("@SYS22862", element.name()));
            }
    
            super();
    
            element.selectMode(AANewFieldLookupSimpleView_NewField);
        }
    
        public void run()
        {
            FormStringControl   callerControl   = SysTableLookup::getCallerStringControl(element.args());
            boolean             filterLookup    = false;
    
            filterLookup = SysTableLookup::filterLookupPreRun(callerControl,
                                                              AANewFeildLookupSimpleView_NewField,
                                                              AANewFieldLookupSimpleView_DS);
    
            super();
    
            SysTableLookup::filterLookupPostRun(filterLookup,
                                                callerControl.text(),
                                                AANewFeildLookupSimpleView_NewField,
                                                AANewFeildLookupSimpleView_DS);
        }
    
        [DataSource]
        class AANewFieldLookupSimpleView
        {
            public void init()
            {
                super();
    
                //this.query(InventItemIdLookupSimple::queryFromArgs(element.args()));
            }
    
        }
    
    }
     
  • Martin Dráb Profile Picture
    237,805 Most Valuable Professional on at
    I don't know what logic you mean by saying "to handle the three tables", but I guess doing it in init() would make sense.
     
    No, no you don't have to create a class for the lookup form. I didn't mean that you should replicate all the complex logic of InventItemIdLookupSimple; I mentioned it just an example of a lookup form associated with an EDT.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Martin Dráb Profile Picture

Martin Dráb 664 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 522 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 303 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans