Pages

Saturday, March 10, 2018

Generic function for switching line numbers on records

Tried to write a generic routine for switching line numbers on records, to help with functions that move records up or down according to a line number sequence.

Comments are welcome and I'll update the post according to the bugs you can find. However I only spent 10 minutes on this and it's provided to you for free, so please bear that in mind before you send me death threats in the comments.

public static void switchLineNumbers(
    Common      _currentTopRecord,
    Common      _currentBottomRecord,
    FieldName   _lineNumberFieldName)
{
    #define.RetryNum(5)
    Common      currentTopRecordUpdate;
    Common      currentBottomRecordUpdate;
    LineNumber  topLineNumber;
    LineNumber  bottomLineNumber;
    FieldId     lineNumberFieldFieldId = fieldName2id(_currentTopRecord.TableId, _lineNumberFieldname);

    try
    {
        ttsBegin;

        // Initialize correct table id on common
        currentTopRecordUpdate = new DictTable(_currentTopRecord.TableId).makeRecord();
        currentBottomRecordUpdate  = new DictTable(_currentBottomRecord.TableId).makeRecord();

        select firstOnly forUpdate currentTopRecordUpdate
            where currentTopRecordUpdate.RecId == _currentTopRecord.RecId;

        // Make a temporary line value, in case there is a unique index with line number,
        // making a free spot to update the currect bottom record with
        topLineNumber = currentTopRecordUpdate.(lineNumberFieldFieldId);

        currentTopRecordUpdate.(lineNumberFieldFieldId) = maxInt();
        currentTopRecordUpdate.update();

        select firstOnly forUpdate currentBottomRecordUpdate
            where currentBottomRecordUpdate.RecId == _currentBottomRecord.RecId;

        bottomLineNumber = currentBottomRecordUpdate.(lineNumberFieldFieldId);

        currentBottomRecordUpdate.(lineNumberFieldFieldId) = topLineNumber;
        currentBottomRecordUpdate.update();

        currentTopRecordUpdate.(lineNumberFieldFieldId) = bottomLineNumber;
        currentTopRecordUpdate.update();

        ttsCommit;
    }

    catch (Exception::DuplicateKeyException)
    {
        if (appl.ttsLevel() == 0)
        {
            if (xSession::currentRetryCount() >= #RetryNum)
            {
                throw Exception::DuplicateKeyExceptionNotRecovered;
            }
            else
            {
                retry;
            }
        }
        else
        {
            throw Exception::DuplicateKeyException;
        }
    }
}

Use at your own risk.

1 comment:

Ievgen Miroshnikov said...

I hope you are aware of Trade*linenumber map and classes that you can find in standard AX to work with line numbers and there is a good reason to build your own ;)