Разработка и Конфигурация · 12 мин
Как вызвать обработку проверки заполнения в 1С
Как вызвать обработку проверки заполнения в 1С: процедура ОбработкаПроверкиЗаполнения, вызов из кода, настройка сообщений об ошибках и типовые сценарии.
Проверка заполнения в 1С — это механизм, который не даёт записать объект с незаполненными или некорректными реквизитами. Он срабатывает автоматически при записи документа или элемента справочника, но разработчику часто нужно вызвать эту проверку принудительно: до записи, при программной обработке данных или при реализации собственной логики контроля.
За проверку отвечает обработчик ОбработкаПроверкиЗаполнения в модуле объекта, а также метод ПроверитьЗаполнение(), который можно вызвать из любого места кода. Понимание того, как эти механизмы связаны, позволяет строить надёжные проверки без дублирования логики.
Как работает механизм проверки заполнения
У любого прикладного объекта — справочника, документа, плана счетов — есть встроенная проверка заполнения. Платформа проверяет реквизиты, у которых в конфигураторе установлено свойство «Проверка заполнения» в значение «Выдавать ошибку», а также обязательные стандартные реквизиты. Если проверка не пройдена, запись прерывается, а пользователь видит сообщение с указанием поля.
Порядок вызова такой: при записи объекта платформа сначала выполняет стандартную проверку обязательных реквизитов, затем вызывает обработчик ОбработкаПроверкиЗаполнения из модуля объекта. Внутри обработчика разработчик может добавить собственные условия и отменить запись, установив параметр Отказ в значение Истина.
Важно понимать, что проверка заполнения — это не то же самое, что подписка на событие «ПриЗаписи». Проверка выполняется до фактической записи в базу и предназначена именно для валидации данных, тогда как «ПриЗаписи» срабатывает уже в транзакции записи.
Вызов проверки заполнения из кода
Чтобы принудительно запустить проверку без записи объекта, используется метод ПроверитьЗаполнение(). Он возвращает булево значение: Истина, если проверка пройдена, и Ложь, если есть ошибки. Сообщения об ошибках при этом выводятся пользователю автоматически.
НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДатаСеанса();
// ... заполнение реквизитов
Если НовыйДокумент.ПроверитьЗаполнение() Тогда
НовыйДокумент.Записать();
Иначе
Сообщить("Документ не прошёл проверку заполнения");
КонецЕсли;
Такой подход особенно полезен при пакетной обработке данных: например, при загрузке документов из файла можно сначала проверить каждый объект, а записывать только корректные. Это защищает базу от частично заполненных документов и упрощает разбор ошибок.
Обратите внимание: метод ПроверитьЗаполнение() вызывает и стандартную проверку реквизитов, и обработчик ОбработкаПроверкиЗаполнения. Отдельно вызвать только свою логику без стандартной нельзя — если это требуется, вынесите проверки в отдельную экспортную функцию модуля объекта.
- 1Создайте или получите объект (СоздатьДокумент, СоздатьЭлемент, ПолучитьОбъект)
- 2Заполните реквизиты программно или оставьте ввод пользователю
- 3Вызовите метод ПроверитьЗаполнение() и проанализируйте возвращаемое значение
- 4При успешной проверке выполните Записать(), при ошибке — обработайте отказ
- 5Проверьте, что сообщения об ошибках содержат понятные указания на поля
Написание собственного обработчика ОбработкаПроверкиЗаполнения
Обработчик размещается в модуле объекта и имеет два параметра: Отказ и ПроверяемыеРеквизиты. Первый — флаг, установка которого в Истина запрещает запись. Второй — массив имён реквизитов, которые платформа проверит стандартно; из него можно удалить реквизит, если стандартная проверка не нужна.
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если СуммаДокумента < 0 Тогда
ОбщегоНазначения.СообщитьПользователю(
"Сумма документа не может быть отрицательной",
ЭтотОбъект, "СуммаДокумента", , Отказ);
КонецЕсли;
// Убираем стандартную проверку необязательного в нашем случае реквизита
Индекс = ПроверяемыеРеквизиты.Найти("Комментарий");
Если Индекс <> Неопределено Тогда
ПроверяемыеРеквизиты.Удалить(Индекс);
КонецЕсли;
КонецПроцедуры
Для вывода сообщений рекомендуется использовать ОбщегоНазначения.СообщитьПользователю (в конфигурациях на БСП) с привязкой к полю формы — тогда сообщение будет кликабельным и подсветит проблемный реквизит. В конфигурациях без БСП можно пользоваться обычным Сообщить(), но привязки к полю не будет.
Проверки табличных частей выполняются в том же обработчике: переберите строки циклом и при ошибке укажите путь к данным вида "Товары[" + Формат(НомерСтроки - 1, "ЧГ=") + "].Номенклатура", чтобы сообщение привязалось к конкретной строке.
Проверка заполнения в форме и директивы компиляции
Если объект редактируется в управляемой форме, проверка запускается при нажатии кнопок «Записать» и «Провести». Но можно вызвать её и программно из модуля формы — например, при нажатии собственной кнопки «Проверить» без записи:
&НаКлиенте
Процедура ПроверитьДокумент(Команда)
Если ПроверитьЗаполнениеНаСервере() Тогда
ПоказатьПредупреждение(, "Ошибок заполнения не обнаружено");
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПроверитьЗаполнениеНаСервере()
ОбъектДанных = РеквизитФормыВЗначение("Объект");
Возврат ОбъектДанных.ПроверитьЗаполнение();
КонецФункции
Нюанс: преобразование РеквизитФормыВЗначение — затратная операция, особенно для документов с большими табличными частями. Для лёгких проверок (например, контроль одного реквизита) часто проще выполнить сравнение прямо в форме без вызова полного механизма.
Ещё один момент — директивы компиляции. Обработчик ОбработкаПроверкиЗаполнения в модуле объекта выполняется на сервере, поэтому код внутри него не должен обращаться к клиентским возможностям: модальным окнам, предупреждениям, элементам формы. Все сообщения выводятся через механизм сообщений пользователю.
Отключение и настройка стандартной проверки реквизитов
Стандартная проверка настраивается в конфигураторе на уровне реквизита: свойство «Проверка заполнения» принимает значения «Не проверять», «Выдавать ошибку». Для реквизитов, обязательность которых зависит от условий (например, договор обязателен только при определённом виде операции), стандартную проверку отключают, а контроль переносят в обработчик.
Альтернатива — оставить стандартную проверку, но удалять реквизит из массива ПроверяемыеРеквизиты по условию. Такой подход удобен, когда в большинстве случаев реквизит обязателен, а исключения редки: стандартное сообщение платформы останется, а лишние проверки отключатся точечно.
Учтите, что свойство «Проверка заполнения» влияет и на формы: поле с обязательной проверкой подсвечивается красной рамкой до заполнения. Если вы перенесли контроль в обработчик, эта подсветка пропадёт — пользователю стоит дать понятное сообщение взамен.
Сравнение вариантов
Подходит для безусловно обязательных полей. Не требует кода, но не поддерживает условия и сложные правила.
Подходит для условных проверок, контроля табличных частей и перекрёстных правил. Требует кода и аккуратных сообщений.
Подходит для UX-подсказок до записи. Не защищает данные при программной записи, поэтому только как дополнение.
Типичные ошибки и их диагностика
Одна из частых проблем — обработчик не вызывается. Причины: код размещён в модуле менеджера вместо модуля объекта, имя процедуры написано с опечаткой, либо проверка запускается для другого вида объекта. Проверьте, что процедура находится именно в модуле объекта и её сигнатура соответствует ожидаемой платформой.
Вторая типичная ситуация — сообщение выводится, но запись всё равно выполняется. Это значит, что параметр Отказ не установлен в Истина: само по себе сообщение запись не блокирует. Обратная ошибка — установка Отказ без сообщения, из-за чего пользователь не понимает причину отказа.
Третья группа ошибок связана с программной записью: разработчик заполняет объект кодом, вызывает Записать() и получает исключение о незаполненном реквизите. Решение — вызывать ПроверитьЗаполнение() до записи и корректно обрабатывать отрицательный результат, а не перехватывать исключение.
Проверка результата и отладка
Чтобы убедиться, что механизм работает, протестируйте три сценария: интерактивную запись с пустым обязательным полем, программный вызов ПроверитьЗаполнение() на заведомо некорректном объекте и запись корректного объекта без ложных срабатываний. Во всех случаях сообщения должны указывать на конкретные поля.
При отладке обработчика удобно ставить точку останова на первой строке процедуры и проверять содержимое массива ПроверяемыеРеквизиты — так видно, какие стандартные проверки выполнит платформа. Если массив пуст, а ошибка всё равно возникает, значит, срабатывает проверка стандартных реквизитов или проверка на уровне СУБД (например, уникальность).
Как проверить результат
Запись отклонена, сообщение указывает на поле
Запись проходит или сообщение без привязки к полю
Возвращает Ложь на некорректном объекте и Истина на корректном
Всегда возвращает Истина или вызывает исключение
Клик по сообщению выделяет нужную строку и колонку
Сообщение общее, строку найти невозможно
Частые вопросы
Можно ли вызвать проверку заполнения без записи объекта?
Да, для этого служит метод ПроверитьЗаполнение(). Он выполняет и стандартные проверки, и обработчик ОбработкаПроверкиЗаполнения, возвращая Истина или Ложь. Запись при этом не выполняется, что удобно для предварительной валидации при загрузке данных.
Почему мой обработчик ОбработкаПроверкиЗаполнения не срабатывает?
Чаще всего процедура размещена не в модуле объекта, а в модуле формы или менеджера. Также проверьте точное имя процедуры и наличие обоих параметров — Отказ и ПроверяемыеРеквизиты. Опечатка в имени превращает обработчик в обычную процедуру, которую платформа не вызывает.
Как отключить стандартную проверку одного реквизита по условию?
В обработчике найдите имя реквизита в массиве ПроверяемыеРеквизиты методом Найти() и удалите его методом Удалить(). Либо в конфигураторе установите для реквизита «Проверка заполнения — Не проверять» и реализуйте контроль полностью в обработчике.
Чем ПроверитьЗаполнение() отличается от Записать()?
ПроверитьЗаполнение() только выполняет проверки и возвращает результат, не изменяя базу данных. Записать() сначала неявно вызывает те же проверки, а затем сохраняет объект; при непройденной проверке запись прерывается с исключением или отказом.
Как вывести сообщение с привязкой к строке табличной части?
Используйте ОбщегоНазначения.СообщитьПользователю с параметром пути к данным вида "Товары[0].Номенклатура" (индекс строки с нуля, без группировки разрядов). Тогда в форме клик по сообщению выделит конкретную ячейку, что заметно упрощает исправление ошибок.
Работает ли проверка заполнения при обмене данными?
При загрузке через механизмы обмена объект часто записывается с установленным ОбменДанными.Загрузка = Истина, и в этом режиме проверка заполнения не выполняется. Если контроль нужен и при обмене, вызывайте ПроверитьЗаполнение() явно в правилах конвертации или после загрузки.
Что важно запомнить
Проверка заполнения вызывается автоматически при записи или принудительно методом ПроверитьЗаполнение(). Собственная логика размещается в обработчике ОбработкаПроверкиЗаполнения модуля объекта: каждая установка Отказ должна сопровождаться понятным сообщением с привязкой к полю, а запись внутри обработчика недопустима.