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