Skip to main content

Notifications

Community site session details

Community site session details

Session Id :
Dynamics 365 Community / Blogs / Jesús Almaraz blog / Returning a record from an ...

Returning a record from an AL function. Isn´t cool? No, it isn´t.

Jalmaraz Profile Picture Jalmaraz 669

A new from BC AL 2021 is returning some complex types from a function. Previously we already had some complex types to return Returning complex types from AL functions. - Dynamics 365 Business Central Community, but we missed classic NAV objects, records, pages, reports, etc.

In February 2021 wave of BC AL designer, we got it, we can return a complex type in a function:
  local procedure GetCustLedgerEntries(CustNo: code[20]CustLedgerEntry: Record "Cust. Ledger Entry"
    begin
        CustLedgerEntry.SetCurrentKey("Customer No.");
        CustLedgerEntry.SetRange("Customer No.", CustNo);
    end;

So, is it alright? Wait a moment!!

The problem is that you only can use once this returned object. If you want to use it in a repeating loop, you will get an infinite loop. The result of run this code calling previous function is the need of abort the process:
                    if GetCustLedgerEntries(CustNo).FindSet() then
                        repeat
                            Counter := Counter + 1;
                            if Counter mod 1000 = 0 then
                                if not Confirm('Thousand Loop %1: continue?', true, Counterthen
                                    Error('Cancelation Loop');
                        until GetCustLedgerEntries(CustNo).Next() 0;
You can think about use this function as a constructor an save it in another record object with a copy statement:
CustLedgerEntry.Copy(GetCustLedgerEntries(CustNo));
Good luck. You will get in the problems panel this error: A 'var' argument must be an assignable variable.
So, I don´t think returning an object record from a function most of times make much sense. The best option still is passing it as output parameter, a programing smell in other contexts, a real need in our developing environment:
    local procedure FilterCustLedgerEntries(CustNo: code[20]; var CustLedgerEntry: Record "Cust. Ledger Entry")
    begin
        CustLedgerEntry.SetCurrentKey("Customer No.");
        CustLedgerEntry.SetRange("Customer No.", CustNo);
    end;

With other objects, make sense

If you return another kind of object, a Page or Codeunit, make sense, because you can save full instance state in a variable setting. So, if I do this function:
    local procedure GetCustomerList() CustomerList: page "Customer List";
    begin
        CustomerList.LookupMode(true);
        CustomerList.RunModal();
    end;
And receive the object in another object this way you will get the actual page selection you made inside the function:
                    CustomerList: page "Customer List";                    
                begin
                    CustomerList := GetCustomerList();
                    CustomerList.SetSelection(Customer);
                    Message('%1'Customer.Count);
That make sense as constructor and is a better approach to OOP features.

Comments

*This post is locked for comments