При организации складской логистики часто возникает задача равномерного распределения нагрузки между сотрудниками склада. Типичная ситуация: в течение дня поступают заказы различного объема, на складе работают несколько кладовщиков, и требуется распределить задачи так, чтобы исключить простои одних сотрудников при перегрузке других, а также точно знать, кто именно собирал конкретный товар.
Разберем типичные ошибки при реализации этого механизма, архитектурные особенности конфигураций 1С и эффективные способы распределения сборочных задач.
Рассмотрим две ключевые ошибки, с которыми часто сталкиваются разработчики при попытке быстро реализовать распределение:
СчетНаОплатуПокупателю для склада: В типовых конфигурациях (например, УПП 1.3) счет является исключительно расчетным документом. Он не формирует движений по регистрам накопления, не резервирует остатки на складах и может быть в любой момент изменен или отменен менеджером. Сборка по документу без проверки резерва ведет к попыткам отобрать отсутствующий товар.Вместо предварительного жесткого назначения сотрудника на заказ на этапе проведения документа гораздо эффективнее использовать модель динамической выдачи («вытягивающее» производство). Кладовщик получает следующее задание только тогда, когда фактически освободился.
Разберем по шагам, как работает этот процесс на бумажном складе без использования дорогостоящих терминалов сбора данных (ТСД):
Посмотрим на пример транзакционной выборки задачи из очереди с использованием механизма управляемых блокировок:
Функция НазначитьЗаказКладовщику(СотрудникСсылка) Экспорт
УстановитьПривилегированныйРежим(Истина);
НачатьТранзакцию();
Попытка
// Блокируем регистр очереди для исключения параллельного назначения
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ОчередьСборкиЗаказов");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Очередь.ДокументЗаказа КАК ДокументЗаказа,
| Очередь.Приоритет КАК Приоритет
|ИЗ
| РегистрСведений.ОчередьСборкиЗаказов КАК Очередь
|ГДЕ
| Очередь.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыСборки.КОтбору)
|УПОРЯДОЧИТЬ ПО
| Очередь.Приоритет УБЫВ,
| Очередь.ДатаПоступления ВОЗР";
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
ОтменитьТранзакцию();
Возврат Неопределено;
КонецЕсли;
Выборка = Результат.Выбрать();
Выборка.Следующий();
// Фиксируем назначение исполнителя
МенеджерЗаписи = РегистрыСведений.ОчередьСборкиЗаказов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ДокументЗаказа = Выборка.ДокументЗаказа;
МенеджерЗаписи.Прочитать();
МенеджерЗаписи.Статус = Перечисление.СтатусыСборки.ВРаботе;
МенеджерЗаписи.Исполнитель = СотрудникСсылка;
МенеджерЗаписи.ДатаВыдачи = ТекущаяДата();
МенеджерЗаписи.Записать();
ЗафиксироватьТранзакцию();
Возврат Выборка.ДокументЗаказа;
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецФункции
Если поступил один объемный заказ (например, на 1000 позиций), отправка одного кладовщика парализует его работу на полдня, пока второй сотрудник будет простаивать. Для решения этой проблемы заказ делится на кванты (сборочные задания).
Проанализируем параметры, по которым необходимо разбивать заказ:
Распределение заказов по простому количеству штук или документов создает перекос в нагрузке. Отобрать 100 штук одного товара с одной полки значительно быстрее, чем отобрать 100 разных позиций по 1 штуке из разных концов склада.
Для справедливого учета трудоемкости при расчете загрузки сотрудников применяем весовые коэффициенты:
Трудоемкость = (КоличествоСтрок * K1) + (ОбщийВес * K2) + (КоличествоШтук * K3)
Где коэффициенты отражают реальные затраты времени:
K1 — наибольший вес, так как переход между ячейками и поиск позиции занимают основную часть времени отбора.K2 — вес фактора перемещения тяжестей.K3 — минимальный вес, отражающий время на пересчет единиц внутри одной ячейки.Для корректного отражения процесса сборки в конфигурации рекомендуется уйти от прямой работы со счетами и использовать предназначенную для этого структуру:
РасходныйОрдерНаТовары. Документ содержит реквизит ответственного, фиксирует складские движения и имеет стандартные печатные формы отбора.ЗаказПокупателя. Документ хранит статус сборки, назначенного кладовщика, фактическое время начала и окончания работы.