Add elements to array in a loop.

mysamzamysamza Member Posts: 62
edited 2019-08-17 in NAV Three Tier
On an Item Card Page, there is a selection of Item Category which has a Code field.
I want to print that value for each of the Items selected in the Sales Quote page (Subform, line items area)
So in Sales Quote I have selected 2 items;
1) Front Hub
2) Bicycle
and these two items have a Item Category Code set (lets say Chair, Desk respectively) in their Item Card Page. I will print Chair / Desk in the report of Sales Quote.
I am approaching this be first finding Item Category Codes for the Line Items and then putting them in an array, then I will compare and move distinct ones (reason for finding distinct is if 2 items have same Item Category Codes I have to print that Code ONLY once, so if 3 Line Items have Desk, Desk, Chair, I will print on the report Desk / Chair) into another array then concatenate the values with ' / ' into a Text Variable.
Here is what I have done so far but got stuck in getting right values into my array.

On the OnAfterGetRecord Trigger of my Sales Quote Report
I have written;
ItemCateTableRec.SetFilter(Code, "Sales Line"."Item Category Code");
IF ItemCateTableRec.FindSet then begin
myArray [ i ] := ItemCateTableRec.Code;
i := i + 1;
until ItemCateTableRec.Next = 0;
upon printing the myArray[1] and [2] I do not get the correct Item Category Code Chair or my Item FrontHub and Desk for my Item Bicycle. I get incorrect values.

Thanks a ton in advance for any guidance.


  • JuhlJuhl Member Posts: 728
    Follow me on my blog
  • ResolusResolus Member Posts: 17
    edited 2019-08-18
    I agree that it would be easy with .NET, but the problem here isn't that big or complex that it would be justified in my opinion. It's easily fixable in C/AL (or AL) without a problem by using a temp table as mentioned.
    ItemCateTableRec.SETRANGE(Code, "Sales Line"."Item Category Code");
    	TempItemCateTableRec.SETRANGE(Code, ItemCateTableRec.Code);
    		TempItemCateTableRec := ItemCateTableRec;
    UNTIL ItemCateTableRec.NEXT = 0;

    I use .NET quite often and I know I shouldn't (e.g. creating an image file from BASE64 sent in Json to save on the drive). It's very powerful and can do way more than C/AL (or AL), but since it's not supported in BC it's best to avoid it unless you have no other choice. Otherwise it'll have to be upgraded later when you move to BC in the cloud.

  • ShaiHuludShaiHulud Member Posts: 172
    edited 2019-08-19
    It may be that you wrote your code in the wrong trigger. It's not clear under which DataItem you wrote it, but it should be under "Sales Line - OnAfterGetRecord()". If that's not it, then you might want to try out something simpler:
    IF ItemCatTableRec.GET("Sales Line"."Item Category Code") THEN BEGIN //because Item Category table has only field "Code" as primary key
      IF TempItemCateTableRec.INSERT(FALSE) THEN; //If it doesn't exist yet, it will get inserted
    //[..] somewhere later, after you've gone through all the categories
    CategoriesText = '';
    IF TempItemCateTableRec.FINDSET THEN BEGIN
        IF CategoriesText <> '' THEN
          CategoriesText += ' / '; //don't need to add slash before the first category
        CategoriesText += TempItemCateTableRec.Code;
      UNTIL TempItemCateTableRec.NEXT = 0;

    If you really want to use arrays, I'd start somewhat differently. First take all the required Sales Lines separately, sort them by Item Category Code, then loop through all of them and if the Item Category Code of the current line is different from the ICC from previous line (stored in a code type variable with default value of blank), then add it to your array. Something like:
    SalesLine.SETCURRENTKEY("Item Category Code");
    SalesLine.SETFILTER("Item Category Code", '<>%1', ''); //not interested in blank categories and lines that are NOT Items (they won't have Item Category Code)
    PreviousCatCode = ''; //variable of type code[10]
    i := 0; //variable of type int
        IF SalesLine."Item Category Code" <> PreviousCatCode THEN BEGIN
          i += 1;
          myArray[i] := SalesLine."Item Category Code";
          PreviousCatCode := SalesLine."Item Category Code";
      UNTIL SalesLine.NEXT = 0;
    After this, you'll have your myArray and i to show its size
  • mysamzamysamza Member Posts: 62
    Hello commenters,

    I found a way before I received comments here and this is how I solved but now stuck in printing the variable.

    Here is what I did;

    trigger OnPostDataItem()

    sourcei: Integer;
    filteredi: Integer;
    intcount: Integer;
    sourcelistcount: Integer;
    filteredlistcount: Integer;
    temp: Text[100];
    sourcei := 1;
    filteredi := 1;
    intcount := 1;
    sourcelistcount := sourcelist.Count();
    filteredlistcount := filteredlist.Count();
    filteredlist.Insert(filteredi, sourcelist.Get(sourcei));
    sourcei := sourcei + 1;

    for intcount := 1 to sourcelistcount do begin
    IF (sourcelist.Get(sourcei) <> filteredlist.get(filteredi)) then begin
    filteredi := filteredi + 1;
    filteredlist.Insert(filteredi, sourcelist.Get(sourcei));

    sourcei := sourcei + 1;



    filteredi := 1;

    intcount := 1;

    foreach temp in filteredlist do

    FilteredIC := FilteredIC + ' / ' + temp;

    ItemCategoryCombined := DelStr(FilteredIC, 1, 3);



    I get precisely what I want to print in the variable ItemCategoryCombined.

    However, my Sales Quote report has 2 dataitems at this point, Sales Header and Sales Line. Adding the Column(ItemCategoryCombined; ItemCategoryCombined) in Sales Line doesn't print the value of ItemCategoryCombined in the report (rdl).

    Any hint what am I missing?

    Thanks in advance.
  • ResolusResolus Member Posts: 17
    Well, you're working in the "OnPostDataItem" trigger. That means all the information for that dataitem has already been processed.

    Try putting your code in the "OnAfterGetRecord" trigger?

Sign In or Register to comment.