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

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Архитектурные особенности проверки заполнения в платформе «1С:Предприятие»

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

  1. Пользователь нажимает кнопку записи или проведения в форме документа.
  2. Расширение управляемой формы перед отправкой команды на сервер обращается к механизму проверки заполнения.
  3. Если для документа установлено свойство проведения Разрешить, то при интерактивной работе проверка запускается только в момент проведения. Если проведение запрещено — проверка запускается при обычной записи.
  4. Платформа формирует список проверяемых реквизитов и вызывает обработчик ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) в модуле объекта.

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

Явный вызов метода ПроверитьЗаполнение

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

  1. Метод возвращает булево значение: Истина, если все обязательные реквизиты заполнены и в коде не выставлен отказ, и Ложь, если обнаружены ошибки.
  2. Вызов ПроверитьЗаполнение() сам по себе не прерывает исполнение программного кода и не отменяет транзакцию записи автоматически. Обработку возвращаемого результата разработчик обязан реализовать явно.
  3. Все стандартные и пользовательские ошибки выводятся через механизм СообщениеПользователю с привязкой к конкретным полям.

Посмотрим на пример правильного вызова метода перед записью документа:


// Создаем или получаем документ
ДокументОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

// ... блок заполнения реквизитов документа ...

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

// Если проверка пройдена успешно, выполняем запись
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

Перехват ошибок в фоновых заданиях и интеграциях

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

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


Если Не ДокументОбъект.ПроверитьЗаполнение() Тогда
    МассивСообщений = ПолучитьСообщенияПользователю(Истина);
    ТекстОшибок = "";
    
    Для Каждого Сообщение Из МассивСообщений Цикл
        ТекстОшибок = ТекстОшибок + Сообщение.Текст + Символы.ПС;
    КонецЦикла;
    
    ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
        НСтр("ru = 'Ошибки при проверке заполнения документа: %1'"), 
        ТекстОшибок
    );
КонецЕсли;

Специфика конфигурации «Бухгалтерия предприятия 3.0»

При программном создании документов (например, РеализацияТоваровУслуг) в «1С:Бухгалтерии 3.0» возникает сопутствующая сложность: в интерактивном режиме заполнение счетов учета номенклатуры, счетов расчетов с контрагентами и ставок НДС выполняется в событиях управляемой формы (таких как ПриИзменении). При программном создании эти обработчики не запускаются, поэтому вызов ПроверитьЗаполнение() сразу вернет Ложь из-за пустых счетов учета.

Для корректного формирования документа в типовых конфигурациях на базе БСП применим следующие правила:

  1. Инициализация документа: сразу после создания объекта вызовем метод ДокументОбъект.Заполнить(Неопределено) (или передадим структуру заполнения). Это запустит процедуру ОбработкаЗаполнения в модуле объекта и подставит организацию, валюту, ответственного и основные реквизиты по умолчанию.
  2. Заполнение счетов учета: программно вызовем типовые процедуры заполнения счетов расчетов и счетов учета номенклатуры из общих модулей конфигурации перед валидацией.
  3. Контроль при проведении: если документ должен быть проведен, можно сразу вызывать ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение). В типовой процедуре ОбработкаПроведения модуля документа уже заложен жесткий контроль ключевых реквизитов и остатков: при обнаружении некорректных данных флаг Отказ будет установлен в значение Истина.
  4. Гарантированная валидация в ПередЗаписью: если требуется обеспечить обязательное заполнение определенных реквизитов при любых способах записи (включая сторонние обмены и прямой вызов Записать), критически важные проверки следует размещать в событии ПередЗаписью модуля объекта с установкой параметра Отказ = Истина.
← На главную