Разработчики и специалисты по внедрению «1С:Документооборот 8 КОРП» (редакция 2.1) часто сталкиваются с требованиями бизнеса изменить логику стандартных бизнес-процессов. Типичный пример: руководство хочет, чтобы для определенных видов документов (например, «Оценка риска») стандартный процесс исполнения выглядел иначе — вместо кнопки «Исполнить» отображалась кнопка «Оценить», были добавлены обязательные проверки, скрыты лишние действия и так далее.
Первое побуждение начинающего разработчика — скопировать существующий бизнес-процесс Исполнение в конфигураторе, переименовать его, например, в Оценка, и доработать формы. Однако этот путь ведет к серьезным архитектурным проблемам. В рамках этой статьи мы разберем, почему копирование типовых бизнес-процессов в 1С:ДО — это тупиковое решение, и рассмотрим правильный, безопасный способ реализации такой задачи с помощью расширения конфигурации.
Конфигурация «1С:Документооборот» спроектирована по модульному принципу. Бизнес-процессы в ней не существуют изолированно; они жестко интегрированы с десятками других механизмов системы. Давайте проанализируем основные причины, почему создание копии процесса (например, копирование БизнесПроцесс.Исполнение) приведет к краху системы:
Оценка, вам придется вручную находить все эти подписки, добавлять в типы ваш новый объект и дублировать огромные объемы кода в общих модулях.Справочник.ШаблоныИсполнения и другие аналогичные справочники. Если вы копируете процесс, вам придется скопировать и всю инфраструктуру шаблонов, переписать интерфейсы их настройки и логику создания процессов по шаблону.Именно поэтому опытные специалисты рекомендуют отказаться от создания новых объектов метаданных и пойти по пути динамической модификации поведения стандартных процессов.
Вместо создания дубликата бизнес-процесса мы можем использовать современный механизм расширений конфигурации (Extensions). Наша задача сводится к тому, чтобы перехватить момент создания формы задачи исполнителя и программно изменить интерфейс (например, переименовать кнопку), если выполняются определенные условия (например, если предметом задачи является документ определенного вида).
В «1С:Документооборот 2.1» за задачи исполнения отвечает объект метаданных Задача.ЗадачаИсполнителя и его форма ФормаЗадачиИсполнить. Мы можем перехватить событие ПриСозданииНаСервере этой формы в расширении и программно переопределить её элементы.
Давайте разберем этот процесс по шагам.
Для начала работы запустим конфигуратор и создадим новое расширение:
Нам потребуется заимствовать форму задачи исполнителя. Найдем в дереве метаданных основной конфигурации объект Задача.ЗадачаИсполнителя, раскроем его формы, найдем форму ФормаЗадачиИсполнить, нажмем по ней правой кнопкой мыши и выберем пункт Добавить в расширение. Также убедимся, что в расширение добавлены необходимые общие модули для работы с реквизитами объектов (например, модуль ОбщегоНазначения).
Откроем модуль заимствованной формы задачи в расширении. Нам необходимо создать обработчик-последователь для стандартного метода ПриСозданииНаСервере. Мы будем использовать аннотацию &После, чтобы наш код выполнялся сразу после того, как отработает вся типовая логика инициализации формы.
Проанализируем структуру хранения данных. В 1С:ДО предметы задачи (документы, файлы, проекты) могут храниться как непосредственно в табличной части Предметы самой задачи, так и в табличной части связанного с ней бизнес-процесса. Нам нужно предусмотреть оба этих варианта.
Рассмотрим подробнее программный код, который решает эту задачу:
&После("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Получаем объект задачи из реквизитов формы для анализа его данных
ЗадачаОбъект = РеквизитФормыВЗначение("Объект");
// Инициализируем переменную, в которой будет храниться ссылка на документ-предмет
ДокументСсылка = Неопределено;
// Сначала пытаемся получить основной предмет непосредственно из табличной части задачи
Если ЗадачаОбъект.Предметы.Количество() > 0 Тогда
// Первый элемент коллекции обычно является основным предметом задачи
ДокументСсылка = ЗадачаОбъект.Предметы[0].Предмет;
Иначе
// Если в самой задаче предметы отсутствуют, проверяем бизнес-процесс, на основании которого она создана
БизнесПроцессСсылка = ЗадачаОбъект.БизнесПроцесс;
Если ЗначениеЗаполнено(БизнесПроцессСсылка)
И ОбщегоНазначения.ЕстьРеквизитОбъекта(БизнесПроцессСсылка, "Предметы") Тогда
БПОбъект = БизнесПроцессСсылка.ПолучитьОбъект();
Если БПОбъект.Предметы.Количество() > 0 Тогда
ДокументСсылка = БПОбъект.Предметы[0].Предмет;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Если предмет успешно найден, переходим к анализу его свойств
Если ЗначениеЗаполнено(ДокументСсылка) Тогда
// Быстро получаем вид документа через стандартную функцию БСП без чтения всего объекта из БД
ВидДокумента = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ДокументСсылка, "ВидДокумента");
// Проверяем соответствие вида документа нашему условию
Если ЗначениеЗаполнено(ВидДокумента) И ВидДокумента.Наименование = "Оценка риска" Тогда
// Выполняем поиск кнопки "Исполнить" на форме задачи
// Обратите внимание: имя элемента формы зависит от версии ДО, обычно это "Исполнить" или "Исполнено"
КнопкаИсполнено = Элементы.Найти("Исполнить");
Если КнопкаИсполнено <> Неопределено Тогда
// Меняем текст кнопки на требуемый по бизнес-логике
КнопкаИсполнено.Заголовок = "Оценить";
// Дополнительно скорректируем заголовок самой формы для удобства пользователя
ЭтотОбъект.Заголовок = "Оценка риска: " + ЗадачаОбъект.Наименование;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Давайте детально разберем наиболее важные моменты представленного алгоритма:
РеквизитФормыВЗначение("Объект") позволяет нам получить полноценный объект ЗадачаОбъект из прикладных данных управляемой формы на сервере. Это необходимо, так как на клиенте или непосредственно в реквизитах формы коллекция табличной части Предметы может быть недоступна для полного обхода.ОбщегоНазначения.ЗначениеРеквизитаОбъекта из состава Библиотеки Стандартных Подсистем (БСП). Это позволяет прочитать только необходимый реквизит (ВидДокумента) напрямую из базы данных, минуя тяжелую процедуру создания и инициализации всего объекта документа в памяти сервера.Элементы.Найти(). Это предохраняет систему от падения в аварийный режим, если в будущем при обновлении конфигурации фирма «1С» переименует или удалит кнопку с формы — код просто вернет Неопределено, не вызывая критической ошибки у пользователя.В примере кода мы использовали прямое сравнение наименования вида документа со строкой: ВидДокумента.Наименование = "Оценка риска". На практике такой подход считается небезопасным, поскольку обычный пользователь с правами администратора может случайно изменить название вида документа в справочнике (например, исправить на «Оценка рисков» или добавить лишний пробел). Это приведет к тому, что условие перестанет выполняться, и кнопка вернет свое стандартное название.
Чтобы избежать этой проблемы, рекомендуется использовать один из следующих подходов:
Если ваша компания не планирует заниматься регулярной доработкой кода конфигурации при каждом обновлении, или перед вами стоит задача кастомизировать десятки различных кнопок под разные бизнес-требования, имеет смысл рассмотреть готовые альтернативы:
Таким образом, мы выяснили, что попытка скопировать бизнес-процесс в 1С:ДО приводит к серьезным трудностям при поддержке и обновлении программного продукта. Использование расширения конфигурации и динамическое управление свойствами элементов управляемой формы — это наиболее гибкий, надежный и архитектурно правильный способ адаптации системы под требования вашего бизнеса.