Skip to main content

Does Pass by Value Work in Businesses Central AL?

 The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function cannot affect the calling function.

And it’s like that in any programing language, right? Well, no not in every case with Businesses Central AL, using a Variant Data Type and Record Ref’s have a little bug. Let’s check it out.

Let’s define a RecRef and assign it to a Sales Line table for example and create a function that accepts input parameter Passed by value of type Variant, you can also try with RecordRef.


Note that SourceRecordRef and SourceFieldRef are local Variables. Assigning Field Ref and then reusing the SourceRecordRef again to get the Customer table will change input parameter to a customer even if it is passed by value. This will happen if the input parameter is RecordRef also.

And in documentation it is stated that “If one RecordRef variable is assigned to another RecordRef variable, then they both refer to the same table instance.” But why it is changing pass as value to pass as reference?

So, the best, practice: “you should Close the record ref before changing the assignment to another table”. And if you do that the problem will be solved. Nevertheless, this does not change the fact that the Parameter pass-by-value acts like a pass-by-reference, which should never happen, in any case!

Please also note that this is an isolated example problem originated when I was using standard Codeunit Data Type Management.

It should be like this:

You can also checkout Git Repository where I played a bit to determine what is happening: SarkeSrb/RecRefBug (github.com)

Additionally, I have reported an issue to Microsoft you can track the issue on link below, until than be sure to Close RecordRef before assignment to other Record to avoid the problem.

Pass by Value becomes, Pass by Reference when using Variant or RecordRef as Parameter and make assignments to other Records · Issue #7312 · microsoft/AL (github.com)


Comments

Popular posts from this blog

3 Ways to GET a Record We all know to do a GET of one record based on values of the primary key fields. The standard syntax is as follows: [Ok :=] Record.Get(PK1[Value], PK2[Value],...). Example would be like: SalesHeaderFind.FindFirst(); SalesHeaderGet.Get(SalesHeaderFind."Document Type", SalesHeaderFind."No."); The most used one, isn’t it? What if I tell you that there is a way to make this code shorter. SalesHeaderGet.Get(SalesHeaderFind.RecordId); Yes! It will! This is because RecordID is already the primary key itself and not one of the fields that forms it, as the method expects. Also be aware that in case that the primary key field is of type RecordID you cannot use GET. In this case you will have to use the SetRange method. And the last one as of Business Central 2019 release wave 2 there is a new method, GetBySystemId. The syntax is as follows. [RecordExists := ]  Record.GetBySystemId(SystemId: Guid) Example would be like: SalesHeaderGet.GetBySystemId(Sales...

How to? Debug a live session

Did you ever encounter a situation where you cannot replicate the behavior of the bug someone reported, in a test or local environment? Microsoft just made your life a bit easier! As of version 23 access to a session in purpose of debugging is available from the web client. If you go, (screenshots below), to “Help” then “Help and Support” scrolling down a little bit to a troubleshooting tab you will see “Attach debugger to this session” this not only that will jump you to a Visual Studio Code it will also either create a new project for the purpose of debugging or if you have your project open create a launch configuration for the current session, of course after login you will be able to download symbols and attach debugger using one of the created launch configurations. Great, isn’t it? 😊

SetLoadFields, for your Consideration!

Nice little feature in AL when thinking about performance is SetLoadFields Function. It sets the fields to be initially loaded when the record is retrieved from database, meaning that for example if you do define Item.SetLoadFields(Description) only Description Field will be retrieved from the database along with the fields that always selected for loading: Primary key, SystemId, and data audit fields SystemCreatedAt, SystemCreatedBy, SystemModifiedAt, SystemModifiedBy, fields that are filtered upon, and all other fields will be unloaded.   Also, a good method to use is SetBaseLoadFields(), that will omit loading of fields that are coming from table extensions so, you have only fields that are from base table to work with, not worrying about how many extensions are installed and lowering performance of your own code for which extensions are usually irrelevant. And now comes the “Be careful” part if you in want to use “Description 2” for example in your later process you will receiv...