Van Vugt's dynamiXs

All around NAV dev and test

FILTERGROUP(-1)

Even though many of us are experienced developers, the FILTERGROUP record function isn't for each of us a well-known or understood concept. Because of this very reason the following question has been for years part of the quiz I start a course day with.

So get ready …

The default lookup page for MyTable is run by the following C/AL code:

MyTable.FILTERGROUP(2);
MyTable.SETFILTER("No.",’1000..5000’);
MyTable.FILTERGROUP(0);
PAGE.RUN(0,MyTable);

When the page is displayed, the user applies the table filter 6000..6500. Which records will then be shown?

a. No records because the filter will read: (1000..5000)&(6000..6500)
b. Records in the range 1000..5000 because the program ignores the filter applied by the user
c. Records in the range 1000..6500 because the filter will read (1000..6500)
d. Records in the range 6000..6500 because the filter applied by the user overrides the SETFILTER call

"OK ... a, b, c, or d?" ...

... I did ask the 13 Slovenian developers I was giving a NAV 2015 update course to the last couple of days. And yes, some knew, but most had a hard time with it.

Triggered by this question and the discussion following it, one of the attendants, Darko Grasic (he earns the credits), consulted the msdn help on FILTERGROUP and asked me about FILTERGROUP(-1).

FILTERGROUP(-1)?

Yep, FILTERGROUP(-1). Follow the link and see. Or just try the following code:

WITH Customer DO BEGIN
  FILTERGROUP(-1);
  SearchString := '@*ou*';
  SETFILTER(Name, SearchString);
  SETFILTER(Contact, SearchString);
  SETFILTER(City, SearchString);
  IF FINDSET THEN
    REPEAT
     MESSAGE(
       'Customer filtered on %1\  %2\  %3\  %4\  %5',
        SearchString,
       "No.",
       Name,
       Contact,
       City);
    UNTIL NEXT = 0;
END

Rewriting the code somewhat so it opens a page the result looks like this (including my former MS colleague Hervé):

You get it?

So with FILTERGROUP(-1) we now have and OR filter that can spread several columns! Wow.

Two things to note

  • running the page the filter didn't work straight forward. Had to mark the records to be able to show the result set in the page:

     

    WITH Customer DO BEGIN
      FILTERGROUP(-1);
      SearchString := '@*ou*';
      SETFILTER(Name, SearchString);
      SETFILTER(Contact, SearchString);
      SETFILTER(City, SearchString);
      IF FINDSET THEN
        REPEAT
         MARK(TRUE);
        UNTIL NEXT = 0;
      FILTERGROUP(0);
      MARKEDONLY(TRUE);
      PAGE.RUN(0,Customer)
    END
  •  

  • Not sure whether a balancing call FILTERGROUP(0) is needed as the filter doesn't show in the UI