AL icon indicating copy to clipboard operation
AL copied to clipboard

Error AL0133 when using Variant by reference as parameter of function and passing record

Open kine opened this issue 5 years ago • 14 comments

In AL, when I define function with parameter of type variant passed by reference, I cannot call the function by passing record, because I will get error:

Argument 2: cannot convert from 'Record "tablename"' to 'var Variant'

This prevents me to do generic functions consuming any record and returning the modified record back. It was possible to use var Variant parameter in C/Side and pass record.

Create e.g. function like this: image

Try to call it with two records. You will get the error in "PROBLEMS" section of the VSCode.

Workaround: Use variant variable, assign the record, use the variant variable as parameter, assign the variable back to the record after the call. But why should I do this?

AL Language: 3.0.124247

kine avatar May 31 '19 05:05 kine

Hi, I have the same problem.

I'm trying to do a function to validate fields and log validate errors, but I don't want to pass a specific record as parameter, that's why I use a Variant as VAR parameter. This is my code:

ValidateField(rcdSalesLine, 6);

procedure ValidateField(VAR rcdTable: Variant; FieldNo: Integer)
    var
        MyRcdRef: RecordRef;
        MyFieldRef: FieldRef;        
        cuTryValidate: Codeunit 8613;
    begin
        Clear(cuTryValidate);
	Clear(MyRcdRef);
        ClearLastError();

        MyRcdRef.GetTable(rcdTable);
        MyFieldRef := MyRcdRef.Field(FieldNo);
        cuTryValidate.SetValidateParameters(MyFieldRef, MyFieldRef.Value());

        if not cuTryValidate.Run() then
            CustomLogError(GetLastErrorText());
        else
            MyRcdRef.SetTable(rcdTable);
    end;
end;

That's why I have to define my procedure as:

procedure ValidateFieldRecord37(VAR rcdSalesLine: Record 37; FieldNo: Integer)

sergiogp1 avatar Oct 16 '19 12:10 sergiogp1

Wow, did this really work in past versions of C/AL? I have run into this limitation multiple times and been frustrated by it. I didn't realise it had ever been possible. It would be great then if it could be again!

dzzzb avatar Feb 10 '21 14:02 dzzzb

Workaround: Use variant variable, assign the record, use the variant variable as parameter, assign the variable back to the record after the call.

Does this really work though? I think at best you get back any fields that were changed. But it doesn't seem to propagate any filters or other record properties that would need a var RecordType parameter. I didn't expect it to from just assignment syntax, so I'm not surprised.

If just passing the Variant directly to the function worked in past C/AL, did that honour changes made to record filter/view/whatever as if by var in such versions?

dzzzb avatar Feb 10 '21 14:02 dzzzb

I used the below extension to test whether filters propagated back through the RecordVariant := Customer; DoTest(RecordVariant); Customer := RecordVariant pattern, and it shows they do not. Changes to fields are preserved this way, but it seems nothing var is; the assignment of Customer := RecordVariant only assigns fields, as it would if the RHS were another Customer record instead of a Variant.

pageextension 50100 CustomerListExt extends "Customer List"
{
    actions
    {
        addfirst(Processing)
        {
            action(Test)
            {
                ApplicationArea = All;
                Caption = 'Filter to current';
                Image = TestFile;
                Promoted = true;
                PromotedCategory = Process;
                PromotedIsBig = true;
                PromotedOnly = true;
                ToolTip = 'Filter only to the current record.';

                trigger OnAction()
                var
                    Customer: Record Customer;
                    RecordVariant: Variant;
                begin
                    Customer := Rec;
                    RecordVariant := Customer;
                    DoTest(RecordVariant);
                    Customer := RecordVariant;
                    Message('''%1'': %2 (%3)', Customer.GetFilters(), Customer.Count(), Customer.Name);
                end;
            }
        }
    }

    local procedure DoTest(var RecordVariant: Variant)
    var
        Customer: Record Customer;
        RecordRef: RecordRef;
    begin
        RecordRef.GetTable(RecordVariant);
        RecordRef.Field(Customer.FieldNo(Name)).Value('Dennis');
        RecordRef.SetRecFilter();
        RecordRef.SetTable(RecordVariant);
    end;
}

output:

'': 6 (Dennis)

dzzzb avatar Feb 10 '21 14:02 dzzzb

Wow, did this really work in past versions of C/AL? I have run into this limitation multiple times and been frustrated by it. I didn't realise it had ever been possible. It would be great then if it could be again!

We are currently on NAV 2018 - it doesn't work here. But it seems like a no-brainer to add this. This would open up the possibility for a lot of generic functions.

What I am trying to write:

CopyToTemporaryRec(InputRecord : Variant;VAR ResultRecordTemporary : Variant)
//Takes a record with filters applied and returns a copy of the data as a temporary record
DataTypeManagement.GetRecordRef(InputRecord,InputRecRef);
CLEAR(ResultRecordTemporary);
ResultRecordTemporary.OPEN(InputRecRef.NUMBER,TRUE);

IF InputRecRef.FINDSET THEN REPEAT
  DataTypeManagement.CopyRecordRef(InputRecRef,ResultRecordTemporary);
  ResultRecordTemporary.INSERT;
UNTIL InputRecRef.NEXT = 0;

Write now I have to create a function for every Table I want to copy, something like: CopySalesLinesToTemporaryRec(InputRecord : Variant;VAR SalesLinesTemporary : Record 37)

MarvinPowell avatar Feb 16 '21 17:02 MarvinPowell

+1. Bump up.

@atoader Any plans to have this feature included in a next / not so far release?

fvet avatar Jun 18 '21 06:06 fvet

+1 would be great if we could have this for generic coding like the typical "+10000" Boilerplate-Code.

EC-Janeck avatar May 01 '22 15:05 EC-Janeck

+1 also just bumped into this issue..

AlexanderSchaetzel avatar Jan 14 '23 13:01 AlexanderSchaetzel

+1, would be great to have this feature

barud-dyna avatar Oct 23 '23 10:10 barud-dyna

+5, since it's almost five years later

DevHarmonize avatar Feb 14 '24 14:02 DevHarmonize