Another form trick, copy-down in grids

A function I have often been asked for, but which does not exist in standard Dynamics AX 2012 is copy-down, or the ability to press a key on the keyboard to copy values into the currently selected field from the row immediately above it.  In my implementation, I have chosen the F11 key, as it was not used for anything else.

The function will be available on all grid-based forms, even in the table browser.

To implement this, modify the SysSetupFormRun class to add a new methods called EB_copyDown.  (As usual, the prefix is up to you and the naming conventions you follow)

// EB 11/03/2016: Enable copy-down on F11 key
private void EB_copyDown( FormDataSource _fds, FieldId _fieldId )
{
  Common prevRecord = _fds.cursor( _fds.getPosition() - 1 );
  Common common = _fds.cursor();

  common.( _fieldId ) = prevRecord.( _fieldId );
}

This sets prevRecord to the record immediately above the current record, by subtracting one from the value returned by getPosition(), and sets common to the current record.  Next, it just copies the requested field from one record to the other.  (This is an example of late-binding fields, or dynamic binding.)

In order for this to work, I’ll need to modify the task() method as well.
I start by adding a number of local variables I’ll need.

 // EB 11/03/2016: Enable copy-down on F11 key ==>
 FieldBinding binding;
 FormDataSource fds;
 FormControl ctrl;
 FieldId fieldId;
 container dependentFields;
 int i;
 Object fds_Object;
 FormDataObject o;
 // EB 11/03/2016: Enable copy-down on F11 key <==

Then we add an else-if branch to the if-statement.

// EB 11/03/2016: Enable copy-down on F11 key ==>
else if( _p1 == 357 ) // F11
{
  ctrl = this.selectedControl();
  if( ( ctrl != null ) && ctrl.enabled() && ctrl.allowEdit() )
  {
    binding = ctrl.fieldBinding();
    fieldId = binding.fieldId();
    fds = ctrl.dataSourceObject();

    if( fds.getPosition() > 1 )
    {
      this.lock();
      o = fds.object( fieldId );
      if( o.allowEdit() )
      {
        fds_Object = fds as Object;
        this.EB_copyDown( fds, fieldId );
        if( formDataSourceHasMethod( fds, identifierStr( EB_dependentFields ) ) )
        {
          dependentFields = fds_Object.EB_dependentFields( fieldId );
        }
        for( i = 1; i <= conlen( dependentFields ); i++ )
        {
          this.EB_copyDown( fds, conPeek( dependentFields, i ) );
        }

        o.modified();
        for( i = 1; i <= conlen( dependentFields ); i++ )
        {
          o = fds.object( fieldId );
          o.modified();
        }
      }
      this.unLock();
      fds.refresh();
    }
    else
    {
      warning( "Not copying down. You had to try, didn't you?" );
    }
  }
}
// EB 11/03/2016: Enable copy-down on F11 key <==

I’m checking to make sure that the user is not on the first row in the grid.  If he/she is, I show a suitable message.  Of course, sensibilities and political correctness may mandate that you don’t show what I did.  I will not be held responsible for any consequences if you do…

Some fields will depend on others.  An example may be a subcategory, which depends on a major category.  When copying the subcategory, it would be useful to also copy the major category, so I have added support for also copying such dependent fields.  To do this, add a form-level method to the relevant form(s).  The method should be called EB_dependentFields and take a fieldId as single parameter.  It will return a container filled with the fieldIds of all other fields that also need to be copied.  You can change the name of the method to suit whatever naming convention you follow, just make sure that the method is public and follows the API described here.  Also, make sure the code above is updated to match the method name you choose.

As usual, an XPO containing these changes are available here: Class_SysSetupFormRun (2).zip

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.