Поля-формулы: циклическая ссылка
Формула поля может читать поля связанной записи, даже если эта запись принадлежит той же таблице. Но прочитать собственное поле в этой записи она не может: редактор формул отклоняет её с сообщением «Circular reference».
Пример
Таблица Groups содержит ссылку на саму себя — Parent: так подгруппа указывает свою группу. Поле-формула Members выбирает людей из одной страны (Country filter), а подгруппа должна выбирать своих среди участников своей группы:
let country := 'Country filter';
let candidates := if Parent then Parent.Members else select People end;
candidates[Country = country]Редактор формул отклоняет этот код: «Circular reference: Members».
Почему
Ninox рассуждает на уровне полей, а не записей. Чтобы скомпилировать формулу Members, ему нужно знать тип Parent.Members, а значит, скомпилировать формулу Members… ту самую, которую он сейчас компилирует. Неважно, что родительская запись никогда не совпадает с самой записью: зависимость отклоняется уже при компиляции.
Внимание
То же самое выражение не вызывает ошибки, когда оно вычисляется через программный интерфейс (/query) или размещено в формуле другого поля. Отклоняет его только редактор формул того поля, которое оно читает: удачная проверка в другом месте не гарантирует, что оно будет принято.
Решение: второе поле
Пусть Members вычисляет свой список, не читая родительскую группу:
let country := 'Country filter';
select People where Country = countryЗатем поручите ограничение второму полю-формуле, Effective members, которое читает Members в самой записи и в её родителе:
if Parent then
let parentMembers := Parent.Members;
Members[contains(parentMembers, this)]
else
Members
endEffective members читает Members, но Members не читает Effective members: цикла больше нет. Внутри квадратных скобок this обозначает проверяемого человека; поэтому участники родителя читаются заранее, в переменную.
Полезно знать
- Поле
Membersподгруппы теперь содержит людей, которые не являются участниками группы: всё, что показывает или использует участников (представления, кнопки, глобальные функции), должно читатьEffective members. - Цикл может проходить и через два поля:
Members, читающееParent.'Effective members', образовало бы петлюMembers→Effective members→Members. Мы не проверяли, как Ninox обрабатывает этот случай: избегайте его тем же способом.
