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

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

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

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

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

Понимание точного порядка вызова критично, потому что этот обработчик встроен в цепочку событий записи объекта и взаимодействует со стандартной проверкой заполнения реквизитов, у которых установлено свойство «Проверка заполнения». Ошибки в логике приводят либо к пропуску некорректных данных в базу, либо к блокировке записи вполне корректных документов.

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

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

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

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

Третья ситуация — проведение документа. При вызове Записать(РежимЗаписиДокумента.Проведение) платформа выполняет проверку заполнения, поскольку проводить документ с незаполненными обязательными полями нельзя. Обработчик вызывается до начала формирования движений.

Важно понимать, чего обработчик не делает: он не вызывается при изменении значения поля в форме, не вызывается при открытии формы, не вызывается при копировании объекта. Если нужна реакция на ввод данных «на лету», используются события формы ПриИзменении или клиентская проверка.

Место обработчика в цепочке событий записи

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

Ключевой нюанс: стандартная проверка реквизитов с признаком «Проверка заполнения = Выдавать ошибку» выполняется до вашего обработчика. Если стандартная проверка не пройдена, запись прерывается, и до вашего кода управление может не дойти. Поэтому в ОбработкаПроверкиЗаполнения имеет смысл размещать только те проверки, которые невозможно выразить стандартными средствами.

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

Порядок событий при записи объекта
  1. 1
    ПередЗаписью — последняя возможность изменить данные до проверок
  2. 2
    Стандартная проверка обязательных реквизитов платформой
  3. 3
    ОбработкаПроверкиЗаполнения — ваши собственные проверки
  4. 4
    ПриЗаписи — действия в транзакции записи
  5. 5
    ПослеЗаписи — завершающие действия на клиенте

Пример реализации собственной проверки

Рассмотрим практический пример: в документе «Заказ покупателя» нужно запретить проведение, если сумма документа равна нулю, а также потребовать заполнение даты отгрузки для определённого вида операции. Код размещается в модуле объекта документа.

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

Если Товары.Итог("Сумма") = 0 Тогда

ОбщегоНазначения.СообщитьПользователю(

"Сумма документа равна нулю. Проверьте табличную часть ""Товары"".",

ЭтотОбъект, "Товары", , Отказ);

КонецЕсли;

Если ВидОперации = Перечисления.ВидыОпераций.Предоплата Тогда

Индекс = ПроверяемыеРеквизиты.Найти("ДатаОтгрузки");

Если Индекс <> Неопределено Тогда

ПроверяемыеРеквизиты.Удалить(Индекс);

КонецЕсли;

КонецЕсли;

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

Обратите внимание на ключевые элементы. Параметр Отказ — выставив его в Истина, вы прерываете запись. Сообщение пользователю желательно привязывать к конкретному полю через параметры метода СообщитьПользователю, чтобы в форме подсветился проблемный реквизит. Удаление из массива ПроверяемыеРеквизиты выполняется по найденному индексу — предварительно нужно проверить, что элемент найден.

Если проверок несколько, не прерывайте выполнение после первой ошибки: лучше вывести все замечания сразу, чтобы пользователь исправил данные за одну итерацию, а не нажимал «Записать» пять раз подряд, получая ошибки по одной.

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

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

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

Практическое правило: если проверка должна гарантированно срабатывать всегда — размещайте её в модуле объекта. Если она касается только удобства работы пользователя в конкретной форме — допустимо разместить в форме.

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

Модуль объекта

Гарантированное срабатывание при любой записи, включая программную и обмены. Правильное место для бизнес-правил.

Модуль формы

Только интерактивная запись из этой формы. Подходит для проверок данных, существующих только в форме.

Подписка на событие

Единая проверка для группы объектов без изменения их модулей. Ограничение — сложнее отладка и привязка сообщений к полям.

Проверка заполнения табличных частей и особые случаи

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

Для табличных частей сообщение об ошибке можно привязать к конкретной строке, указав путь к данным вида Товары[2].Количество. Это существенно упрощает пользователю поиск проблемы в длинных документах. Помните, что индексация в пути данных идёт с нуля, а номер строки, который видит пользователь, — с единицы.

Отдельный случай — обмены данными. При загрузке объектов через планы обмена проверка заполнения также может выполняться, и жёсткие проверки способны заблокировать загрузку данных из другой базы. Если объект участвует в обмене, предусмотрите ветку поведения: например, при загрузке (ОбменДанными.Загрузка = Истина) пропускать часть некритичных проверок или писать предупреждения в журнал регистрации вместо отказа.

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

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

Для отладки момента вызова поставьте точку останова в первой строке обработчика и выполните запись разными способами. Если точка не срабатывает при программной записи — вероятно, запись выполняется в режиме загрузки (ОбменДанными.Загрузка = Истина), при котором проверка заполнения платформой пропускается.

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

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

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

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

Запись блокируется, поле подсвечено, сообщение понятно

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

Документ записывается или ошибка не привязана к полю

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

Проверка срабатывает так же, как при интерактивной записи

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

Проверка пропускается — логика размещена только в форме

Загрузка через обмен данными
Норма

Данные загружаются, некритичные ошибки фиксируются в журнале

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

Обмен падает на каждом документе из-за жёсткой проверки

Вызов ПроверитьЗаполнение()
Норма

Возвращает Ложь для некорректного объекта

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

Возвращает Истина при явно незаполненных данных

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

Первая распространённая ошибка — размещение проверки только в форме и удивление, что «через обработку документ записывается с пустыми полями». Любая бизнес-проверка, критичная для целостности данных, должна жить в модуле объекта.

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

Третья ошибка — вывод сообщений через Сообщить() без привязки к объекту и полю. Пользователь получает текст в панели сообщений, но не видит, какое именно поле заполнить. Всегда используйте СообщитьПользователю с указанием объекта и пути к данным.

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

FAQ: частые вопросы о проверке заполнения

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

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

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

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

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

В обработчике ОбработкаПроверкиЗаполнения найдите имя реквизита в массиве ПроверяемыеРеквизиты методом Найти() и удалите элемент по полученному индексу. Платформа не будет проверять этот реквизит в текущем сеансе записи. Свойство «Проверка заполнения» в метаданных при этом менять не нужно.

Чем ПроверитьЗаполнение() отличается от записи объекта?

Метод ПроверитьЗаполнение() выполняет стандартную проверку и вызывает обработчик, но не записывает данные в базу. Он возвращает Истина, если проверки пройдены, и Ложь в противном случае. Это удобно для предварительной валидации перед операциями, которые нельзя откатить.

Можно ли вызвать диалог «Вопрос» из обработчика проверки?

Нет. Обработчик выполняется в серверном контексте, где интерактивные диалоги недоступны. Если нужно запросить подтверждение пользователя, делайте это на клиенте до вызова записи — например, в обработчике команды формы, а результат передавайте в запись через дополнительные свойства объекта.

Срабатывает ли проверка заполнения при проведении документа?

Да. Проведение — это частный случай записи, и перед формированием движений платформа выполняет проверку заполнения, включая вызов вашего обработчика. Документ с непройденной проверкой проведён не будет.

Итог

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

ОбработкаПроверкиЗаполнения вызывается при записи, проведении и явном вызове ПроверитьЗаполнение() — после стандартной проверки реквизитов, но до записи в базу. Критичные бизнес-проверки размещайте в модуле объекта, сообщения привязывайте к полям, а поведение при обмене данными продумывайте отдельно.