Business central blog
Subscribe to blog and get news about new posts.

Classic Record.Copy?

Today I want to talk about the Copy function. Specifically, about one seemingly innocent property.
From the documentation we know:
Parameter ShareTable will indicate function copy record information or create a reference to a record. It follows from the documentation, but what does it mean actually?

Let's do a little experiment.
codeunit 60019 "TestCopyReference"
{
    trigger OnRun()
    begin
        TestCopyReference();
    end;

    local procedure TestCopyReference()
    var
        Customer: Record Customer;
        CustomerTemp: Record Customer temporary;
        CustomerTemp2: Record Customer temporary;
    begin
        //Selecting Customer with specified name
        Customer.SETRANGE(Name, 'Spotsmeyer''s Furnishings');
        Customer.FINDFIRST;

        //Copy Customer to Temp1 variable and get cursor
        CustomerTemp.INIT;
        CustomerTemp := Customer;
        CustomerTemp.INSERT;

        //Copy Customer from Temp1 to Temp2 with reference
        CustomerTemp2.COPY(CustomerTemp, TRUE);

        //Modifying Customer Name in Temp1
        CustomerTemp.Name := 'Test Name';
        CustomerTemp.MODIFY;

        //Getting latest data from Temp2
        CustomerTemp2.FIND;

        //Customer Name in Temp2 will be: 'Test Name'
        MESSAGE('%1', CustomerTemp2.Name);
    end;
}
So when we do changes with Temp record it will affect linked referenced Temp2. Since in essence, we created a reference to record as described in the documentation. One must be extremely careful with SharedCopy parameter in Record.Copy function. But at the same time, this can be a useful property.

I will give an example of practical use on the example for 80 codeunit "Sales-Post". Let's look at ResetTempLines function.
local procedure ResetTempLines(var TempSalesLineLocal: Record "Sales Line" temporary)
    begin
        TempSalesLineLocal.Reset;
        TempSalesLineLocal.Copy(TempSalesLineGlobal, true);
        OnAfterResetTempLines(TempSalesLineLocal);
    end;
As we can see this function will Reset incoming parameter TempSalesLineLocal and copy the reference from TempSalesLineGlobal. Then will trigger standard event OnAfterResetTempLines with passed parameter TempSalesLineLocal.
[IntegrationEvent(false, false)]
local procedure OnAfterResetTempLines(var TempSalesLineLocal: Record "Sales Line" temporary)
    begin
    end;
This means that any actions taken to event parameter TempSalesLineLocal will affect global record TempSalesLineGlobal. That is, we have implicit access to the global variable in this event.

For me, it was useful in one project with a missing event for required modification. Most classic NAV functions contain consequences important to remember and use.
The main message of this post: The devil is in the details.

TUESDAY, FEBRUARY 25