Как сделать форму бизнес-процесса доступной для редактирования на определенной точке маршрута?

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

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

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

Почему не работает управление формой из модуля объекта бизнес-процесса?

Рассмотрим ситуацию, с которой часто сталкиваются разработчики на начальном этапе. Попытка обратиться к форме из модуля объекта бизнес-процесса выглядит следующим образом:


Форма = ЭтотОбъект.ПолучитьФорму("ФормаБизнесПроцесса");
Форма.ТолькоПросмотр = Ложь;

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

  1. Разделение контекстов (Клиент / Сервер): Модуль объекта бизнес-процесса всегда выполняется на стороне сервера. Форма же является интерактивным клиентским объектом. Прямое управление свойствами отображения интерфейса (такими как ТолькоПросмотр, Видимость или Доступность) из контекста модуля объекта физически невозможно и запрещено архитектурой платформы.
  2. Получение нового экземпляра: Метод ПолучитьФорму(), вызванный на сервере, создает абсолютно новый, изолированный экземпляр формы в оперативной памяти сервера. Этот экземпляр никак не связан с той формой, которую в данный момент видит перед собой пользователь на экране. Изменения свойств этого нового объекта не окажут никакого влияния на текущий сеанс пользователя.

Таким образом, логика управления интерфейсом должна быть перенесена непосредственно в модуль самой управляемой формы бизнес-процесса.

Решение 1. Логика управления в модуле управляемой формы

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

Для определения текущего этапа бизнес-процесса у объекта существует стандартный метод ПолучитьТекущиеТочкиМаршрута(). Этот метод возвращает массив активных точек маршрута для конкретного экземпляра бизнес-процесса.

Проанализируем пример реализации данного механизма по шагам:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, что бизнес-процесс уже запущен, записан в базу данных и еще не завершен
    Если ЗначениеЗаполнено(Объект.Ссылка) И Объект.Стартован И НЕ Объект.Завершен Тогда
        
        // 1. По умолчанию для всех запущенных процессов закрываем форму на редактирование
        ЭтаФорма.ТолькоПросмотр = Истина;
        
        // 2. Получаем массив активных точек маршрута для текущей ссылки БП
        ТекущиеТочки = Объект.Ссылка.ПолучитьТекущиеТочкиМаршрута();
        
        // 3. Получаем ссылку на предопределенную точку маршрута из метаданных,
        // на которой пользователю должно быть разрешено редактирование
        НужнаяТочка = БизнесПроцессы.ИмяВашегоБизнесПроцесса.ТочкиМаршрута.ИмяНужнойТочки;
        
        // 4. Если бизнес-процесс в данный момент находится на этой точке — открываем доступ
        Если ТекущиеТочки.Найти(НужнаяТочка) <> Неопределено Тогда
            
            // Разрешаем редактирование всей формы
            ЭтаФорма.ТолькоПросмотр = Ложь;
            
            // Чтобы пользователь случайно не изменил системные реквизиты (например, Автор, ДатаСтарта),
            // рекомендуется явно заблокировать остальные элементы формы программным обходом
            ЗаблокироватьЛишниеЭлементыФормы();
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

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


&НаСервере
Процедура ЗаблокироватьЛишниеЭлементыФормы()
    
    // Обходим коллекцию элементов формы и закрываем от изменения все, кроме разрешенных реквизитов
    Для Каждого Элемент Из Элементы Цикл
        
        // Проверяем имена элементов, которые должны остаться доступными для редактирования
        Если Элемент.Имя <> "РеквизитДляРедактирования1" 
           И Элемент.Имя <> "РеквизитДляРедактирования2" Тогда
            
            Попытка
                Элемент.ТолькоПросмотр = Истина;
            Исключение
                // Пропускаем группы, декорации и другие элементы, не имеющие свойства ТолькоПросмотр
            КонецПопытки;
            
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Решение 2. Использование расширений конфигурации

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

Рассмотрим последовательность действий для реализации задачи через расширение:

  1. Добавьте в расширение конфигурации нужный бизнес-процесс и его основную форму.
  2. В модуле формы бизнес-процесса в расширении создайте обработчик-перехватчик для процедуры ПриСозданииНаСервере с аннотацией &После.
  3. Перенесите туда логику проверки активной точки маршрута и изменения свойства формы ТолькоПросмотр.

Пример кода в модуле формы расширения:


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

Решение 3. Альтернативный UX-подход: Редактирование через задачу

С точки зрения эргономики интерфейса (UX/UI) заставлять пользователя переходить из формы задачи в форму бизнес-процесса только ради изменения одного-двух реквизитов считается не самым удобным сценарием. Это порождает лишние клики и усложняет работу.

Гораздо более удобным и архитектурно красивым решением является вынесение необходимых полей бизнес-процесса напрямую на форму задачи, которая создается на конкретной точке маршрута.

Рассмотрим, как реализовать этот подход:

  1. На форме задачи создайте реквизиты (например, РеквизитБП_Значение), которые соответствуют реквизитам бизнес-процесса, требующим редактирования. Разместите их на форме задачи.
  2. При создании формы задачи на сервере заполните эти реквизиты значениями из бизнес-процесса:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Заполняем реквизит формы задачи данными из связанного бизнес-процесса
    Если ЗначениеЗаполнено(Объект.БизнесПроцесс) Тогда
        РеквизитБП_Значение = Объект.БизнесПроцесс.ИмяНужногоРеквизита;
    КонецЕсли;
КонецПроцедуры
  1. При записи или выполнении задачи перенесите измененные пользователем данные обратно в объект бизнес-процесса и программно запишите его. Это можно сделать в модуле формы задачи перед выполнением:

&НаСервере
Процедура ЗаписатьДанныеВБизнесПроцесс()
    
    // Получаем объект бизнес-процесса для изменения
    БПОбъект = Объект.БизнесПроцесс.ПолучитьОбъект();
    
    // Переносим отредактированное значение из реквизита формы задачи
    БПОбъект.ИмяНужногоРеквизита = РеквизитБП_Значение;
    
    // Записываем бизнес-процесс без изменения состояния его маршрута
    БПОбъект.Записать();
    
КонецПроцедуры

Этот способ полностью решает проблему доступности формы бизнес-процесса, так как пользователь вообще не открывает форму самого БП, а работает исключительно в рамках своей текущей задачи. Это снижает количество ошибок и делает работу пользователей в системе 1С более комфортной.

← На главную