Как реализовать автоматический подбор оптимальной ячейки для заказов разного размера в 1С

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

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

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

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

Логика выбора для "маленького" заказа должна быть следующей:

  1. Исключить ячейки, занятые "обычным" заказом.
  2. Исключить ячейки, где уже лежат два "маленьких" заказа.
  3. В приоритете выбрать ячейку, где уже есть один "маленький" заказ.
  4. Если таких нет — выбрать пустую ячейку.

Разработка запроса для подбора ячейки

Рассмотрим основной программный метод решения этой задачи. Для получения корректных данных нам потребуется выполнить ЛЕВОЕ СОЕДИНЕНИЕ справочника ячеек с данными регистра сведений. Это позволит нам увидеть даже те ячейки, в которых на данный момент ничего не хранится.

Проанализируем пример кода запроса, который решает данную задачу:


ВЫБРАТЬ
    Ячейки.Ссылка КАК Ячейка,
    ЕСТЬNULL(Размещение.ТипЗаказаМаленький, ЛОЖЬ) КАК ЭтоМаленькийЗаказ,
    КОЛИЧЕСТВО(Размещение.Заказ) КАК КоличествоЗаказов
ПОМЕСТИТЬ ВтРазмещение
ИЗ
    Справочник.Ячейки КАК Ячейки
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РазмещениеЗаказов КАК Размещение
        ПО Ячейки.Ссылка = Размещение.Ячейка
СГРУППИРОВАТЬ ПО
    Ячейки.Ссылка,
    ЕСТЬNULL(Размещение.ТипЗаказаМаленький, ЛОЖЬ)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПЕРВЫЕ 1
    ВтРазмещение.Ячейка КАК ОптимальнаяЯчейка
ИЗ
    ВтРазмещение КАК ВтРазмещение
ГДЕ
    (ВтРазмещение.КоличествоЗаказов = 0)
    ИЛИ (ВтРазмещение.ЭтоМаленькийЗаказ = ИСТИНА И ВтРазмещение.КоличествоЗаказов < 2)

УПОРЯДОЧИТЬ ПО
    ВтРазмещение.КоличествоЗаказов УБЫВ

Рассмотрим подробнее, что происходит в этом запросе. В первой части мы собираем информацию о текущем заполнении склада. Мы используем функцию КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...) или обычное количество, чтобы понять, сколько заказов уже закреплено за каждой ячейкой. Во второй части мы накладываем фильтры: нам подходят либо абсолютно пустые ячейки (КоличествоЗаказов = 0), либо те, где лежит один маленький заказ.

Обратите внимание на конструкцию УПОРЯДОЧИТЬ ПО КоличествоЗаказов УБЫВ. Это критически важный момент для "уплотнения" склада. Сортировка по убыванию количества (от 1 к 0) заставит систему сначала предложить ячейку, которая уже частично занята, и только потом — новую пустую.

Учет типов данных и оптимизация

В процессе реализации мы можем столкнуться с тем, что тип заказа определяется не строкой, а признаком Булево (например, ЭтоМаленькийЗаказ). В таком случае запрос становится более производительным. Посмотрим на пример того, как можно оптимизировать условия:

Если в ячейке может находиться "обычный" заказ, он занимает её целиком. В регистре это может выглядеть как одна запись с флагом ЭтоМаленькийЗаказ = ЛОЖЬ. Чтобы наш алгоритм не подселил к нему маленький заказ, мы должны строго проверять состав ячейки. Если в результатах группировки для одной ячейки есть хотя бы одна запись, где флаг равен ЛОЖЬ, такая ячейка должна быть исключена полностью.

Профессиональные методики: WMS-подход

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

  1. Блокировки данных: При работе нескольких кладовщиков одновременно может возникнуть ситуация "гонки" (race condition), когда система выдаст одну и ту же ячейку двум разным людям. Чтобы этого избежать, используйте объект БлокировкаДанных перед выполнением запроса.
  2. Зонирование (ABC-анализ): Маленькие заказы часто собираются быстрее. Проанализируем ситуацию: разумно будет добавить в запрос условие по реквизиту Ячейка.ЗонаХранения, чтобы система подбирала места в зоне быстрого доступа (нижние ярусы, ближе к зоне комплектации).
  3. Обходной путь: Чтобы кладовщик не перемещался по складу хаотично, добавьте в УПОРЯДОЧИТЬ ПО индекс сортировки ячейки (адресный путь). Это позволит выдавать ячейки по порядку их расположения на стеллажах.

Использование в интерфейсе (СКД и формы)

Для реализации кнопки "Подобрать оптимальную ячейку" на форме документа Размещение, удобнее всего вызывать описанный выше запрос в фоновом задании или непосредственно в обработчике нажатия. Если же вам нужно наглядное представление занятости склада, разберем решение через СКД.

В системе компоновки данных вы можете настроить Условное оформление, которое будет подсвечивать ячейки:

Такой подход позволит диспетчеру склада визуально оценивать эффективность использования пространства и принимать решения о необходимости перемещения (уплотнения) товаров вручную.

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

← На главную