Book Image

Microsoft Dynamics AX 2012 R3 Development Cookbook

By : Mindaugas Pocius
Book Image

Microsoft Dynamics AX 2012 R3 Development Cookbook

By: Mindaugas Pocius

Overview of this book

<p>Microsoft Dynamics AX 2012 R3 Development Cookbook will help you manage your company's or customer's ERP information and operations efficiently. Beginning with exploring data manipulation concepts in Dynamics AX, you will build scripts to assist data migration and organize data in AX forms. You will learn how to create custom lookups using AOT forms and generate them dynamically. After this, you'll learn how to enhance your application by using advanced form controls, and integrate your system with other external systems. You will also learn how to enhance your user interface using various Dynamics AX UI elements.</p> <p>This book will help you look at application development from a business process perspective, and develop enhanced ERP solutions by learning and implementing the best practices and techniques.</p>
Table of Contents (16 chapters)
Microsoft Dynamics AX 2012 R3 Development Cookbook
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Copying a record


Copying existing data is one of the data manipulation tasks in Dynamics AX. There are numerous places in the standard Dynamics AX application where users can create new data entries just by copying existing data and then modifying it. A few examples are the Copy button on the Costing versions form located in Inventory management | Setup | Costing and the Copy project button on the All projects list page located in Project management and accounting | Common | Projects. Also, although the mentioned copying functionality might not be that straightforward, the idea is clear: the existing data is reused while creating new entries.

In this recipe, we will learn two ways to copy records in X++. We will discuss the usage of the table's data() method, the global buf2buf() function, and their differences. As an example, we will copy one of the existing main account records into a new record.

How to do it...

Carry out the following steps in order to complete this recipe:

  1. Navigate to General ledger | Common | Main accounts and find the account to be copied. In this example, we will use 130100, as shown here:

  2. Open the AOT, create a new job named MainAccountCopy with the following code snippet, and run it:

    static void MainAccountCopy(Args _args)
    {
        MainAccount mainAccount1;
        MainAccount mainAccount2;
    
        mainAccount1 = MainAccount::findByMainAccountId( '130100');
    
        ttsBegin;
    
        mainAccount2.data(mainAccount1);
    
        mainAccount2.MainAccountId = '130101';
        mainAccount2.Name += ' - copy';
    
        if (!mainAccount2.validateWrite())
        {
            throw Exception::Error;
        }
    
        mainAccount2.insert();
    
        ttsCommit;
    }
  3. Navigate to General ledger | Common | Main accounts again and notice that there are two identical records now, as shown in the following screenshot:

How it works...

In this recipe, we have two variables: mainAccount1 for the original record and mainAccount2 for the new record. First, we find the original record by calling findMainAccountId() in the MainAccount table.

Next, we copy the original record into the new one. Here, we use the table's data() method, which copies all the data fields from one variable into another.

After that, we set a new main account number, which is a part of the table's unique index.

Finally, we call insert() on the table if validateWrite() is successful. In this way, we create a new main account record that is exactly the same as the existing one apart from the account number.

There's more...

As we saw before, the data() method copies all the table fields, including the system fields such as the record ID or company account. Most of the time it is OK because when the new record is saved, the system fields are overwritten with the new values. However, this function may not work for copying records across companies. In this case, we can use another function called buf2Buf(). This function is a global function and is located in the Global class, which you can find by navigating to AOT | Classes. The buf2Buf() function is very similar to the table's data() method with one major difference. The buf2Buf() function copies all the data fields excluding the system fields. The code in the function is as follows:

static void buf2Buf(
    Common _from,
    Common _to,
    TableScope _scope = TableScope::CurrentTableOnly)
{
    DictTable   dictTable = new DictTable(_from.TableId);
    FieldId     fieldId   = dictTable.fieldNext(0, _scope);

    while (fieldId && ! isSysId(fieldId))
    {
        _to.(fieldId)   = _from.(fieldId);
        fieldId         = dictTable.fieldNext(fieldId, _scope);
    }
}

We can clearly see that during the copying process, all the table fields are traversed, but the system fields, such as RecId or dataAreaId, are excluded. The isSysId() helper function is used for this purpose.

In order to use the buf2Buf() function, the code of the MainAccountCopy job can be amended as follows:

static void MainAccountCopy(Args _args)
{
    MainAccount mainAccount1;
    MainAccount mainAccount2;

    mainAccount1 = MainAccount::findByMainAccountId('130100');

    ttsBegin;

    buf2Buf(mainAccount1, mainAccount2);

    mainAccount2.MainAccountId = '130101';
    mainAccount2.Name += ' - copy';

    if (!mainAccount2.validateWrite())
    {
        throw Exception::Error;
    }

    mainAccount2.insert();

    ttsCommit;
}