Как правильно реализовать резервирование товаров в 1С: выбор между отдельным регистром и измерением?

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

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

Вариант 1: Использование дополнительного измерения «Заказ» в регистре остатков

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

Плюсы:

  1. Простота запросов: Нам не нужно соединять две таблицы в запросе, чтобы получить общую картину. Мы просто получаем остатки по регистру.
  2. Целостность данных: Товар физически «перемещается» с пустого заказа на конкретный заказ в рамках одного движения.

Минусы (критические):

  1. Взрывной рост таблицы итогов: Это самая серьезная проблема. В 1С итоги хранятся в разрезе уникальных комбинаций всех измерений. Если у вас 1000 товаров и 10 складов, в таблице итогов будет максимум 10 000 записей. Но если вы добавите измерение Заказ, и у вас будет 50 000 заказов, количество записей в таблице итогов может вырасти до миллионов. Это приведет к колоссальному замедлению получения остатков и проведения документов.
  2. Блокировки данных: При проведении документа по регистру остатков система устанавливает блокировки. Если резерв находится в том же регистре, что и основные остатки, транзакции по резервированию будут конфликтовать с транзакциями по обычной отгрузке, даже если они не пересекаются по смыслу.

Вариант 2: Использование отдельного регистра накопления «Резервы товаров»

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

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

Преимущества этого метода:

  1. Гибкость аналитики: В регистре остатков нам важны Склад и Серия. В резервах же нам может быть не важно, из какой ячейки или какой серии будет взят товар, но важен Менеджер или ДатаСнятияРезерва. Разделение регистров позволяет не перегружать лишними данными основную таблицу остатков.
  2. Производительность: Таблица итогов основного регистра остается компактной. Выборка свободного остатка происходит быстро через соединение двух небольших таблиц.
  3. Параллельность работы: Менеджеры, резервирующие товар, меньше мешают складским работникам, оформляющим фактические отгрузки, так как запись идет в разные таблицы БД.

Посмотрим на пример запроса для получения свободного остатка при такой архитектуре:


ВЫБРАТЬ
    Остатки.Номенклатура КАК Номенклатура,
    ЕСТЬNULL(Остатки.КоличествоОстаток, 0) - ЕСТЬNULL(Резервы.КоличествоОстаток, 0) КАК СвободныйОстаток
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК Остатки
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезерве.Остатки(&Период, ) КАК Резервы
    ПО Остатки.Номенклатура = Резервы.Номенклатура
    И Остатки.Склад = Резервы.Склад

Вариант 3: Дополнительный ресурс в регистре остатков

Выясним, когда уместно использовать вариант с добавлением ресурса ВРезерве в основной регистр. В этом случае структура регистра выглядит так: Измерения (Номенклатура, Склад), Ресурсы (ВНаличии, Зарезервировано).

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

Однако, если бизнес-процесс требует отслеживать сроки резервов, частичное снятие по конкретным заказам или перерезервирование между клиентами, этот метод быстро станет тупиковым из-за отсутствия аналитики по заказам.

Вариант 4: Динамический расчет («Неявный резерв»)

Проанализируем ситуацию, когда данные о резервах вообще не пишутся в регистры накопления. Система может рассчитывать резерв «на лету», суммируя количество в документах ЗаказПокупателя, которые еще не закрыты и не отгружены.

Когда это эффективно: Если количество активных (невыполненных) заказов невелико. В этом случае мы экономим на дисковом пространстве и исключаем ошибки рассогласования регистров и документов.

Когда это опасно: Если заказов тысячи, запрос на расчет остатков с учетом резервов превратится в тяжелую операцию сканирования таблиц документов, что недопустимо для оперативной работы менеджера.

Сложные случаи: Резервирование «в пути»

В современных ERP-системах часто требуется резервировать товар, которого еще нет на складе, но который уже заказан у поставщика. Реализовать это через измерение в регистре складских остатков невозможно, так как физический остаток еще не возник.

Рассмотрим архитектуру «Запасы и потребности». Это отдельный регистр, где учитываются:

Это наиболее продвинутый вариант, позволяющий реализовать схему Intercompany или резервирование под будущие даты поставки.

Выводы и рекомендации

Подведем итог нашему анализу. Выбор метода зависит от сложности вашего бизнес-процесса:

  1. Если конфигурация простая, и резерв — это просто временная блокировка товара на пару часов без привязки к глубокой аналитике, используйте дополнительный ресурс в регистре остатков.
  2. Если важна история заказов, отчетность по выполнению заявок и перерезервирование — используйте отдельный регистр «Резервы». Это обеспечит максимальную гибкость и производительность при масштабировании.
  3. Никогда не используйте измерение «Заказ» в основном регистре остатков, если планируете иметь более нескольких сотен активных заказов одновременно — это приведет к деградации базы данных.

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

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

← На главную