Перейти к основному содержимому
Версия: 7.0

Правила: события (WHEN)

Правила событий (WHEN)

  1. Событие WHEN срабатывает каждый раз, когда его условие становится истинным в текущей сессии, и записывает целевое свойство безусловно. Если то же целевое свойство также изменяется явно где-то ещё в сессии (ввод пользователя, присваивание в действии, импорт), событие перезаписывает это явное изменение.

  2. Когда задача события — лишь вывести или подставить значение по умолчанию из других входов, ассистенту СЛЕДУЕТ защищать условие через AND NOT CHANGED(<целевое>) для каждого целевого свойства, в которое пишет событие.

    Это предотвращает затирание событием явного изменения целевого свойства, сделанного в той же сессии.

  3. Защиту СЛЕДУЕТ опускать только когда событие должно принудительно перебивать любое явное изменение — например, поддерживаемые итоги, аудит-метки или инварианты, обходить которые пользователю не позволено.

  4. Правила 1-3 описывают форму события-действия WHEN <условие> DO <целевое> <- <выражение>. Форма вычисляемого события <целевое> <- <выражение> WHEN <условие> ведет себя иначе: его изменение вычисляется при обращении к целевому свойству, и явное изменение этого свойства в сессии приоритетнее изменения события.

    Поэтому для подстановки значения по умолчанию, уступающей явному изменению, достаточно самой формы вычисляемого события — защита не нужна. Проверять CHANGED(<целевое>) в его условии в любом случае нельзя: целевое свойство стало бы зависеть от собственного изменения, образуя цикл <целевое> -> CHANGED(<целевое>) -> <целевое>.

    При отсутствии явного изменения событие записывает значение выражения и тогда, когда оно NULL.

  5. Условие WHEN проверяется и на удаленных объектах. Удаление объекта сбрасывает его первичные свойства в NULL, поэтому условие, реагирующее на превращение значения в NULL, выполняется для каждого удаленного объекта, у которого значение было не NULL, и обработчик отрабатывает на уже несуществующем объекте.

    Какие это операторы изменения, решает переход, который каждый из них покрывает: DROPPED, CHANGED, DROPCHANGED и SETDROPPED включают переход из не-NULL в NULL и потому срабатывают на удалении; SET и SETCHANGED требуют, чтобы новое значение было не NULL, и не срабатывают.

    Там, где условие может сработать на пути в NULL, а обработчик не должен действовать на удалении или уходе объекта из класса, оно ОБЯЗАНО быть сужено через <объект> IS <Класс>.

Когда на самом деле выполняются локальные события

  1. Локальный обработчик события выполняется не в момент изменения данных, а в одной из точек жизни сессии: синхронизация формы, открытие формы, начало APPLY, создание вложенной сессии либо явный вызов System.executeLocalEvents[].

    Вне интерактивной формы — в действии, вызванном из внешней системы, в задании планировщика — из этих точек обычно случается только применение. Поэтому чтение свойства сразу после изменения данных, от которых оно зависит, вернет значение БЕЗ применения локальных обработчиков — в отличие от вычисляемого свойства, которое всегда актуально.

    Ассистент НЕ ДОЛЖЕН рассчитывать в таком месте на то, что локальный обработчик отработал: либо это делает APPLY, либо перед чтением вызывается System.executeLocalEvents[].