Как реализовать автоподстановку «Все руководители автора документа, кроме последнего» в 1С:Документооборот

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

В процессе настройки согласования в 1С:Документооборот часто возникает потребность в гибком подборе исполнителей. Типовые автоподстановки позволяют выбрать всех руководителей или только непосредственного начальника, но бизнес-логика иногда требует исключить из цепочки «самого главного» — например, руководителя службы или директора предприятия, чтобы не отвлекать их от рутинных задач. В этой статье мы подробно разберем, как написать и внедрить собственную автоподстановку «Все руководители автора, кроме последнего».

Постановка задачи и выбор места для разработки

Представим структуру: Контролер — Заместитель старшего контролера — Старший контролер — Руководитель службы качества. Нам нужно, чтобы документ прошел согласование по всей цепочке вверх, но остановился на Старшем контролере, не попадая к Руководителю службы. Для реализации этого функционала нам потребуется внести изменения в общий модуль ШаблоныБизнесПроцессовПереопределяемый. Именно этот модуль предназначен для расширения списка функций автоподстановки без вмешательства в ядро системы.

Шаг 1. Регистрация новой функции автоподстановки

Чтобы система «увидела» нашу функцию в адресной книге или в шаблоне процесса, ее нужно зарегистрировать в функции ПолучитьСписокДоступныхФункций. Рассмотрим, как правильно дополнить этот список, чтобы не нарушить работу существующих механизмов.

Проанализируем пример кода для регистрации:


Функция ПолучитьСписокДоступныхФункций(ИменаПредметовДляФункций) Экспорт
    ДоступныеФункции = Новый СписокЗначений;
    
    // Регистрируем функцию для автора самого процесса
    ДоступныеФункции.Добавить("ШаблоныБизнесПроцессовПереопределяемый.ВсеРуководителиАвтораБизнесПроцессаКромеПоследнего(Объект)", 
        "Все руководители автора бизнес процесса кроме последнего");
        
    Если ИменаПредметовДляФункций <> Неопределено Тогда
        Если ИменаПредметовДляФункций.Количество() > 0 Тогда
            Для Каждого ИмяПредмета Из ИменаПредметовДляФункций Цикл
                // Регистрируем функцию для конкретного предмета (документа)
                ДоступныеФункции.Добавить("ШаблоныБизнесПроцессовПереопределяемый.ВсеРуководителиАвтораДокументаКромеПоследнего(Объект, ИмяПредмета)", 
                    СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
                        НСтр("ru = '%1.Все руководители автора документа кроме последнего'"), Строка(ИмяПредмета)));
            КонецЦикла;
        КонецЕсли;
    КонецЕсли;
    
    Возврат ДоступныеФункции;
КонецФункции

Важный нюанс: при редактировании этого модуля убедитесь, что вы не дублируете функцию ПолучитьСписокДоступныхФункций, если она уже создана. Нужно просто дописать свои строки в существующее тело функции. Также обратите внимание на Возврат ДоступныеФункции — он должен стоять в самом конце, вне цикла, иначе регистрация прервется на первом же предмете.

Шаг 2. Реализация логики поиска руководителей по иерархии

Теперь разберем алгоритм поиска. Нам нужно двигаться от подразделения автора вверх к родительским подразделениям, собирать их руководителей и остановиться за шаг до «вершины». Выясним причину, по которой мы используем цикл Пока: структура предприятия может иметь неограниченную вложенность.

Рассмотрим код основной функции:


