Как распределить заказ покупателя по нескольким складам и организовать раздельную печать в 1С:Управление торговлей 10.3?

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

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

Разберем детально, как устроена работа со складами в строках документов, проанализируем программное разделение единого документа на поддокументы, а также рассмотрим нюансы автоматической печати сборочных листов на удаленные принтеры и выгрузки данных в бухгалтерию.

Вариант 1. Указание складов в табличной части и авторезервирование

В типовой конфигурации 1С:Управление торговлей 10.3 предусмотрена возможность задавать склад не только в шапке документа, но и для каждой конкретной товарной позиции. Рассмотрим базовую настройку системы:

  1. Перейдем в меню Сервис — Настройка учета — Параметры учета.
  2. На вкладке настроек документов установим флаг Указание складов в табличной части документов.
  3. После включения этой настройки в документе ЗаказПокупателя в табличной части Товары появляется колонка Склад.

Теперь менеджер может в одном заказе размещать позиции по разным складам. Резервирование товара выполняется через типовой механизм: в строке заполняется склад-источник и указывается способ обеспечения (из текущего остатка или из ожидаемых поступлений). Однако типовые печатные формы (например, Накладная или Бланк заказа) по умолчанию печатают весь состав документа подряд, что приводит к путанице среди кладовщиков.

Вариант 2. Программное разбиение документа по складам

Если специфика бизнес-процесса требует физического разделения документов (или если необходимо формировать отдельные кассовые чеки / накладные на каждую точку отгрузки), применяется обработка табличной части. Она берет исходный документ менеджера, группирует строки по местам хранения и создает дочерние документы на каждый склад.

Рассмотрим пример процедуры, выполняющей группировку строк по данным регистра сведений МестаХраненияНоменклатуры (или по явно указанной колонке склада) и формирующей раздельные документы с их последующим проведением:


Процедура СформироватьДокументыПоСкладам(ДокументОбъект, ТабличнаяЧастьДляЗаполнения)
    
    // Запрашиваем строки текущего документа и определяем целевой склад для каждой позиции
    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("ТекущийДокумент", ДокументОбъект.Ссылка);
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    Док.НомерСтроки КАК НомерСтроки,
        |    Док.Номенклатура КАК Номенклатура,
        |    Док.Количество КАК Количество,
        |    Док.Цена КАК Цена,
        |    Док.Сумма КАК Сумма,
        |    ЕстьNULL(МестаХранения.Склад, Док.Ссылка.Склад) КАК Склад
        |ИЗ
        |    Документ.ЧекККМ.Товары КАК Док
        |    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.МестаХраненияНоменклатуры КАК МестаХранения
        |        ПО Док.Номенклатура = МестаХранения.Номенклатура
        |ГДЕ
        |    Док.Ссылка = &ТекущийДокумент";
        
    РезультатЗапроса = Запрос.Выполнить().Выгрузить();
    
    // Получаем уникальный список складов, задействованных в заказе
    ТаблицаСклады = РезультатЗапроса.Скопировать(, "Склад");
    ТаблицаСклады.Свернуть("Склад");
    
    Если ТаблицаСклады.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    // Если все товары с одного склада - просто обновляем шапку
    Если ТаблицаСклады.Количество() = 1 Тогда
        ДокументОбъект.Склад = ТаблицаСклады[0].Склад;
        Попытка
            ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
        Исключение
            Сообщить("Ошибка проведения: " + ОписаниеОшибки());
        КонецПопытки;
        Возврат;
    КонецЕсли;
    
    // Если складов несколько - первый оставляем в текущем документе, под остальные создаем новые
    МассивСозданныхДокументов = Новый Массив;
    
    Для Каждого СтрСклад Из ТаблицаСклады Цикл
        ТекущийСклад = СтрСклад.Склад;
        
        Отбор = Новый Структура("Склад", ТекущийСклад);
        СтрокиСклада = РезультатЗапроса.НайтиСтроки(Отбор);
        
        // Создаем локальную таблицу с позициями конкретного склада
        ТЗТовары = ТабличнаяЧастьДляЗаполнения.ВыгрузитьКолонки();
        Для Каждого Стр Из СтрокиСклада Цикл
            НоваяСтрока = ТЗТовары.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, Стр);
        КонецЦикла;
        
        Если НЕ ЗначениеЗаполнено(ДокументОбъект.Склад) Тогда
            ДокументОбъект.Склад = ТекущийСклад;
        КонецЕсли;
        
        Если ТекущийСклад = ДокументОбъект.Склад Тогда
            ТабличнаяЧастьДляЗаполнения.Загрузить(ТЗТовары);
            ДокументОбъект.Записать();
            МассивСозданныхДокументов.Добавить(ДокументОбъект.Ссылка);
        Иначе
            // Функция создания нового документа другого склада
            НовыйДокСсылка = СоздатьНовыйДокумент(ТекущийСклад, ТЗТовары, ДокументОбъект);
            МассивСозданныхДокументов.Добавить(НовыйДокСсылка);
        КонецЕсли;
    КонецЦикла;
    
    // Проводим все сформированные документы
    Для Каждого ДокСсылка Из МассивСозданныхДокументов Цикл
        ОбъектДляПроведения = ДокСсылка.ПолучитьОбъект();
        Попытка
            ОбъектДляПроведения.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный);
        Исключение
            Сообщить("Ошибка при оперативном проведении: " + ОписаниеОшибки());
        КонецПопытки;
    КонецЦикла;

