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