Обработчик события ОбработкаПроверкиЗаполнения

#std463

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

1.1. В данном обработчике модуля объекта выполняются действия, связанные с проверкой правильности заполнения значений реквизитов объектов (измерений, ресурсов, реквизитов табличных частей и т.п., далее: просто "реквизиты").

См. также Подсказка и проверка заполнения 

1.2. Данным обработчиком следует пользоваться в случаях, когда для проверки корректности значений реквизитов обычной проверки на заполненность уже недостаточно (например, значение реквизита логически связано со значением другого реквизита), или же требование к тому, чтобы значение реквизита было заполнено не является безусловным.

Если проверка заполнения какого-либо реквизита - условная (т.е. зависит от значений других реквизитов или значения параметризированной функциональной опции) в обработчике следует предусмотреть код, который удаляет имя такого реквизита из массива проверяемых реквизитов ПроверяемыеРеквизиты. В общем виде, схема проверки заполнения выглядит следующим образом:

При этом не рекомендуется использовать другие схемы проверки заполнения значений реквизитов, так как они затрудняют анализ логики работы конфигурации, поскольку скрывают из свойства "Проверка заполнения" случаи условной проверки заполнения значений объектов.
Например, неправильно:

Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

  ...

  // Проверка значения реквизита на соответствие некоторым требованиям
  Если НЕ ИННСоответствуетТребованиям(ИНН) Тогда
    Сообщение = Новый СообщениеПользователю();
    Сообщение.Текст = НСтр("ru = 'ИНН задан неверно.'");
    Сообщение.Поле = "ИНН";
    Сообщение.УстановитьДанные(ЭтотОбъект);
    Сообщение.Сообщить();
    Отказ = Истина;
  КонецЕсли;

  ...

  // Значение реквизита не должно быть пустым в зависимости от значения другого реквизита
  Если ЮрФизЛицо = Перечисления.ЮрФизЛицо.ФизЛицо Тогда
    // Для индивидуального предпринимателя должно быть сопоставлено физ. лицо
    ПроверяемыеРеквизиты.Добавить("ИндивидуальныйПредприниматель");
  КонецЕсли;

  ...

КонецПроцедуры

правильно:

Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) 

  НепроверяемыеРеквизиты = Новый Массив();
  ...

  // Проверка значения реквизита на соответствие некоторым требованиям
  Если НЕ ИННСоответствуетТребованиям(ИНН) Тогда
    Сообщение = Новый СообщениеПользователю();
    Сообщение.Текст = НСтр("ru = 'ИНН задан неверно.'");
    Сообщение.Поле = "ИНН";
    Сообщение.УстановитьДанные(ЭтотОбъект);
    Сообщение.Сообщить();
    Отказ = Истина; 
    НепроверяемыеРеквизиты.Добавить("ИНН"); 
  КонецЕсли;

  ...
  // Значение реквизита не должно быть пустым в зависимости от другого реквизита
  Если ЮрФизЛицо <> Перечисления.ЮрФизЛицо.ФизЛицо Тогда  
    НепроверяемыеРеквизиты.Добавить("ИндивидуальныйПредприниматель");
  КонецЕсли;

  ...
  УдалитьНепроверяемыеРеквизитыИзМассива(ПроверяемыеРеквизиты, НепроверяемыеРеквизиты);
КонецПроцедуры;

Процедура УдалитьНепроверяемыеРеквизитыИзМассива(МассивРеквизитов, МассивНепроверяемыхРеквизитов) Экспорт

  Для Каждого ЭлементМассива Из МассивНепроверяемыхРеквизитов Цикл
 
    // перед удалением реквизита из массива необходимо проверить, что он там есть
    // (не был удален ранее платформой или в коде).
    ПорядковыйНомер = МассивРеквизитов.Найти(ЭлементМассива);
    Если ПорядковыйНомер <> Неопределено Тогда
      МассивРеквизитов.Удалить(ПорядковыйНомер);
    КонецЕсли;
 
  КонецЦикла;
 
