Как реализовать адресное хранение и правильно удалять товар из ячейки в 1С?

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

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

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

Анализ первоначальной архитектуры и ее главный недостаток

В исходной задаче была предложена следующая структура объектов:

  1. Справочник "Ячейки" — для хранения списка складских ячеек.
  2. Регистр сведений "РазмещениеВЯчейках" — для хранения информации о том, какой товар в какой ячейке лежит.
    • Измерения: Склад, Номенклатура.
    • Ресурс: Ячейка.
  3. Документ "РазмещениеВЯчейке" — для регистрации операций. В табличной части указывается номенклатура, ячейка и действие («Разместить» или «Убрать»).

Основная проблема этой архитектуры кроется в структуре регистра сведений. Поскольку измерениями являются Склад и Номенклатура, система обеспечивает уникальность записей именно по этой связке. На практике это означает, что для одной номенклатуры в рамках одного склада может быть указана только одна ячейка.

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

Как технически отразить "удаление" товара из ячейки?

Автор задал конкретный вопрос: что писать в коде, если пользователь выбрал действие «Убрать»? На форуме был предложен вариант:

Движение.Ячейка = Справочники.Ячейки.ПустаяСсылка();

Хотя автор принял это решение, оно является не совсем корректным с точки зрения идеологии регистров. Этот код не удаляет запись из регистра. Он оставляет запись о связке Склад + Номенклатура, но в качестве ячейки указывает пустое значение. Это может привести к "замусориванию" регистра и неверной логике в отчетах. Вы будете видеть, что товар где-то числится, но его ячейка не определена.

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

Рассмотрим, как должен выглядеть код в обработке проведения документа.


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    
    // Очищаем существующие движения документа, чтобы избежать дублей
    Движения.РазмещениеВЯчейках.Записать(); 
    
    // Создаем набор записей для добавления новых данных
    НаборЗаписей = Движения.РазмещениеВЯчейках;
    
    Для Каждого ТекСтрокаТовары Из Товары Цикл
        
        Если ТекСтрокаТовары.Действие = Перечисления.ДействияСЯчейкой.Разместить Тогда
            // Если действие "Разместить", добавляем новую запись в регистр
            Движение = НаборЗаписей.Добавить();
            Движение.Период = Дата;
            Движение.Склад = Склад;
            Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;
            Движение.Ячейка = ТекСтрокаТовары.Ячейка;
        ИначеЕсли ТекСтрокаТовары.Действие = Перечисления.ДействияСЯчейкой.Убрать Тогда
            // Если действие "Убрать", мы должны найти и удалить существующую запись.
            // При текущей архитектуре (одна ячейка на товар) достаточно просто НЕ добавлять новую запись,
            // т.к. старая будет удалена при очистке движений документа, если этот же документ ее и создал.
            // Но более универсальный способ — использовать менеджер записи для удаления.
            
            МенеджерЗаписи = РегистрыСведений.РазмещениеВЯчейках.СоздатьМенеджерЗаписи();
            МенеджерЗаписи.Склад = Склад;
            МенеджерЗаписи.Номенклатура = ТекСтрокаТовары.Номенклатура;
            
            // Читаем запись по измерениям
            МенеджерЗаписи.Прочитать();
            
            // Если запись существует, удаляем ее
            Если МенеджерЗаписи.Выбран() Тогда
                МенеджерЗаписи.Удалить();
            КонецЕсли;
        КонецЕсли;
        
    КонецЦикла;
    
    // Записываем только те движения, которые были добавлены (для действия "Разместить")
    НаборЗаписей.Записать();
    
КонецПроцедуры

Этот код более правильный, но он все еще работает в рамках flawed architecture. Давайте разберем, как можно улучшить саму структуру.

Как спроектировать правильную структуру для адресного хранения?

Чтобы решить проблему "один товар — одна ячейка", необходимо изменить саму архитектуру хранения данных.

Решение 1: Изменить структуру регистра сведений

Чтобы разрешить хранение одного товара в нескольких ячейках, нужно сделать уникальным ключ, включающий саму ячейку. Для этого перенесем поле Ячейка из ресурсов в измерения.

Новая структура регистра РазмещениеВЯчейках:

Теперь уникальной будет связка «Склад + Номенклатура + Ячейка», что позволяет для одной и той же номенклатуры создать несколько записей с разными ячейками. Это уже гораздо ближе к реальным потребностям склада.

Решение 2: Использовать регистр накопления

Если кроме факта размещения нужно отслеживать и количество товара в каждой ячейке, то регистр сведений — неподходящий инструмент. Для учета остатков предназначен регистр накопления вида «Остатки».

Правильная структура для учета остатков в ячейках:

При проведении документа «РазмещениеВЯчейке» нужно будет формировать движения с видом «Приход» или «Расход» по этому регистру, увеличивая или уменьшая остаток товара в конкретной ячейке.

Не изобретайте велосипед: используйте штатные механизмы 1С

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

1. Справочное хранение в ячейках

Это самый простой режим. Его суть — закрепить за номенклатурой основное место хранения. Система не следит за остатками в ячейках, а лишь предоставляет информацию кладовщику, где обычно лежит тот или иной товар. Это упрощает поиск, но не является полноценной системой WMS.

2. Адресное хранение остатков (ордерная схема)

Это полноценная WMS-система, которая ведет точный учет остатков товаров в разрезе каждой ячейки. Для ее работы необходимо включить ордерную схему документооборота на складе.

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

← На главную