Skip to main content

Notifications

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Unanswered

avoid repetitive code

(2) ShareShare
ReportReport
Posted on by 1,549
How to avoid repetitive code, i need to repeat the code if it's for salesLine or quotationLine while both have the same fields. I had to repeat logic in both methods run and initContract (the difference is only the table name)
 
is there a way to make it better?
    public void initFromArgs(Args _args)
    {
        if(_args.record())
        {
            if(_args.record().TableId == tableNum(SalesQuotationLine))
            {
                quotationLine   = _args.record();
            }
            else if(_args.record().TableId == tableNum(salesLine))
            {
                salesLine   = _args.record();
            }
            else
            {
                throw error(Error::wrongUseOfFunction(funcName()));
            }
        }
        
    }

public void run()
{
    if(quotationLine)
    {
        XContract xContract = this.initXContract(quotationLine);
        if(quotationLine.Field1)
        {
            Class1::send(quotationLine, xContract);
        }
        else
        {
            class2::send(quotationLine,xContract);
        }
    }
    else if(salesLine)
    {
        XContract xContract = this.initXContract(null, salesLine);
        if(salesLine.Field1)
        {
            Class1::send(salesLine, xContract);
        }
        else
        {
            Class2::send(salesLine, xContract);
        }
    }
   
}

public XContract initXContract(SalesQuotationLine _salesQuotationLine, SalesLine _salesLine = null)
{
    XContract xContract = new XContract();
    if(_salesQuotationLine && !_salesLine)
    {
        xContract.parmField1(_salesQuotationLine.Field1);
        xContract.parmField2(_salesQuotationLine.Field2);
        xContract.parmField3(_salesQuotationLine.Field3);
    }
    else if (_salesLine && !_salesQuotationLine)
    {
        xContract.parmField1(_salesLine.Field1);
        xContract.parmField2(_salesLine.Field2);
        xContract.parmField3(_salesLine.Field3);
    }

    return xContract;
}
 
Categories:
  • Martin Dráb Profile Picture
    233,743 Most Valuable Professional on at
    avoid repetitive code
    1. Your code is wrong indeed. Please look at code I gave you before.
    2. This code compiles without any error:
    SalesLine line;
    fieldName2Id(line.TableId, fieldStr(SalesQuotationLine, ItemId));
    Please fix your code before trying to test further changes.
    Of course, it's logically wrong and I wouldn't use that in my code, but it's still slighhtly better than just hard-coding the name.
    3. No, fieldName2Id() doesn't affect performance.
    4. You can't really extend maps, although a workaround exists in this case (Extend table maps that are used as interfaces). There is no universal answer to where you should extend an existing element (table, class, form, map...) or create a custom one. It depends on what you're doing. For example, if you want a map just for your specific scenario, you want a custom one, not to extend a map that is used for other things as well. 
  • .. Profile Picture
    1,549 on at
    avoid repetitive code
    Hi Martin,
     
     
     
    1) The errors that i got for this code, is the following:
        Common line = _salesQuotationLine ? _salesQuotationLine : _salesLine;  //this errors
    
        xContract.parmField1(fieldId2Name(line.TableId, fieldNum(line.TableId, Field1)));  //this also errors
     
           Cannot implicitly convert from type 'SalesLine' to type 'SalesQuotationLine'.  

           Table 'line.TableId' is not found.  

     
     
    2) Regarding your sentence "You could at least use fieldStr() with a name from one of the tables, a table map or so."  Do you mean, if both tables contain the same exact name, then i can use either salesline or quotationLine instead of hard-coding the field and it will still work?

    it seems it's not working for me

     

    3) does this fieldName2Id affect performance?


    4) You also mentioned table map, how to use it here? and shall i create a new map or extend SalesPurchLine map?



    4) Regarding the class design, i will investigate it and get back to you
     
     
     
     
     
  • Martin Dráb Profile Picture
    233,743 Most Valuable Professional on at
    avoid repetitive code
    Next time, please tell us what error you got, not just that you got an error.
     
    It would be something like this:
    public XContract initXContract(Common _line)
    {
        XContract contract = new XContract();
        
        contract.parmField1(_line.(fieldName2Id(_line.TableId, 'Field1'));
    
        return contract;
    }
    Of course, hard-coding field names isn't ideal, because you lose compile-time control, cross-references etc. You could at least use fieldStr() with a name from one of the tables, a table map or so.
     
    You could also design the whole thing differently, but the correct design depends on the whole scenario, which you haven't shared with us. Your current code suggests that you have a common logic where some details are specific to one of two distinct types. In object-oriented programming, this can be easily designed as a class hierarchy with two child classes. For example:
     
    public abstract class MyProcess
    {
        public void run()
        {
            if (this.shouldDoA())
            {
                this.sendA();
            }
            else
            {
                this.sendB();
            }
        }
        
        private void sendA()
        {
            ClassA::send(this.line(), this.initContract());
        }
        
        private void sendB()
        {
            ClassB::send(this.line(), this.initContract());
        }
        
        protected abstract boolean shouldDoA();
        {
        }
        
        protected abstract XContract initContract();
        {
        }
        
        protected abstract Common line()
        {
        
        }
    }
    
    public MyProcessSalesLine extends MyProcess
    {
        SalesLine salesLine;
    
        public static MyProcessSalesLine newFromRecord(SalesLine _salesLine)
        {
            MyProcessSalesLine myProcess = new MyProcessSalesLine();
            myProcess.salesLine = _salesLine;
            return myProcess;
        }
        
        protected Common line()
        {
            return salesLine;
        }
        
        protected boolean shouldDoA();
        {
            return salesLine.Field1;
        }
        
        protected XContract initContract();
        {
            return XContract::newFromSalesLine(salesLine);
        }
    }
    This is just one of many possible designs. As I said, the correct design depends on the whole scenario. There is no single design correct in all situations.
  • .. Profile Picture
    1,549 on at
    avoid repetitive code
    Hi Andre,
    • If i'm going to use a map, shall i create a new one? or use the existing SalesPurchLine map to include to it salesQuotationLine?
      Do you mean sth like this?
     
    • can you show me an example of what you suggested here "work with field numbers to retrieve the field values" where it's used with common object??
       
       Do you mean like this?
       
      ​
       
          Common line = _salesQuotationLine ? _salesQuotationLine : _salesLine;  //this errors
      
          xContract.parmField1(fieldId2Name(line.TableId, fieldNum(line.TableId, Field1)));  //this also errors
      
      ​
       
       
      but it seems the code is wrong, what shall fieldNum take instead of Line.TableId??

      and would it affect performance to keep retrieving field value from the number?
  • André Arnaud de Calavon Profile Picture
    294,941 Super User 2025 Season 1 on at
    avoid repetitive code
    Hi ..,
     
    This coding will work. In case you expect some more tables or fields you can consider using the Common object. This will add some complexity as you will need to work with field numbers to retrieve the field values. Although the field names are the same, the field numbers can be different per table.
    A table map can also be used. For both, there are a lot of examples in the standard application.

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

Announcing the Engage with the Community forum!

This forum is your space to connect, share, and grow!

🌸 Community Spring Festival 2025 Challenge Winners! 🌸

Congratulations to all our community participants!

Adis Hodzic – Community Spotlight

We are honored to recognize Adis Hodzic as our May 2025 Community…

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

#1
Martin Dráb Profile Picture

Martin Dráb 512 Most Valuable Professional

#2
Saalim Ansari Profile Picture

Saalim Ansari 315

#3
Adis Profile Picture

Adis 312 Super User 2025 Season 1

Overall leaderboard

Product updates

Dynamics 365 release plans