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, Counter) then
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.
*This post is locked for comments