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