Правила: события (WHEN)
Правила событий (WHEN)
-
Событие
WHENсрабатывает каждый раз, когда его условие становится истинным в текущей сессии, и записывает целевое свойство безусловно. Если то же целевое свойство также изменяется явно где-то ещё в сессии (ввод пользователя, присваивание в действии, импорт), событие перезаписывает это явное изменение. -
Когда задача события — лишь вывести или подставить значение по умолчанию из других входов, ассистенту СЛЕДУЕТ защищать условие через
AND NOT CHANGED(<целевое>)для каждого целевого свойства, в которое пишет событие.Это предотвращает затирание событием явного изменения целевого свойства, сделанного в той же сессии.
-
Защиту СЛЕДУЕТ опускать только когда событие должно принудительно перебивать любое явное изменение — например, поддерживаемые итоги, аудит-метки или инварианты, обходить которые пользователю не позволено.
-
Правила 1-3 описывают форму события-действия
WHEN <условие> DO <целевое> <- <выражение>. Форма вычисляемого события<целевое> <- <выражение> WHEN <условие>ведет себя иначе: его изменение вычисляется при обращении к целевому свойству, и явное изменение этого свойства в сессии приоритетнее изменения события.Поэтому для подстановки значения по умолчанию, уступающей явному изменению, достаточно самой формы вычисляемого события — защита не нужна. Проверять
CHANGED(<целевое>)в его условии в любом случае нельзя: целевое свойство стало бы зависеть от собственного изменения, образуя цикл<целевое>->CHANGED(<целевое>)-><целевое>.При отсутствии явного изменения событие записывает значение выражения и тогда, когда оно
NULL. -
Условие
WHENпроверяется и на удаленных объектах. Удаление объекта сбрасывает его первичные свойства вNULL, поэтому условие, реагирующее на превращение значения вNULL, выполняется для каждого удаленного объекта, у которого значение было неNULL, и обработчик отрабатывает на уже несуществующем объекте.Какие это операторы изменения, решает переход, который каждый из них покрывает:
DROPPED,CHANGED,DROPCHANGEDиSETDROPPEDвключают переход из не-NULLвNULLи потому срабатывают на удалении;SETиSETCHANGEDтребуют, чтобы новое значение было неNULL, и не срабатывают.Там, где условие может сработать на пути в
NULL, а обработчик не должен действовать на удалении или уходе объекта из класса, оно ОБЯЗАНО быть сужено через<объект> IS <Класс>.
Когда на самом деле выполняются локальные события
-
Локальный обработчик события выполняется не в момент изменения данных, а в одной из точек жизни сессии: синхронизация формы, открытие формы, начало
APPLY, создание вложенной сессии либо явный вызовSystem.executeLocalEvents[].Вне интерактивной формы — в действии, вызванном из внешней системы, в задании планировщика — из этих точек обычно случается только применение. Поэтому чтение свойства сразу после изменения данных, от которых оно зависит, вернет значение БЕЗ применения локальных обработчиков — в отличие от вычисляемого свойства, которое всегда актуально.
Ассистент НЕ ДОЛЖЕН рассчитывать в таком месте на то, что локальный обработчик отработал: либо это делает
APPLY, либо перед чтением вызываетсяSystem.executeLocalEvents[].