К статье
Практический материал

Разработка и Конфигурация · 11 мин

ОбработкаПроверкиЗаполнения в 1С: когда вызывается и как использовать

Разбираем, когда вызывается обработчик ОбработкаПроверкиЗаполнения в 1С, порядок проверки реквизитов, типичные ошибки разработчиков и примеры кода.

ОбработкаПроверкиЗаполнения — это событие модуля объекта (справочника, документа, плана счетов и других прикладных объектов), которое платформа 1С вызывает автоматически при записи объекта в базу данных. Его назначение — проверить, что обязательные реквизиты заполнены, а значения не противоречат бизнес-логике, и при необходимости отказать в записи.

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

Ниже разобраны все случаи вызова обработчика, порядок стандартных и пользовательских проверок, работа с параметром ПроверяемыеРеквизиты, типичные ошибки и готовые примеры кода.

В какие моменты платформа вызывает обработчик

Событие ОбработкаПроверкиЗаполнения возникает всякий раз, когда выполняется запись объекта, у которого в свойствах включена проверка заполнения. Это происходит в двух основных сценариях: интерактивная запись (пользователь нажимает «Записать» или «Провести» в форме) и программная запись через метод Записать() в коде.

Важный нюанс: при проведении документа проверка заполнения тоже выполняется, потому что проведение — это частный случай записи с режимом Проведение. Если документ записывается в режиме простой записи (без проведения), обработчик также вызывается. А вот при отмене проведения проверка заполнения по умолчанию не выполняется, поскольку данные не изменяются осмысленным образом.

Событие не вызывается при работе с набором записей регистра напрямую, если у регистра не определены собственные правила проверки, и не срабатывает при использовании методов, записывающих данные в обход объектной модели (например, прямые запросы изменения — что в 1С в принципе не применяется штатно). Также проверка не выполняется, если объект записывается с установленным признаком ОбменДанными.Загрузка = Истина — это стандартный механизм обхода проверок при загрузке данных из обменов.

Порядок событий при записи объекта

Чтобы правильно размещать логику, нужно знать последовательность событий. При записи объекта платформа выполняет цепочку: ПередЗаписью → ОбработкаПроверкиЗаполнения → ПриЗаписи → запись в базу → ПослеЗаписи (в форме). Если на любом этапе до физической записи установлен Отказ = Истина, транзакция прерывается.

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

Если проверка заполнения завершилась с Отказ = Истина, события ПриЗаписи и ПослеЗаписи не выполняются. Пользователь увидит сообщения об ошибках, добавленные через Сообщить() или через объект СообщениеПользователю, а объект останется в режиме редактирования.

Стандартная проверка и массив ПроверяемыеРеквизиты

До того как выполнится ваш код в обработчике, платформа формирует массив ПроверяемыеРеквизиты — список реквизитов, у которых в конфигураторе свойство «Проверка заполнения» установлено в значение «Выдавать ошибку». Стандартная проверка пройдет по этому массиву автоматически после отработки вашего кода, если реквизиты не удалить из массива вручную.

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

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

Обратите внимание на передачу параметра Отказ в метод СообщитьПользователю: так отказ установится автоматически при выводе сообщения, и не нужно писать отдельную строку Отказ = Истина. Это стандартный прием типовых конфигураций.

Как проверять табличные части и связанные реквизиты

Стандартная проверка заполнения работает и для реквизитов табличных частей, но сообщения платформы часто недостаточно информативны. В обработчике удобно проверять табличные части вручную: контролировать наличие хотя бы одной строки, дубли строк по ключевым полям, соответствие сумм табличной части итоговым реквизитам шапки.

При выводе ошибки по строке табличной части важно правильно сформировать путь к данным, чтобы платформа подсветила именно ту ячейку, где проблема. Для этого используется обобщенный путь вида «Объект.Товары[Индекс].Номенклатура».

bsl
Для Каждого Строка Из Товары Цикл
	Если Строка.Количество = 0 Тогда
		Поле = "Товары[" + Формат(Товары.Индекс(Строка), "ЧГ=") + "].Количество";
		ОбщегоНазначения.СообщитьПользователю(
			"В строке " + Строка.НомерСтроки + " не указано количество",
			ЭтотОбъект, Поле, "Объект", Отказ);
	КонецЕсли;
КонецЦикла;

Проверки согласованности (например, «сумма по строкам равна сумме документа») тоже правильно размещать здесь, а не в ПередЗаписью: пользователь получит единый список всех проблем за одну попытку записи, а не будет исправлять ошибки по одной.

Отличия для формы объекта и кода на клиенте

