AL
AL copied to clipboard
Error AL0133 when using Variant by reference as parameter of function and passing record
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:
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
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)
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!
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?
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)
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)
+1. Bump up.
@atoader Any plans to have this feature included in a next / not so far release?
+1 would be great if we could have this for generic coding like the typical "+10000" Boilerplate-Code.
+1 also just bumped into this issue..
+1, would be great to have this feature
+5, since it's almost five years later