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