Автоматическое создание документов в 1С для ордерного склада надёжнее всего строить через очередь задач: при проведении документа в регистр сведений ставится задача («создать или изменить расходный ордер по заказу»), а отдельный обработчик выбирает задачи по порядку, проверяет встречные изменения и создаёт или корректирует документы следующего уровня. Так заказ клиента, расходный ордер и отборы остаются согласованными, даже если клиент меняет заказ, а склад уже собирает товар.
Ниже — схема для УТ 11 / КА / ERP с ордерными складами: структура очереди, постановка задач из расширения, обработка с блокировками и правила разрешения конфликтов «с двух концов».
Цепочка документов ордерного склада и где ломается ручной ввод
Типовая цепочка отгрузки с ордерного склада:
- Заказ клиента — менеджер или импорт с сайта.
- Расходный ордер на товары — распоряжение складу.
- Отбор (размещение) товаров — задание кладовщику; по одному ордеру их может быть несколько.
- Реализация — после сборки.
Вручную через «Создать на основании» это работает, пока заказов немного. Когда заказы приходят из интернет-магазина сотнями, менеджеры не успевают создавать ордера, а склад простаивает. Первый шаг автоматизации очевиден — создавать следующий документ при проведении предыдущего, если выполнены условия: статус «К обеспечению», есть предоплата, подтверждение клиента.
Сложности начинаются с обратным потоком. Отбор может завершиться со статусом «выполнено с ошибками»: часть товара не нашли. Эти данные нужно поднять в расходный ордер, а оттуда — в заказ. А в это же время клиент звонит и уменьшает количество в той же позиции. Два изменения идут навстречу друг другу, и без правил одно перезапишет другое или они сложатся.

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

Самое важное в механизме — договориться о правилах, когда изменения приходят с двух сторон:
- Факт важнее плана. Сначала применяется результат отбора (что реально собрано), затем изменения клиента. Поэтому задача
ОрдерПоЗаказуждёт, пока обработается встречнаяОрдерПоОтборупо тому же ордеру. - Пересчёт, а не приращение. Ордер не «уменьшается на разницу», а пересчитывается из текущего заказа и фактов отборов. Тогда порядок применения не приводит к двойному вычитанию.
- Отборы в работе не трогаем. Если по позиции отбор уже выполняется, изменение заказа порождает размещение (возврат на полки) после завершения отбора, а не правку отбора под руками кладовщика.
- Повтор вместо ошибки. Если документ заблокирован пользователем, задача остаётся необработанной и берётся при следующем запуске.
Функция ЕстьВстречнаяЗадача проверяет по объекту и связанным документам, нет ли в очереди необработанных задач обратного направления. Карту «какая задача какой мешает» удобно держать в одном месте — в общем модуле очереди.
Запуск и мониторинг
- Регламентное задание раз в одну–две минуты обрабатывает задачи всех видов в порядке: обратный поток, затем прямой.
- В конфигурациях на БСП альтернативой служит дополнительная обработка с командой вида «ВызовСерверногоМетода» и расписанием — её проще поправить без обновления конфигурации.
- Отчёт по регистру очереди с отбором «Ошибка = Истина» — ежедневный рабочий инструмент ответственного за склад.
- Обработанные задачи старше месяца удаляются отдельным заданием.
Такие механизмы я делаю в расширениях, чтобы не снимать типовую с поддержки, — см. расширения 1С и доработку 1С под складские процессы.
Типичные ошибки
- Создание подчинённых документов внутри проведения заказа — долгие блокировки и откат заказа при любой ошибке.
- Запись результата задачи внутри транзакции — при откате теряется описание ошибки.
- Приращение количества вместо пересчёта — двойное списание при встречных изменениях.
- Отсутствие проверки
ОбменДанными.Загрузка— задачи создаются при загрузке из обменов. - Одна транзакция на всю очередь — один проблемный заказ останавливает весь склад.
Итог
- Проведение документа только ставит задачу в очередь, документы создаёт отдельный обработчик.
- Каждая задача — в своей транзакции с управляемой блокировкой, результат пишется после неё.
- Встречные задачи разрешаются правилами: факт важнее плана, пересчёт вместо приращения.
- Очередь в регистре сведений одновременно служит журналом ошибок для пользователей.




