Почему не формируются движения по регистрам при программном проведении документа через расширение в 1С?

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

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

Причина 1: Неполное заполнение обязательных и скрытых реквизитов

Самая распространенная причина отсутствия движений — это банальная нехватка данных в объекте. Современные типовые конфигурации (такие как ERP, КА или УТ 11) используют сложные алгоритмы проведения, которые опираются не только на основные реквизиты, видимые пользователю на форме, но и на служебные поля, а также на содержимое скрытых табличных частей.

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

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


// Создаем новый документ
НовыйАкт = Документы.АктВыполненныхРабот.СоздатьДокумент();

// Обязательно вызываем процедуру заполнения по основанию
// Это инициализирует множество скрытых параметров и структуру ДополнительныеСвойства
НовыйАкт.Заполнить(ДокументОснованиеЗаказ);

// Если нужно что-то подправить
НовыйАкт.Дата = ТекущаяДата();
НовыйАкт.СуммаДокумента = 1200;
НовыйАкт.Менеджер = ПараметрыСеанса.ТекущийПользователь;

// Проверяем заполнение технических реквизитов, если они не заполнились автоматически
Если НовыйАкт.ЭтапыОплаты.Количество() = 0 Тогда
    // Логика заполнения этапов оплаты
КонецЕсли;

НовыйАкт.Записать(РежимЗаписиДокумента.Проведение);

Чтобы выяснить, каких именно данных не хватает, рекомендуется воспользоваться обработкой "Сравнение реквизитов". Создайте один документ вручную (интерактивно) и проведите его, а второй создайте своим кодом. Сравнив значения всех реквизитов (включая скрытые), вы быстро обнаружите разницу.

Причина 2: Нюансы заимствования объекта в расширение

Когда мы работаем в контексте расширения, критически важно, как именно заимствован объект. Если вы программно создаете документ типа АктВыполненныхРабот, сам этот объект (тип) должен быть добавлен в расширение. Выясним причину: если объект не захвачен, платформа может ограничивать доступ к некоторым его свойствам или метаданным в контексте выполнения кода расширения.

Проверьте следующие настройки в расширении для заимствованного документа:

  1. Свойство «Проведение»: Оно должно иметь значение Разрешить.
  2. Состав движений: Перейдите на вкладку «Движения» заимствованного документа в дереве расширения. Все регистры, по которым должны формироваться записи, должны быть также заимствованы в расширение и отмечены галочками в составе движений документа. Если регистра нет в составе движений внутри расширения, платформа может блокировать запись в него, даже если типовой код модуля объекта пытается это сделать.

Причина 3: Инициализация «Дополнительных свойств»

В современных конфигурациях на базе БСП (Библиотеки Стандартных Подсистем) огромную роль играет структура ДополнительныеСвойства объекта. При интерактивном проведении формы документа часто подготавливают временные таблицы и кэшированные данные в эту структуру, которые затем считываются в модуле проведения.

При вызове СоздатьДокумент() в расширении эта структура пуста. Если типовой алгоритм проведения ожидает найти там, например, таблицу распределения запасов или аналитику учета, и не находит ее, он может просто «тихо» выйти из процедуры, не выдав ошибки, но и не сформировав движений. Решением здесь также является вызов метода Заполнить() или явный вызов экспортных процедур менеджера документа, отвечающих за подготовку данных для проведения (например, ПодготовитьНаборыДанныхДляПроведения).

Причина 4: Влияние режима «ОбменДанными.Загрузка»

Проанализируем еще одну частую ошибку. Иногда при написании обработок по созданию документов разработчики копируют куски кода из механизмов импорта и оставляют следующую строку:


НовыйАкт.ОбменДанными.Загрузка = Истина;
НовыйАкт.Записать(РежимЗаписиДокумента.Проведение);

Важно помнить: установка свойства Загрузка = Истина отключает выполнение всех проверок и, что самое главное, блокирует выполнение обработчиков проведения (событие ОбработкаПроведения в модуле объекта не вызывается). В этом режиме документ просто записывается в базу со статусом «Проведен», но движения по регистрам не создаются. Убедитесь, что этот флаг установлен в Ложь.

Причина 5: Функциональные опции и права доступа

Иногда движения отсутствуют из-за того, что в расширении не учитывается состояние функциональных опций. Если в базе отключена опция, отвечающая за конкретный вид учета (например, «Учет заказов»), типовой код проведения пропустит соответствующие блоки формирования движений. В редких случаях расширение может некорректно считывать параметры сеанса, если код выполняется в специфическом контексте (например, в фоновом задании, запущенном из расширения без надлежащей инициализации).

Также стоит проверить права доступа. Если программное создание происходит под пользователем с ограниченными правами, а расширение добавляет свои условия проверки, это может привести к тому, что запись в регистры будет молчаливо заблокирована механизмом RLS (права на уровне записей).

Подведем итоги

Для успешного формирования движений при программном проведении в расширении выполните следующие шаги:

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

Соблюдение этих правил гарантирует, что программно созданный документ будет полноценно участвовать в учете, формируя все необходимые записи в регистрах системы.

← На главную