Как в 1С:Документооборот 2.1 настроить авторегистрацию договоров и автоматическое выполнение рутинных задач

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

В процессе согласования и сопровождения договорной работы в «1С:Документооборот 2.1» пользователи нередко сталкиваются с избыточными ручными действиями. Классическая цепочка требует зарегистрировать документ после положительного утверждения или подписания, вручную внести полученный регистрационный номер в файл Word, а затем закрыть множество сопутствующих задач вроде «Ознакомиться с результатом» или «Исполнить». Разберем, как автоматизировать этот процесс: зарегистрировать договор программно, обновить номер в файле и исключить лишние шаги для исполнителей.

Автоматическая регистрация договоров при подписании

Для автоматической фиксации номера сразу после того, как документ перешел в состояние подписания, удобнее всего использовать механизм бизнес-событий и детекторы. Выясним причину такого выбора: механизм детекторов позволяет асинхронно реагировать на изменение данных документа без прямого вмешательства в логику записи объектов пользователем.

Проанализируем текст запроса для детектора событий. Запрос должен отслеживать появление подписанных внутренних документов конкретного вида, у которых еще отсутствует регистрационный номер:


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

Запрос.УстановитьПараметр("ВидДокумента", Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Договоры"));
Запрос.УстановитьПараметр("РезультатПодписания", Перечисления.РезультатыПодписания.Подписан);

РезультатЗапроса = Запрос.Выполнить().Выбрать();
Если РезультатЗапроса.Следующий() Тогда 
    ПараметрыВозврата.Вставить("Источник", РезультатЗапроса.Ссылка);
    Результат = Истина;
КонецЕсли;

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


Попытка
    Ур = УровеньЖурналаРегистрации.Информация;
    Документ = Событие.Источник;
    ЮИБ_ОбщегоНазначенияСервер.АвтоматическаяРегистрацияДоговора(Документ);
Исключение
    Ур = УровеньЖурналаРегистрации.Ошибка;
    Инфо = СокрЛП(ОписаниеОшибки());
    ЗаписьЖурналаРегистрации("Договоры", Ур, , Документ, Инфо);
КонецПопытки;

Рассмотрим подробнее саму процедуру регистрации. Для генерации номера по правилам делопроизводства используем типовые методы подсистемы Делопроизводство:


Процедура АвтоматическаяРегистрацияДоговора(Документ) Экспорт
    
    УстановитьПривилегированныйРежим(Истина);
    
    // Проверим, что документ еще не зарегистрирован
    Если ЗначениеЗаполнено(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Документ, "РегистрационныйНомер")) Тогда 
        Возврат;
    КонецЕсли;
    
    СообщениеОбОшибке = "";
    
    Если Делопроизводство.ЗарегистрироватьПредмет(Документ, СообщениеОбОшибке) Тогда
        Делопроизводство.ЗаписатьСостояниеДокумента(
            Документ,
            ТекущаяДатаСеанса(),
            Перечисления.СостоянияДокументов.Зарегистрирован,
            ПользователиКлиентСервер.ТекущийПользователь());
    КонецЕсли;
        
    УстановитьПривилегированныйРежим(Ложь);        
    
КонецПроцедуры

Автоматическое заполнение номера в файле Word (DOCX)

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

Для перезаполнения тегов в файле формата .docx вызываем специализированный метод типового общего модуля:


АвтозаполнениеШаблоновФайловКлиентСервер.ЗаполнитьПоляФайлаДаннымиВладельца(Ложь, ФайлСсылка, Истина, , ДокументСсылка);

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

  1. Блокировка редактирования: перед вызовом процедуры необходимо убедиться, что файл не занят пользователем. Проверяем реквизит Редактирует у элемента справочника Файлы. Если значение заполнено, перезаполнение вызовет ошибку.
  2. Версионирование: если для вида документа включено версионирование, процедура создаст новую версию файла от имени системной учетной записи.
  3. Формат документа: автоматическая обработка на сервере без использования COM-соединений поддерживается только для формата .docx через разбор OpenXML. Устаревший формат .doc требует вызова внешних библиотек MS Word, что неприменимо на серверах под управлением ОС Linux.

Исключение лишних задач: «Ознакомился», «Исполнено», «Зарегистрировать»

Для очистки рабочего стола определенного пользователя от рутинных шагов можно использовать несколько подходов — от программного закрытия до тонкой настройки комплексных процессов.

Способ 1. Автоматическое исполнение задач через детектор

Если нет возможности перенастраивать действующие комплексные маршруты, можно отлавливать создание задач на нужного пользователя и программно переводить их в статус завершенных.

Текст запроса детектора для поиска незавершенных задач конкретного сотрудника:


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

Запрос.УстановитьПараметр("Исполнитель", Справочники.Пользователи.НайтиПоРеквизиту("ЮИБ_ТабельныйНомер", "01001"));
РезультатЗапроса = Запрос.Выполнить().Выбрать();
Если РезультатЗапроса.Следующий() Тогда 
    ПараметрыВозврата.Вставить("Источник", РезультатЗапроса.Ссылка);
    Результат = Истина;
КонецЕсли;

Проанализируем процедуру завершения задачи. Прямой вызов ЗадачаОбъект.ВыполнитьЗадачу() требует обязательной подготовки реквизитов, иначе бизнес-логика процесса может вызвать отмену транзакции:


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

Важное предостережение: детектор срабатывает при возникновении бизнес-событий. Если попытаться мгновенно заблокировать и выполнить задачу внутри той же транзакции, в которой создается бизнес-процесс, высок риск получить взаимоблокировку (Deadlock) на уровне СУБД. Рекомендуется передавать такие задачи в очередь фонового регламентного задания или выполнять с небольшой задержкой.

Способ 2. Оптимизация маршрутов и использование правил эскалации

Создание задачи только для того, чтобы фоновое задание сразу ее закрыло, создает избыточную нагрузку на базу данных. Разберем по шагам альтернативные решения без лишней записи объектов:

  1. Отключение задач ознакомления: в шаблонах комплексных процессов для действий «Согласование» и «Утверждение» можно отключить признак формирования задачи «Ознакомиться с результатом» при положительном исходе. Задача будет создаваться только тогда, когда документ возвращен с замечаниями.
  2. Условия маршрутизации: для шагов «Регистрация» или «Исполнение» можно добавить типовые условия старта действия. Если автор или инициатор документа совпадает с определенным сотрудником, действие просто исключается из маршрута и задачи не создаются вовсе.
  3. Глобальные правила эскалации: правила эскалации не обязательно создавать отдельно под каждый шаблон. Достаточно создать общее правило по виду бизнес-процесса (например, для всех процессов типа «Ознакомление») с отбором по конкретному исполнителю и действием «Выполнить автоматически». Механизм эскалации штатно обрабатывается регламентным заданием без риска конфликтов блокировок.
  4. Перехват в расширении: в расширении конфигурации можно подключиться к событию ПриСозданииЗадач бизнес-процесса. Если текущий исполнитель совпадает с целевым пользователем, можно прерывать создание задачи или сразу устанавливать признак ее выполнения до сохранения в базу.
← На главную