Filter operators should not be used in SetRange
Customer.SetRange(Name, 'A*') looks like it should match all customers whose name starts with A. It does not. SetRange treats every character literally — the filter matches only records where the Name field is exactly the two-character string A*.
The same applies to all filter operators: <>, .., *, &, and |. A call like SetRange("No.", '<>10000') does not filter for “not equal to 10000” — it sets an exact-match filter on the literal string <>10000. Replacement fields (%1, %2) are equally silent: SetRange does not support format strings, so SetRange(MyField, '<>%1', MyCode) uses '<>%1' as the FromValue and MyCode as the ToValue — a meaningless range between two unrelated values.
Use SetFilter whenever the expression contains operators or replacement fields.
Example
procedure FindCustomers()
var
Customer: Record Customer;
begin
Customer.SetRange(Name, 'A*'); // Filter operators should not be used in SetRange [PC0003]
Customer.FindSet();
end;Use SetFilter to apply filter expressions with operators.
procedure FindCustomers()
var
Customer: Record Customer;
begin
Customer.SetFilter(Name, 'A*');
Customer.FindSet();
end;When replacement fields are involved, move the full expression to SetFilter:
procedure FindItems(CategoryFilter: Code[20])
var
Item: Record Item;
begin
Item.SetFilter("Item Category Code", '<>%1', CategoryFilter);
Item.FindSet();
end;Code fix
The code fix replaces SetRange with SetFilter.
See also
- Filtering records with SetRange, SetFilter, GetRangeMin, and GetRangeMax on Microsoft Learn
- Record.SetRange Method on Microsoft Learn