Как программно создать документ «Перемещение товаров» на основании «Заказа на перемещение» в 1С:Розница

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

В процессе разработки собственных обработок в среде 1С:Предприятие часто возникает задача автоматизации цепочки документов. В конфигурации 1С:Розница 2.3 (и других решениях на базе БСП) типичным сценарием является создание документа Перемещение товаров на основании предварительно созданного и проведенного документа Заказ на перемещение товаров. Рассмотрим подробно, как реализовать этот механизм правильно, избежав типичных ошибок новичков. Если требуется готовое решение, можно использовать обработку для заполнения заказов и документов перемещения по остаткам в 1С:Розница 2.3.

Разберем основную проблему

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


// Создание заказа
Заказ = Документы.ЗаказНаПеремещение.СоздатьДокумент();
// Заполнение реквизитов заказа...
Заказ.Записать(РежимЗаписиДокумента.Проведение);

// Попытка создания перемещения вручную
Перемещение = Документы.ПеремещениеТоваров.СоздатьДокумент();
Перемещение.ДокументОснование = Заказ.Ссылка;
// Далее следует ручной перенос строк ТЧ...

Такой подход не является оптимальным. Платформа 1С предоставляет мощный механизм Заполнить(), который задействует логику конфигурации, заложенную в процедуре ОбработкаЗаполнения модуля объекта.

Решение №1: Использование метода Заполнить()

Самый правильный и быстрый способ создать подчиненный документ — вызвать метод Заполнить(), передав в него ссылку на документ-основание. Выясним причину, по которой этот метод иногда «не срабатывает».

Для того чтобы Перемещение.Заполнить(Заказ.Ссылка) отработало корректно, должны выполняться три условия:

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

Рассмотрим правильный алгоритм работы:


// 1. Создаем и записываем Заказ
НовыйЗаказ = Документы.ЗаказНаПеремещение.СоздатьДокумент();
// ... заполняем шапку и товары ...
НовыйЗаказ.Записать(РежимЗаписиДокумента.Проведение);

// 2. Создаем Перемещение на основании Заказа
НовоеПеремещение = Документы.ПеремещениеТоваров.СоздатьДокумент();
// Метод Заполнить автоматически перенесет товары и реквизиты шапки
НовоеПеремещение.Заполнить(НовыйЗаказ.Ссылка);

// 3. Дозаполняем специфические поля, если нужно
НовоеПеремещение.Дата = ТекущаяДата();
НовоеПеремещение.Ответственный = Пользователи.ТекущийПользователь();

// 4. Записываем результат
НовоеПеремещение.Записать(РежимЗаписиДокумента.Проведение);

Решение №2: Оптимизация работы с ценами и данными (избавляемся от запросов в цикле)

Проанализируем частую ошибку производительности: выполнение запроса к регистру цен внутри цикла заполнения строк документа. Если в документе 100 позиций, система выполнит 100 обращений к базе данных, что существенно замедлит работу.

Рассмотрим, как сделать это правильно: сначала соберем всю номенклатуру, одним запросом получим цены и затем распределим их. Посмотрим на пример кода:


// Создаем массив всех товаров для запроса
МассивТоваров = Новый Массив;
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
    МассивТоваров.Добавить(СтрокаТЧ.Номенклатура);
КонецЦикла;

// Выполняем один запрос для получения всех цен сразу
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Цены.Номенклатура КАК Номенклатура,
    |	Цены.Цена КАК Цена
    |ИЗ
    |	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, Номенклатура В (&МассивТоваров) И ВидЦены = &ВидЦены) КАК Цены";

Запрос.УстановитьПараметр("Период", ТекущаяДата());
Запрос.УстановитьПараметр("МассивТоваров", МассивТоваров);
Запрос.УстановитьПараметр("ВидЦены", НужныйВидЦены);

ТаблицаЦен = Запрос.Выполнить().Выгрузить();
ТаблицаЦен.Индексировать("Номенклатура");

// Теперь в цикле заполнения просто ищем цену в таблице (это очень быстро)
Для Каждого СтрокаДок Из Перемещение.Товары Цикл
    ПараметрыПоиска = Новый Структура("Номенклатура", СтрокаДок.Номенклатура);
    НайденныеСтроки = ТаблицаЦен.НайтиСтроки(ПараметрыПоиска);
    Если НайденныеСтроки.Количество() > 0 Тогда
        СтрокаДок.Цена = НайденныеСтроки[0].Цена;
        СтрокаДок.Сумма = СтрокаДок.Количество * СтрокаДок.Цена;
    КонецЕсли;
КонецЦикла;

Важные нюансы работы в «1С:Розница»

При автоматизации перемещений в «Рознице» следует учитывать архитектурные особенности программы. Проанализируем ключевые моменты:

  1. Магазины и склады: В Рознице документ ПеремещениеТоваров жестко связан с понятием «Магазин». Часто недостаточно просто указать СкладОтправитель, необходимо заполнить и МагазинОтправитель. Если эти реквизиты не будут соответствовать друг другу, типовые механизмы могут очистить данные при открытии формы пользователем.
  2. Статусы заказов: Чтобы перемещение «увидело» потребность, установленную заказом, убедитесь, что в заказе установлен статус К выполнению (или аналогичный в вашей версии). Если статус Закрыт или Черновик, стандартная процедура Заполнить() может проигнорировать такой документ.
  3. Связанные документы: В Рознице 2.3 связь между заказом и перемещением часто фиксируется не только через поле ДокументОснование, но и в самой табличной части товаров (например, через реквизит ДокументРезерва). Использование метода Заполнить() гарантирует, что эти скрытые связи будут установлены корректно для корректной работы отчетов по исполнению заказов.

Использование интерфейсов БСП

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

Подведем итог: для создания документа на основании в обработке, всегда отдавайте приоритет методу Заполнить(). Предварительно записывайте и проводите документ-основание, а также не забывайте об оптимизации запросов, вынося их за пределы циклов. Это обеспечит стабильность работы системы и корректность ведения управленческого учета в вашей компании. Для автоматизации массового создания таких документов без программирования подойдёт инструмент для группового формирования перемещений товаров.

← На главную