Skip to main content

Notifications

Copy records between two different tables having same fields in D365FO using X++

Bharani Preetham Peraka Profile Picture Bharani Preetham Pe... 3,487 Super User

What is this copying of record from table to another which I am talking about? Where this is used? This can be simply achieved by assigning value right? But why this generic method? 

To answer all these questions, lets read this :)

 

Lets says we need to insert or update the data from one table to another table where the two tables are completely different tables. Ideally we will just assign each and every field value from source to target. But lets say we have many fields. Like we cant just assign each and every field with those many fields and we have to use this in multiple places in the code. Then in general we will use buf2buf or data() methods to perform this activity.
 
But I have a different requirement where I need to copy all data from one table to another having same fields but 2 different tables.
 
This particular scenario exists when you have some log table or else some custom workflow related tables.
 
To accomplish this task what I did is I customized the standard as per my requirement so this can now work with 2 different tables. Basically the buf2buf requires same table as the source and target. But here I made this work with 2 different tables using DictTable.
 
private void insertOrUpdateData(Common _source, Common _target)
{
	var         dictTable           = new DictTable(_source.TableId);
    DictTable   dicttableTarget     = new DictTable(_target.TableId);
    FieldId     fieldId             = dictTable.fieldNext(0);

    while (fieldId && ! isSysId(fieldId))
    {
        FieldId     fieldIdTarget;

        fieldIdTarget               = dicttableTarget.fieldName2Id(dictTable.fieldObject(fieldId).name());

        if (fieldIdTarget)
        {
            _target.(fieldIdTarget)     = _source.(fieldId);
        }
        else
        {
            fieldId                     = dictTable.fieldNext(fieldId);
            continue;
        }
        fieldId                     = dictTable.fieldNext(fieldId);
    }
}
 
This method can be called while insert or update and it needs the source and target tables to be passed as parameters.
 
Lets say may be you do not want to copy some field. So you can simply say the system not do copy for this field by below.
 
FieldId  fieldId     = dictTable.fieldNext(0);
const str Party      = "Party";

boolean ignoreThisField = dictTable.fieldObject(fieldId).name() != Party;
Here we are checking the field name using fieldId and saying the system if to include it or no.
 
The reason why we has this line of code, isSysId(fieldId) is this will skip the standard fields like RecId, RecVersion.
 
This method can be called while insert or update and after that based on process need to call the insert() or update() method something like below.
 
TableNameSource tableNameSource;

TableNameTarget tableNameTarget;


//insert();

//call the method and pass arguments
if (tableNameTarget.validatewrite())
{
      tableNameTarget.insert();
}



//update
//selecting which record to update
if (tableNameTarget)
{
       tableNameTarget.selectforupdate(true);
       //call method and pass arguments

       if (tableNameTarget.validatewrite())
       {
           ttsbegin;
           tableNameTarget.update();
           ttscommit;
       }
}
 
 
With this approach data can be copied between 2 different tables having same Field names.

Comments