В процессе разработки на платформе 1С:Предприятие 8 мы часто сталкиваемся с необходимостью реализации сложной логики проверки заполнения данных. Механизм ОбработкаПроверкиЗаполнения является мощным инструментом для решения этой задачи. Однако у многих разработчиков возникают вопросы о том, когда именно этот обработчик вызывается и как в него можно передать дополнительную информацию, например, текущий режим записи документа. Давайте вместе разберемся в этих нюансах, проанализируем ситуацию и выясним причину такого поведения.
Начнем с фундаментального вопроса: при каких условиях платформа 1С вызывает процедуру ОбработкаПроверкиЗаполнения? Мы выясним, что это зависит от нескольких факторов, в основном от настройки свойства "Проведение" документа и способа вызова.
ОбработкаПроверкиЗаполнения будет вызван расширением формы перед проведением документа. То есть, когда пользователь интерактивно нажимает кнопку "Провести" или "Записать и провести".ОбработкаПроверкиЗаполнения не вызывается автоматически при программной записи объекта. Чтобы инициировать проверку программно, нам необходимо явно вызвать метод ПроверитьЗаполнение().ПроверятьЗаполнениеАвтоматически в значение Истина. В этом случае сначала будет вызван обработчик ОбработкаПроверкиЗаполненияНаСервере() формы, а затем уже ОбработкаПроверкиЗаполнения() модуля объекта.Таким образом, мы видим, что сам режим записи (проведение или простая запись) напрямую определяет, когда именно платформа инициирует проверку заполнения через этот обработчик.
Возникает логичный вопрос: если платформа сама знает, проводится документ или просто записывается, зачем нам дополнительно передавать эту информацию в обработчик? Мы проанализируем ситуацию.
Хотя платформа и определяет момент вызова в зависимости от свойства "Проведение" документа, внутри самого обработчика ОбработкаПроверкиЗаполнения нам может понадобиться реализовать условную логику проверки. Например, одни реквизиты должны быть обязательными при проведении документа, но необязательными при его простой записи. Или, возможно, при проведении требуется более строгая валидация, чем при черновой записи. Для такой гибкой настройки нам и потребуется информация о текущем режиме записи.
Давайте разберем, как мы можем передать режим записи или любую другую вспомогательную информацию из формы в обработчик ОбработкаПроверкиЗаполнения модуля объекта. Для этого мы будем использовать свойство ДополнительныеСвойства объекта.
В процедуре ПередЗаписьюНаСервере формы документа у нас есть доступ к параметру ТекущийОбъект. У этого объекта существует свойство ДополнительныеСвойства, которое представляет собой структуру. Мы можем использовать эту структуру для временного хранения любых значений, которые нам нужно передать дальше по цепочке серверных вызовов, не изменяя при этом сам объект документа.
В процедуре ПередЗаписьюНаСервере формы документа мы можем добавить информацию о режиме записи в структуру ДополнительныеСвойства. Мы посмотрим на пример:
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ПараметрыЗаписи)
// ... ваш код перед записью ...
// Передаем информацию о режиме записи
Если ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
ТекущийОбъект.ДополнительныеСвойства.Вставить("РежимЗаписи", "Проведение");
Иначе
ТекущийОбъект.ДополнительныеСвойства.Вставить("РежимЗаписи", "Запись");
КонецЕсли;
// ... продолжение вашего кода ...
КонецПроцедуры
Здесь мы используем параметр ПараметрыЗаписи.РежимЗаписи, который доступен в ПередЗаписьюНаСервере формы. Мы вставляем строку "Проведение" или "Запись" в структуру ДополнительныеСвойства под ключом "РежимЗаписи".
Теперь, когда обработчик ОбработкаПроверкиЗаполнения в модуле объекта будет вызван, мы сможем получить переданную информацию. Разберем по шагам:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Получаем режим записи из ДополнительныхСвойств
Перем РежимЗаписи;
Если ДополнительныеСвойства.Свойство("РежимЗаписи", РежимЗаписи) Тогда
// Теперь переменная РежимЗаписи содержит переданное значение ("Проведение" или "Запись")
Сообщить("Текущий режим записи: " + РежимЗаписи);
Если РежимЗаписи = "Проведение" Тогда
// Реализуем проверки, специфичные для проведения
Если ЗначениеЗаполнено(ЭтотОбъект.Контрагент) Тогда
// Все хорошо
Иначе
Отказ = Истина;
Сообщить("При проведении необходимо заполнить контрагента!", СтатусСообщения.Важное);
КонецЕсли;
Иначе // РежимЗаписи = "Запись"
// Реализуем проверки, специфичные для простой записи
// Например, здесь Контрагент может быть необязательным
КонецЕсли;
Иначе
// Если по какой-то причине режим записи не был передан
Сообщить("Режим записи не был передан в ОбработкуПроверкиЗаполнения.", СтатусСообщения.Внимание);
КонецЕсли;
// ... дальнейшая логика проверки заполнения ...
КонецПроцедуры
Мы используем метод Свойство() структуры ДополнительныеСвойства для безопасного получения значения. Затем мы можем использовать переменную РежимЗаписи для построения нашей условной логики.
Этот подход позволяет нам гибко настраивать проверки в зависимости от контекста вызова, используя временные данные, не сохраняемые в самом объекте.
Рассмотрим подробнее, какие еще возможности предоставляет обработчик ОбработкаПроверкиЗаполнения, помимо условной логики:
Отказ и ПроверяемыеРеквизиты:
Отказ (типа Булево) позволяет нам отменить дальнейшую запись или проведение документа, если проверка не пройдена. Установите его в Истина, чтобы остановить операцию.ПроверяемыеРеквизиты (типа Массив) содержит список имен реквизитов, которые платформа будет проверять автоматически (те, у которых свойство "Проверка заполнения" в конфигураторе установлено в "Выдавать ошибку").ПроверяемыеРеквизиты:
Мы можем модифицировать этот массив для тонкой настройки проверки:
Посмотрим на пример:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Добавляем реквизит "Комментарий" для обязательной проверки, если его нет
Если Не ПроверяемыеРеквизиты.Найти("Комментарий") Тогда
ПроверяемыеРеквизиты.Добавить("Комментарий");
КонецЕсли;
// Удаляем реквизит "Ответственный" из списка автоматической проверки,
// чтобы проверить его заполнение вручную с более сложной логикой
Индекс = ПроверяемыеРеквизиты.Найти("Ответственный");
Если Индекс <> Неопределено Тогда
ПроверяемыеРеквизиты.Удалить(Индекс);
КонецЕсли;
// Наша сложная проверка для Ответственного
Если ЭтотОбъект.СуммаДокумента > 100000 И Не ЗначениеЗаполнено(ЭтотОбъект.Ответственный) Тогда
Отказ = Истина;
Сообщить("При сумме документа более 100 000 руб. Ответственный обязателен!", СтатусСообщения.Важное);
КонецЕсли;
// ... другая логика ...
КонецПроцедуры
ПриЗаписи:
Важно различать ОбработкаПроверкиЗаполнения и проверки, выполняемые непосредственно в процедуре ПриЗаписи объекта. ОбработкаПроверкиЗаполнения предназначена для проверки интерактивного ввода пользователя и может содержать более сложную, контекстно-зависимую логику. Проверки же в ПриЗаписи должны быть быстрыми, строгими и являться частью технической логики объекта, гарантируя целостность данных независимо от способа записи (интерактивный или программный).
Мы надеемся, что это подробное объяснение помогло вам разобраться в механизме ОбработкаПроверкиЗаполнения, понять его вызовы и научиться передавать в него дополнительную информацию, такую как режим записи. Используйте эти знания для создания более надежных и удобных для пользователя решений на платформе 1С:Предприятие 8!