0

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:

  • Sales Line 1. "No." 123
  • Sales Line 2. "No." 1234
  • Sales Line 3. "No." 12345
  • Sales Line 4. "No." 1234567

 

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.

1 Answer 1

1

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. al compiler errors in vscode

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much Christian. I appreciate your insight and showing me how you would write the code really helps me if I run into a similar situation in the future. I've marked this as the answer. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.