Функция ВсеРуководителиАвтораДокументаКромеПоследнего(БизнесПроцессОбъект, ИмяПредмета) Экспорт
    // 1. Поиск предмета в процессе
    СтрокаПредмета = БизнесПроцессОбъект.Предметы.Найти(ИмяПредмета, "ИмяПредмета");
    Если СтрокаПредмета = Неопределено Тогда
        // Если предмет не найден по имени, попробуем взять основной (индекс 0)
        Если БизнесПроцессОбъект.Предметы.Количество() > 0 Тогда
            СтрокаПредмета = БизнесПроцессОбъект.Предметы[0];
        Иначе
            Возврат Новый Массив;
        КонецЕсли;
    КонецЕсли;

    // 2. Определение автора документа
    АвторДокумента = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СтрокаПредмета.Предмет, "Подготовил");
    МассивРуководителей = Новый Массив;

    // 3. Получение подразделения автора через регистр сведений
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	СведенияОПользователях.Подразделение КАК Подразделение
    |ИЗ
    |	РегистрСведений.СведенияОПользователяхДокументооборот КАК СведенияОПользователях
    |ГДЕ
    |	СведенияОПользователях.Пользователь = &Пользователь";
    Запрос.УстановитьПараметр("Пользователь", АвторДокумента);
    
    Результат = Запрос.Выполнить();
    Если Результат.Пустой() Тогда
        Возврат МассивРуководителей;
    КонецЕсли;
    
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    Подразделение = Выборка.Подразделение;

    // 4. Цикл по иерархии подразделений
    Пока ЗначениеЗаполнено(Подразделение) Цикл
        // Проверяем, есть ли у текущего подразделения вышестоящее (Родитель)
        // Если родителя нет, значит это "последнее" подразделение, и его руководителя мы не берем
        Если Не ЗначениеЗаполнено(Подразделение.Родитель) Тогда
            Прервать;
        КонецЕсли;

        РеквизитыПодразделения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Подразделение, 
            "Руководитель, Руководитель.Недействителен, Родитель");
        
        Руководитель = РеквизитыПодразделения.Руководитель;
        
        Если ЗначениеЗаполнено(Руководитель) И Руководитель <> АвторДокумента Тогда
            Если НЕ РеквизитыПодразделения.РуководительНедействителен Тогда
                МассивРуководителей.Добавить(Руководитель);
            КонецЕсли;
        КонецЕсли;
        
        Подразделение = РеквизитыПодразделения.Родитель;
    КонецЦикла;

    Возврат МассивРуководителей;
КонецФункции

Шаг 3. Обработка критических ошибок и исключений

Проанализируем ситуацию, описанную пользователями на практике: что произойдет, если у сотрудника всего один руководитель (он же последний)? В этом случае функция вернет пустой массив. Система 1С:Документооборот при попытке старта процесса выдаст критическую ошибку: Не найдены исполнители для автоподстановки.

Для решения этой проблемы рассмотрим два подхода:

  1. Настройка условий маршрутизации: В шаблоне бизнес-процесса перед этапом, где используется эта автоподстановка, добавьте условие. Проверяйте, является ли автор документа рядовым сотрудником с длинной цепочкой руководителей. Если руководителей недостаточно, направляйте процесс по другому пути или пропускайте шаг.
  2. Возврат системного пользователя: В коде функции, если МассивРуководителей.Количество() = 0, можно возвращать технического пользователя (например, администратора) или самого автора, чтобы процесс не «падал», но это требует согласования с бизнес-заказчиком.

Шаг 4. Обновление списка автоподстановок в интерфейсе

После того как код написан и конфигурация обновлена, новые пункты не всегда сразу появляются в списке выбора. Выясним, как принудительно обновить кэш системы:

  1. Откройте любой шаблон бизнес-процесса.
  2. Перейдите на вкладку настройки исполнителей.
  3. Нажмите на кнопку выбора исполнителя (откроется адресная книга).
  4. В левой части, где отображается дерево «Автоподстановки», нажмите правой клавишей мыши.
  5. Выберите пункт «Обновить автоподстановки».

Только после этого действия система перечитает содержимое модуля ШаблоныБизнесПроцессовПереопределяемый и добавит ваши функции в список доступных.

Особенности для комплексных процессов

При использовании в комплексных процессах может возникнуть ошибка Не найден предмет процесса. Это происходит потому, что в комплексном процессе предметы могут называться иначе, чем в простых задачах (например, «Документ» вместо «Основной предмет»). Чтобы код был универсальным, мы добавили проверку: если ИмяПредмета не найдено в коллекции, берется первый доступный предмет. Это гарантирует стабильную работу автоподстановки даже при нетипичных настройках шаблона.

Совет: Если вы планируете использовать эту логику в 1С:Документооборот версии 3.0, помните, что там работа с автоподстановками может быть реализована через скрипты в правилах обработки документов, что позволяет избежать изменения конфигурации в ряде случаев.

← На главную