В модуле формы существует одноименный обработчик ОбработкаПроверкиЗаполненияНаСервере, а на клиенте доступны проверки через события перед записью. Разница принципиальна: обработчик в модуле объекта гарантированно сработает при любой записи, включая программную, обмены и фоновые задания. Обработчик формы — только при интерактивной записи через эту конкретную форму.

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

Маршрут решения

Где размещать проверку

Проверка защищает целостность данных (обязательные поля, согласованность сумм)Размещайте в ОбработкаПроверкиЗаполнения модуля объекта
Проверка — только подсказка пользователю в конкретной формеИспользуйте обработчик формы ОбработкаПроверкиЗаполненияНаСервере
Данные загружаются обменом и могут быть неполными на промежуточном этапеЗаписывайте с ОбменДанными.Загрузка = Истина, но догрузите обязательные поля позже
Проверка требует тяжелых запросов к базеВынесите её в регламентное задание или отчет контроля, а не в обработчик записи

Типичные ошибки при работе с обработчиком

Самая частая ошибка — установка Отказ = Истина без сообщения пользователю. Запись молча отклоняется, пользователь видит пустое или непонятное окно и не понимает, что исправлять. Всегда сопровождайте отказ конкретным сообщением с указанием поля.

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

Третья ошибка — удаление реквизита из ПроверяемыеРеквизиты без замены собственной проверкой. Разработчик «гасит» стандартную ошибку, забывает добавить свою логику, и объект начинает сохраняться с пустым обязательным полем. После любого удаления из массива сразу пишите замещающую проверку или комментарий, почему она не нужна.

Типичные ошибки
01
Отказ = Истина без сообщения — пользователь не понимает причину отказа в записи
02
Удаление реквизита из ПроверяемыеРеквизиты без замещающей проверки — объект сохраняется с пустым полем
03
Тяжелые запросы к базе внутри обработчика — блокировки и таймауты при параллельной работе
04
Проверка только в форме — обмены и программная запись обходят валидацию
05
Изменение данных объекта внутри проверки — логика заполнения должна быть в ПередЗаписью или ОбработкаЗаполнения

Как проверить, что обработчик работает правильно

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

Проверьте также позитивный сценарий: объект с корректно заполненными данными должен записываться без лишних сообщений. Частая недоработка — проверка срабатывает всегда, потому что условие построено неверно (например, сравнение с Неопределено вместо использования ЗначениеЗаполнено()).

Контрольные точки

Как проверить результат

Запись объекта с пустым обязательным реквизитом
Норма

Запись отклонена, выведено понятное сообщение с подсветкой поля

Тревожный признак

Запись проходит или отказ без сообщения

Программная запись через Записать() в коде
Норма

Проверка срабатывает так же, как из формы

Тревожный признак

Объект сохраняется в обход проверки

Запись корректно заполненного объекта
Норма

Записывается с первой попытки без сообщений

Тревожный признак

Ложные срабатывания проверки

Загрузка через обмен с ОбменДанными.Загрузка = Истина
Норма

Загрузка проходит, контроль выполняется отдельным механизмом

Тревожный признак

Обмен падает на проверках заполнения

Частые вопросы

Вызывается ли ОбработкаПроверкиЗаполнения при проведении документа?

Да. Проведение — это запись в специальном режиме, поэтому проверка заполнения выполняется. Если проверка не пройдена, документ не будет ни записан, ни проведен, а движения не изменятся.

Почему обработчик не срабатывает при загрузке данных из обмена?

Скорее всего, при загрузке устанавливается ОбменДанными.Загрузка = Истина — это штатный механизм обхода всех проверок при записи. Если контроль нужен, реализуйте его в правилах конвертации или отдельной проверкой после загрузки.

Чем ОбработкаПроверкиЗаполнения отличается от ПередЗаписью?

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

Как вывести ошибку с привязкой к конкретной строке табличной части?

Сформируйте путь к полю вида «Товары[Индекс].ИмяРеквизита» и передайте его в СообщитьПользователю вместе с ключом «Объект». Платформа подсветит нужную ячейку при двойном щелчке по сообщению.

Можно ли отключить стандартную проверку заполнения для одного реквизита?

Да, двумя способами: в конфигураторе установить свойство «Проверка заполнения» реквизита в «Не проверять», либо в обработчике удалить имя реквизита из массива ПроверяемыеРеквизиты. Второй способ позволяет делать это условно.

Вызывается ли событие при записи набора записей регистра?

Для регистров существует собственное событие ОбработкаПроверкиЗаполнения в модуле набора записей, и оно вызывается при записи набора. Но оно не связано с обработчиком документа-регистратора — проверки движений нужно реализовывать отдельно.

Итог

Что важно запомнить

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