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