При автоматизации складских процессов часто возникает классическая задача: документ сборки (заказ) настолько велик, что его должны собирать сразу несколько сотрудников с терминалами сбора данных (ТСД). Основная сложность здесь заключается не только в технической блокировке объекта 1С, но и в логическом разделении труда, чтобы два человека не пошли к одной полке за одним и тем же товаром. Разберем наиболее эффективные методы реализации такой работы в среде 1С:Предприятие.
Наиболее надежный и масштабируемый способ — это отказ от прямой работы ТСД с табличной частью документа. Вместо этого мы создадим промежуточное звено. Рассмотрим ситуацию: при проведении или подготовке документа «Сборка» система должна автоматически формировать записи в специальном РегистреСведений (например, «ОчередьЗаданийСклада»).
Структура регистра может быть следующей:
ДокументОснование, Номенклатура, Характеристика, Ячейка.КоличествоПлан, КоличествоФакт.Исполнитель (ссылка на пользователя ТСД), Статус (перечисление: В очереди, Выполняется, Завершено).Проанализируем алгоритм работы: когда сотрудник на ТСД открывает задание, система не открывает сам документ, а делает запрос к этому регистру. Чтобы исключить дублирование, мы используем механизм «захвата» задачи. Программа ищет свободные строки по документу и проставляет в них текущего Исполнителя и статус «Выполняется».
Рассмотрим пример кода для захвата порции заданий:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 5
| ОчередьЗаданий.Номенклатура,
| ОчередьЗаданий.КоличествоПлан
|ИЗ
| РегистрСведений.ОчередьЗаданийСклада КАК ОчередьЗаданий
|ГДЕ
| ОчередьЗаданий.ДокументОснование = &Документ
| И ОчередьЗаданий.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыЗаданий.ВЗолотойОчереди)";
// После получения строк, обновляем их статус в транзакции
НачатьТранзакцию();
Для Каждого СтрокаЗапроса Из РезультатЗапроса Цикл
МенеджерЗаписи = РегистрыСведений.ОчередьЗаданийСклада.СоздатьМенеджерЗаписи();
// Заполнение ключевых полей...
МенеджерЗаписи.Исполнитель = ПараметрыСеанса.ТекущийПользователь;
МенеджерЗаписи.Статус = Пречисления.СтатусыЗаданий.Выполняется;
МенеджерЗаписи.Записать();
КонецЦикла;
ЗафиксироватьТранзакцию();
Если склад разделен на зоны (например, зона мелкоштучного товара и зона паллетного хранения), целесообразно делить один большой заказ на несколько «Отборочных листов». В этом случае каждый ОтборочныйЛист — это отдельный подчиненный документ. Проблема одновременной работы решается сама собой: один сотрудник берет один лист и работает с ним, не блокируя работу другого.
Разберем преимущества этого подхода. Во-первых, это физическое разделение потоков — сотрудники не сталкиваются в одном проходе. Во-вторых, упрощается контроль: мы всегда видим, какая часть общего заказа уже собрана. После завершения всех листов основной документ «Сборка» автоматически заполняется суммарными данными. Выясним причину популярности этого метода: он лучше всего соответствует реальным складским процессам крупных дистрибьюторов.
Современные ТСД чаще всего работают через HTTP-сервисы. Это позволяет избежать прямого подключения через RDP и проблем с блокировками объектов 1С. В этом сценарии 1С выступает в роли Backend-сервера. Когда сотрудник сканирует товар, ТСД отправляет асинхронный запрос.
Как предотвратить сканирование одного товара дважды в этой схеме?
Мы можем использовать временную таблицу в оперативной памяти сервера или быстрый РегистрСведений, где фиксируются все «сканы» в реальном времени. Если два сотрудника одновременно сканируют одну и ту же позицию, сервер примет запрос от того, кто прислал его на долю секунды раньше. Второй сотрудник мгновенно получит на экране ТСД сообщение: «Ошибка: товар уже обрабатывается другим сотрудником».
Посмотрим на пример обработки входящего сканирования через HTTP-сервис:
Функция ОбработатьСкан(ДанныеСканирования)
// 1. Проверяем, не занята ли эта строка (или марка Честный Знак) другим ТСД
Если СтрокаУжеЗаблокирована(ДанныеСканирования.Штрихкод) Тогда
Возврат Новый HTTPСервисОтвет(409); // Conflict
КонецЕсли;
// 2. Записываем результат сканирования в промежуточную таблицу
ЗаписатьРезультатСканирования(ДанныеСканирования);
Возврат Новый HTTPСервисОтвет(200);
КонецФункции
Проанализируем ситуацию, когда нам всё же нужно работать с одним документом. В этом случае мы можем применить стратегию «виртуального сведения». Каждый ТСД ведет свой собственный список собранного товара локально или в отдельном документе-черновике. В основном документе сборки данные отсутствуют до самого последнего момента.
Когда последний сборщик нажимает кнопку «Завершить», система запускает процедуру консолидации. Она собирает данные из всех черновиков, привязанных к этому заказу, сворачивает их по номенклатуре и сериям, и только тогда заполняет финальную табличную часть документа СборкаТоваров. Это гарантирует, что ОбъектЗаблокирован не возникнет в процессе работы, так как запись в основной документ происходит единожды в конце процесса.
Если ваша сборка включает маркированную продукцию («Честный Знак»), задача упрощается и одновременно усложняется. Упрощается она тем, что каждая марка уникальна. Два сотрудника физически не могут отсканировать одну и ту же марку, если они не держат в руках одну и ту же коробку. Однако, чтобы система не выдала ошибку при записи в 1С, необходимо на уровне базы данных проверять уникальность каждой считанной марки среди всех участников процесса сборки. Для этого идеально подходит РегистрСведений с единственным измерением — ЗначениеМарки, который служит глобальным кэшем для текущих операций сборки.
Подводя итог, выделим основные шаги для реализации коллективной сборки:
Следуя этим принципам, мы исключим конфликты блокировок и обеспечим прозрачный контроль за работой каждого складского сотрудника в рамках одного общего заказа.