7 ошибок настройки маршрутов согласования в 1С:ДО

Почему документы «зависают» в согласовании: реальная проблема реального бизнеса
Картина знакома каждому, кто работает с 1С:Документооборот в крупной компании: договор отправлен на согласование три недели назад, контрагент уже звонит с претензиями, а документ тихо «висит» на каком-то этапе маршрута. Никаких уведомлений, никаких эскалаций — просто тишина. Бизнес-процесс де-факто остановился, хотя в системе формально числится «в работе».
По данным внутренних аудитов, которые проводят внедренцы 1С, от 30 до 60% проблем с согласованием в 1С:Документооборот связаны не с нежеланием сотрудников работать и не с техническими сбоями платформы — а с ошибками при первоначальной настройке маршрутов. Эти ошибки закладываются однажды и потом годами отравляют жизнь всей организации.
В этой статье мы разберём семь наиболее распространённых и критичных ошибок, которые допускают при настройке маршрутов согласования. Для каждой — объясним механизм возникновения, покажем, как её диагностировать, и дадим практические рекомендации по исправлению, включая примеры кода на встроенном языке 1С.
Ошибка №1: Отсутствие обработчика «Исполнитель не найден»
Как это происходит
Самая частая причина «вечного зависания» — маршрут настроен так, что исполнитель задачи определяется динамически (например, через реквизит документа «Ответственный» или через роль подразделения), но никто не предусмотрел ситуацию, когда этот реквизит пустой или роль не заполнена.
Система создаёт задачу, пытается определить адресата — и не находит его. В зависимости от версии платформы и конфигурации поведение может быть разным: задача либо создаётся «в никуда» (без исполнителя), либо процесс тихо останавливается без каких-либо ошибок в журнале регистрации.
Диагностика
Откройте список задач бизнес-процесса и найдите задачи с пустым полем «Исполнитель». Также полезно выполнить следующий запрос в консоли запросов:
// Поиск задач без исполнителя в незавершённых процессах
ВЫБРАТЬ
Задача.Ссылка КАК Задача,
Задача.БизнесПроцесс КАК Процесс,
Задача.Наименование КАК НаименованиеЗадачи,
Задача.Дата КАК ДатаСоздания
ИЗ
Задача.ЗадачаИсполнителя КАК Задача
ГДЕ
Задача.Выполнена = ЛОЖЬ
И Задача.ДатаНачала < &ДатаПроверки
И (Задача.Исполнитель = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)
ИЛИ Задача.РольИсполнителя = ЗНАЧЕНИЕ(Справочник.РолиИсполнителей.ПустаяСсылка))
УПОРЯДОЧИТЬ ПО
Задача.Дата
Как исправить
В шаблоне бизнес-процесса обязательно добавьте обработчик события ПередСозданиемЗадачи или используйте условный переход с проверкой на заполненность исполнителя. Пример обработчика:
// Обработчик события ПередСозданиемЗадачи для точки маршрута
Процедура МаршрутТочка1ПередСозданиемЗадачи(Точка, ДанныеЗадачи, СтандартнаяОбработка)
// Определяем исполнителя из реквизита документа
ОбъектДокумента = ДанныеЗадачи.Предмет.ПолучитьОбъект();
Если НЕ ЗначениеЗаполнено(ОбъектДокумента.Ответственный) Тогда
// Исполнитель не определён — назначаем ответственного за процесс
// или отправляем уведомление администратору
ДанныеЗадачи.Исполнитель = ПолучитьАдминистратораДокументооборота();
// Логируем ситуацию для последующего анализа
ЗаписатьПредупреждение(
"Маршрут согласования",
"Исполнитель не определён для документа: " + Строка(ОбъектДокумента),
ОбъектДокумента.Ссылка
);
КонецЕсли;
КонецПроцедуры
// Вспомогательная функция получения администратора
Функция ПолучитьАдминистратораДокументооборота()
// Получаем из настроек системы или константы
Возврат Константы.АдминистраторДокументооборота.Получить();
КонецФункции
Ошибка №2: Циклические маршруты без условия выхода
Механизм зависания
Циклические маршруты — мощный инструмент для итерационного согласования: документ дорабатывается, возвращается на повторное рассмотрение, снова уходит на доработку. Проблема возникает, когда разработчик создаёт цикл, но забывает задать условие выхода из него или задаёт его некорректно.
Классический сценарий: согласующий отклоняет документ, тот уходит на доработку к автору, автор вносит правки и снова отправляет на согласование — но условие «документ доработан» никогда не выполняется, потому что проверяется не тот реквизит или логика условия инвертирована.
Типичная ошибка в условии
// НЕПРАВИЛЬНО: условие никогда не завершит цикл
// Проверяем статус, но присваиваем его неверно
Функция УсловиеВыходаИзЦикла(БизнесПроцесс)
Документ = БизнесПроцесс.Предмет.ПолучитьОбъект();
// Ошибка: проверяем «Черновик» вместо «На согласовании»
// Документ никогда не будет в статусе «Черновик» после доработки
Если Документ.СтатусДокумента = Перечисления.СтатусыДокументов.Черновик Тогда
Возврат Истина; // Выходим из цикла
КонецЕсли;
Возврат Ложь; // Остаёмся в цикле
КонецФункции
// ПРАВИЛЬНО: корректная проверка с ограничением числа итераций
Функция УсловиеВыходаИзЦиклаКорректное(БизнесПроцесс)
Документ = БизнесПроцесс.Предмет.ПолучитьОбъект();
// Проверяем правильный статус
Если Документ.СтатусДокумента = Перечисления.СтатусыДокументов.Согласован Тогда
Возврат Истина;
КонецЕсли;
// Защита от бесконечного цикла: максимум 5 итераций
// Счётчик итераций хранится в реквизите процесса
Если БизнесПроцесс.КоличествоИтераций >= 5 Тогда
// Эскалируем на руководителя
БизнесПроцесс.ТребуетсяЭскалация = Истина;
Возврат Истина; // Принудительно выходим из цикла
КонецЕсли;
// Увеличиваем счётчик
БизнесПроцесс.КоличествоИтераций = БизнесПроцесс.КоличествоИтераций + 1;
БизнесПроцесс.Записать();
Возврат Ложь;
КонецФункции
Правило проектирования
Любой циклический маршрут должен иметь не менее двух условий выхода: содержательное (документ согласован) и защитное (превышено максимальное число итераций). Это не опциональная «хорошая практика» — это обязательное требование к архитектуре маршрута.
Ошибка №3: Неправильная настройка параллельного согласования
Суть проблемы
Параллельное согласование — когда документ одновременно уходит нескольким согласующим — экономит время. Но здесь есть коварная ловушка: настройка условия завершения параллельной точки.
В 1С:Документооборот параллельная точка может завершаться по разным правилам: когда все участники приняли решение, когда хотя бы один принял решение, когда набрано нужное количество голосов «за». Если настроить «завершение при решении всех», а один из согласующих уволился или заблокирован в системе — процесс встанет навсегда.
Диагностика зависших параллельных задач
// Находим параллельные точки, где часть задач выполнена, а часть — нет
ВЫБРАТЬ
БП.Ссылка КАК БизнесПроцесс,
БП.Наименование,
БП.Дата КАК ДатаЗапуска,
КОЛИЧЕСТВО(Задача.Ссылка) КАК ВсегоЗадач,
СУММА(ВЫБОР КОГДА Задача.Выполнена ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК ВыполненоЗадач,
СУММА(ВЫБОР КОГДА НЕ Задача.Выполнена ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК НевыполненоЗадач
ИЗ
БизнесПроцесс.Согласование КАК БП
ЛЕВОЕ СОЕДИНЕНИЕ Задача.ЗадачаИсполнителя КАК Задача
ПО БП.Ссылка = Задача.БизнесПроцесс
ГДЕ
БП.Завершён = ЛОЖЬ
И БП.Дата < ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -7)
СГРУППИРОВАТЬ ПО
БП.Ссылка,
БП.Наименование,
БП.Дата
ИМЕЮЩИЕ
СУММА(ВЫБОР КОГДА НЕ Задача.Выполнена ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) > 0
И СУММА(ВЫБОР КОГДА Задача.Выполнена ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) > 0
УПОРЯДОЧИТЬ ПО
ВыполненоЗадач УБЫВ
Рекомендации по настройке
Для параллельных точек всегда задавайте:
- Таймаут задачи — максимальное время ожидания ответа от одного участника
- Замещение — кто выполняет задачу, если основной исполнитель недоступен
- Правило завершения — «большинство» вместо «все», если бизнес-процесс это допускает
- Эскалацию — автоматический перевод задачи руководителю при просрочке
Ошибка №4: Игнорирование замещений и делегирования
Почему это критично
Сотрудники уходят в отпуск, болеют, увольняются. Если маршрут согласования жёстко привязан к конкретному пользователю (а не к роли или должности), любое его отсутствие превращается в стоп-кран для всего потока документов.
Типичная картина: юрист Иванова, которая согласует все договоры, ушла в декрет. IT-специалист добавил нового пользователя, но забыл настроить замещение в 1С:ДО. Теперь все договоры ждут Иванову, которая вернётся через полтора года.
Программная проверка настройки замещений
// Процедура проверки актуальности замещений для активных процессов
Процедура ПроверитьЗамещенияДляАктивныхПроцессов() Экспорт
ТекущаяДата = ТекущаяДата();
// Получаем всех исполнителей незавершённых задач
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Задача.Исполнитель КАК Исполнитель
|ИЗ
| Задача.ЗадачаИсполнителя КАК Задача
|ГДЕ
| Задача.Выполнена = ЛОЖЬ
| И Задача.Исполнитель <> ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
ПроблемныеИсполнители = Новый Массив;
Пока Выборка.Следующий() Цикл
Пользователь = Выборка.Исполнитель;
// Проверяем, активен ли пользователь
Если Пользователь.НедействующийПользователь Тогда
ПроблемныеИсполнители.Добавить(Пользователь);
Продолжить;
КонецЕсли;
// Проверяем наличие активного замещения
ЕстьЗамещение = ПроверитьАктивноеЗамещение(Пользователь, ТекущаяДата);
// Проверяем, не в отпуске ли сотрудник (через HR-данные если интегрированы)
// ЕстьОтпуск = ПроверитьОтпуск(Пользователь, ТекущаяДата);
Если НЕ ЕстьЗамещение И НЕ Пользователь.Активен Тогда
ПроблемныеИсполнители.Добавить(Пользователь);
КонецЕсли;
КонецЦикла;
// Отправляем отчёт администратору
Если ПроблемныеИсполнители.Количество() > 0 Тогда
ОтправитьУведомлениеАдминистратору(ПроблемныеИсполнители);
КонецЕсли;
КонецПроцедуры
// Проверка наличия активного замещения
Функция ПроверитьАктивноеЗамещение(Пользователь, НаДату)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Замещение.Ссылка
|ИЗ
| РегистрСведений.Замещения КАК Замещение
|ГДЕ
| Замещение.Сотрудник = &Пользователь
| И Замещение.НачалоЗамещения <= &НаДату
| И (Замещение.ОкончаниеЗамещения >= &НаДату
| ИЛИ Замещение.ОкончаниеЗамещения = ДАТАВРЕМЯ(1, 1, 1))";
Запрос.УстановитьПараметр("Пользователь", Пользователь);
Запрос.УстановитьПараметр("НаДату", НаДату);
Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции
Ошибка №5: Отсутствие таймаутов и эскалаций
«Вечная задача» как норма
Одна из самых распространённых ошибок — настройка маршрута без каких-либо временных ограничений. Теоретически согласующий должен обработать задачу в разумные сроки. На практике задача тонет в потоке других дел, откладывается «на потом» и в итоге забывается.
Правильно спроектированный маршрут должен содержать явные таймауты на каждой точке и автоматическую эскалацию при их нарушении. Это не просто удобство — это обязательный элемент архитектуры любого корпоративного процесса согласования.
Настройка автоматической эскалации через регламентное задание
// Регламентное задание: проверка просроченных задач и эскалация
Процедура ЭскалироватьПросроченныеЗадачи() Экспорт
ТекущаяДата = ТекущаяДата();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Задача.Ссылка КАК Задача,
| Задача.Исполнитель КАК Исполнитель,
| Задача.БизнесПроцесс КАК БизнесПроцесс,
| Задача.СрокИсполнения КАК Срок,
| Задача.Наименование
|ИЗ
| Задача.ЗадачаИсполнителя КАК Задача
|ГДЕ
| Задача.Выполнена = ЛОЖЬ
| И Задача.СрокИсполнения < &ТекущаяДата
| И Задача.Эскалирована = ЛОЖЬ
| И РАЗНОСТЬДАТ(Задача.СрокИсполнения, &ТекущаяДата, ДЕНЬ) >= 1";
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Определяем руководителя исполнителя
Руководитель = ПолучитьРуководителя(Выборка.Исполнитель);
Если НЕ ЗначениеЗаполнено(Руководитель) Тогда
// Если руководитель не найден — уведомляем администратора ДО
Руководитель = Константы.АдминистраторДокументооборота.Получить();
КонецЕсли;
// Отправляем уведомление руководителю
ОтправитьУведомлениеОбЭскалации(
Руководитель,
Выборка.Исполнитель,
Выборка.Задача,
Выборка.Срок
);
// Помечаем задачу как эскалированную
ОбъектЗадачи = Выборка.Задача.ПолучитьОбъект();
ОбъектЗадачи.Эскалирована = Истина;
ОбъектЗадачи.ДатаЭскалации = ТекущаяДата;
ОбъектЗадачи.ЭскалированаК = Руководитель;
ОбъектЗадачи.Записать();
КонецЦикла;
КонецПроцедуры
// Отправка уведомления об эскалации
Процедура ОтправитьУведомлениеОбЭскалации(Руководитель, Исполнитель, Задача, Срок)
ТекстСообщения = СтрШаблон(
"Задача \"%1\" просрочена.%nИсполнитель: %2%nПлановый срок: %3%n" +
"Просрочка: %4 дн.%nПожалуйста, примите меры.",
Задача.Наименование,
Строка(Исполнитель),
Формат(Срок, "ДФ=дд.ММ.гггг"),
Строка(Цел(ТекущаяДата() - Срок) / 86400)
);
// Отправка через механизм уведомлений 1С:ДО
ДокументооборотКлиентСервер.ОтправитьУведомление(
Руководитель,
"Эскалация: просроченная задача согласования",
ТекстСообщения,
Задача
);
КонецПроцедуры
Рекомендуемая структура таймаутов
| Тип документа | Плановый срок | 1-я эскалация | 2-я эскалация |
|---|---|---|---|
| Договор типовой | 3 рабочих дня |