КонецПроцедуры

Вариант 3. Раздельная печать сборочных листов без дробления заказа

Дробление исходного Заказа покупателя на несколько отдельных документов несет существенный минус: при отказе клиента от части позиций менеджеру приходится корректировать 3–4 документа параллельно. Чтобы избежать лишней путаницы, рекомендуется сохранять один родительский Заказ покупателя, а на склады отправлять индивидуальные сборочные листы.

Для программной отправки отфильтрованных табличных документов на удаленные складские принтеры используем следующие свойства и методы объекта ТабличныйДокумент:


Процедура НапечататьЛистыСборкиПоСкладам(ЗаказСсылка)
    
    // Получаем перечень складов и товаров из табличной части заказа
    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("ЗаказСсылка", ЗаказСсылка);
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    Товары.Склад КАК Склад,
        |    Товары.Номенклатура КАК Номенклатура,
        |    Товары.Количество КАК Количество,
        |    Товары.ЕдиницаИзмерения КАК ЕдиницаИзмерения
        |ИЗ
        |    Документ.ЗаказПокупателя.Товары КАК Товары
        |ГДЕ
        |    Товары.Ссылка = &ЗаказСсылка
        |ИТОГИ ПО
        |    Склад";
        
    РезультатЗапроса = Запрос.Выполнить();
    ВыборкаСклад = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    
    Макет = ПолучитьМакет("СборочныйЛист");
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    
    Пока ВыборкаСклад.Следующий() Цикл
        
        ТабДок = Новый ТабличныйДокумент;
        ТабДок.ПолеСверху = 0;
        ТабДок.ПолеСнизу = 0;
        ТабДок.ПолеСлева = 0;
        ТабДок.ПолеСправа = 0;
        
        ОбластьШапка.Параметры.НомерЗаказа = ЗаказСсылка.Номер;
        ОбластьШапка.Параметры.ДатаЗаказа = ЗаказСсылка.Дата;
        ОбластьШапка.Параметры.Склад = ВыборкаСклад.Склад;
        ТабДок.Вывести(ОбластьШапка);
        
        ВыборкаДетали = ВыборкаСклад.Выбрать();
        Пока ВыборкаДетали.Следующий() Цикл
            ОбластьСтрока.Параметры.Заполнить(ВыборкаДетали);
            ТабДок.Вывести(ОбластьСтрока);
        КонецЦикла;
        
        // Определяем сетевой путь к принтеру склада (из реквизита или регистра сведений)
        СетевойПринтер = ВыборкаСклад.Склад.ПринтерЧеков; // Пример: "\\Server\Print_Sklad_1"
        
        Если ЗначениеЗаполнено(СетевойПринтер) Тогда
            ТабДок.ИмяПринтера = СетевойПринтер;
            // Печать без отображения диалога пользователю
            ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
        КонецЕсли;
        
    КонецЦикла;

КонецПроцедуры

Тонкости организации удаленной печати и взаимодействия с БП

При реализации межскладской сборки следует учитывать важные инфраструктурные и методологические ограничения:

  1. Работа в терминале (RDP). Если операторы подключены через RDP, перенаправленные порты клиентов получают суффиксы вида (перенаправлено N). Прямая печать по имени в таком случае дает сбой. Сетевые принтеры складов необходимо устанавливать непосредственно на сервере терминалов по постоянным TCP/IP-портам или подключать через UNC-пути (\\PrintServer\SharedPrinterName).
  2. Чековые принтеры (термопринтеры 58/80 мм). При выводе обычного макета на узкую ленту часто возникают разрывы страниц или пустые отступы. Для термопринтеров в настройках драйвера Windows выбирают размер бумаги формата Roll Paper, либо настраивают драйвер Generic / Text Only для быстрой текстовой печати.
  3. Обмен с конфигурацией «Бухгалтерия предприятия» (БП). В типовой БП документ Реализация товаров и услуг содержит реквизит Склад исключительно в шапке документа. Если оставить в УТ 10.3 один документ реализации с разными складами в строках, при выгрузке в БП возникнет сбой: списание себестоимости по счету 41 пройдет по одному складу из шапки. Поэтому итоговые документы реализации перед выгрузкой в бухгалтерию должны быть обязательно разделены по отдельным складам.
  4. Альтернатива безбумажного склада (монитор сборщика). Вместо риска замятия ленты в чековых принтерах на складах целесообразно использовать рабочие мониторы или планшеты. Обработка с интервалом обновления через ПодключитьОбработчикОжидания() отображает строки заказа, относящиеся к данному складу. Кладовщик по факту отбора нажимает кнопку «Собрано», что мгновенно отражается в общей базе.
← На главную