КонецПроцедуры

1.3. Следует учитывать, что обработчик ОбработкаПроверкиЗаполнения вызывается не при каждой записи объекта, в частности, он не вызывается в случаях если запись были инициирована программно.

Методическая рекомендация (полезный совет)

1.4. В случае использования в конфигурации подсистемы "Обмен данными" Библиотеки стандартных подсистем обработчик ОбработкаПроверкиЗаполнения вызывается при проведении документов, после их загрузки из сообщения обмена. Для отключения некоторых проверок в этом режиме в обработчике можно анализировать дополнительное свойство объекта ДополнительныеСвойства.ОтложенноеПроведение.

Проверки, выполняемые в и вне транзакции записи объекта

2.1. Проверки в обработчике ОбработкаПроверкиЗаполнения выполняются вне транзакции записи объекта. Поскольку в случае некорректного заполнения объекта выполнение операции будет прервано еще до записи объекта в базу данных, то размещение проверок в этом обработчике является наиболее эффективным.

При выполнении внетранзакционных проверок в обработчике ОбработкаПроверкиЗаполнения необходимо учитывать тот факт, что новое состояние объекта еще не записано. Если требуется выполнить запрос к тем или иным данным системы, например, прочитать признак ВидНоменклатуры для товаров, выбранных в табличной части документа, "отталкиваясь" от данных документа, то такую поверку можно выполнить, применяя сохранение необходимых для запроса данных во временные таблицы.

2.2. В то же время, в обработчике ОбработкаПроверкиЗаполнения не следует размещать проверки, которые должны гарантировать целостное состояние объекта или зависящих от него данных (например, движений) на которые рассчитывает система. Поэтому для реквизитов, некорректные значения которых могут привести к рассогласованности данных в информационной базе, проверку корректности следует выполнять в обработчиках событий, возникающих в транзакции записи - ПередЗаписью, ПриЗаписи, ОбработкаПроведения (для документов).

Для транзакционных проверок, в свою очередь, выделяются два случая:

  1. Проверка состояния движений, формируемых документами оперативного учета. Такие проверки довольно часто встречаются в приложениях с оперативным учетом. 
  2. Проверка состояния других объектов информационной базы, ссылки на которых содержатся в текущем объекте. Такие проверки следует применять очень редко. Не следует злоупотреблять количеством проверок в транзакции записи объекта. Следует помнить, что внутри транзакции записи имеет смысл выполнять только проверки таких ресурсов или таких правил соответствия объектов друг другу, которые не изменяются без проверок всеми участниками процесса.

В первом случае, проверку остатков некоторого ресурса имеет смысл выполнять в транзакции записи только в том случае, если все документы выполняют такую же проверку в транзакции записи. Если хоть один из документов, изменяющих ресурс, делает это без проверок, выполнение проверок другими участниками процесса бессмысленно и такие проверки необходимо выполнять вне транзакции. Исключением может быть только случай, когда документ, который выполняет изменение контролируемого ресурса без проверок, вводится крайне редко. Например, не смотря на то, что документ "Инвентаризация товаров" изменяет остатки товаров без проверок, эта ситуация допустима в виду того, что он вводится крайне редко. Каждое такое исключение из правила должно быть оправданным.

Во втором случае, если при записи Подразделения в транзакции записи выполняется проверка, что сотрудник, выбранный в качестве руководителя подразделения, имеет должность "Руководитель", то при записи Сотрудника также должна выполняться и "встречная" проверка этого же правила: нельзя записать Сотрудника с должностью отличной от "Руководитель", если он указан руководителем того или иного подразделения. Поскольку правило, что "Сотрудник", выбранный руководителем подразделения, должен иметь должность "Руководитель", может быть нарушено как при записи подразделения, так и при записи сотрудника, то и проверка должна выполняться или в транзакции записи обоих объектов, или вне транзакции записи обоих объектов (а может и не выполняться вообще).