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