For some background, I'm a junior Business Central AL developer with not much experience. I am hoping to find some help with the syntax of what I'm trying to accomplish.
Situation:
I have several Sales Lines displaying in a Sales Order. I want to increase the width of the Sales Line "No." field based on the longest "No." value.
Example:
Sales Order abc123 has four Sales Line entries:
Desired outcome of example:
The "No." column of the Sales Line to have its width property set to the length of the longest "Sales Line"."No.". In this example, the width property would be set to 7 (Longest sales line is #4, with a length of 7).
What I have so far:
I have the following psuedo(ish)code and I'm not really sure how to put it into practice. The specific part I'm struggling with is inserting each "Sales Line"."No." length ("No.".StrLen(String: Text)
) into the array (SalesLineNumbers
), and then finding the largest integer in the array.
modify("No.") {
trigger OnAfterValidate();
var
SalesLineNumbers: array of Integer;
MaxSalesLineNumberLen: Integer;
begin
"Sales Header".Get(abc123); //find the sales header we are working with
foreach "Sales Line"."No." in "Sales Header": //perform the following actions for each sales line within this sales header
insert into SalesLineNumbers "No.".StrLen(String: Text); //add the length of the "Sales Line"."No." into the array
MaxSalesLineNumberLen := max(value in SalesLineNumbers); //set MaxSalesLineNumberLen to the largest integer in the array
end;
Width = MaxPartNoLen; //set the width property of field "No." to MaxPartNoLen
}
If there is any more information you need me to provide, or if I'm not clear in what I'm trying to accomplish, please let me know.
Thank you in advance for reading.
first of all I like the format of your question:: Situation, Example, Desired outcome and What I have so far. Awesome, keep it up!
I get two compiler errors saying that I can't use a variable and therefore have to use an integer literal.
The code for determining the longest number would look similar to this:
var
SalesLine: Record "Sales Line";
MaxLength: Integer;
begin
MaxLength := 0;
SalesLine.SetRange("Document Type", Rec."Document Type");
SalesLine.SetRange("Document No.", Rec."Document No.");
if SalesLine.FindSet() then
repeat
if MaxStrLen(SalesLine."No.") > MaxLength then
MaxLength := StrLen(SalesLine."No.");
until SalesLine.Next() = 0;
Message(Format(MaxLength));
end;
Unfortunately, as already mentioned, we cannot use this variable for the width property.
If the number is really so important that it needs to be displayed in full length, set the width to 20. Keep in mind that Users can override the width by personalizing the page that displays the field. Read more about the Width property: https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/properties/devenv-width-property
Transfering the pseudo(ish)code into AL, I would use a list instead of an array, and the code could look like this, for example:
var
SalesHeader: Record "Sales Header";
SalesLine: Record "Sales Line";
SalesLineNumbers: List of [Integer];
MaxSalesLineNumberLen: Integer;
Index: Integer;
begin
SalesHeader.Get(Enum::"Sales Document Type"::Order, 'S-ORD101009'); //find the sales header we are working with
SalesLine.SetRange("Document Type", SalesHeader."Document Type");
SalesLine.SetRange("Document No.", SalesHeader."No.");
if SalesLine.FindSet() then //perform the following actions for each sales line within this sales header
repeat
SalesLineNumbers.Add(StrLen(SalesLine."No.")); //add the length of the "Sales Line"."No." into the list
until SalesLine.Next() = 0;
// loop through the list to find the largest value
for Index := 1 to SalesLineNumbers.Count() do begin
if SalesLineNumbers.Get(Index) > MaxSalesLineNumberLen then
MaxSalesLineNumberLen := SalesLineNumbers.Get(Index); //set MaxSalesLineNumberLen to the largest integer in the list
end;
end;
Please feel free to ask, if you have any further questions.