Как в 1С:Документооборот 3.0 управлять кнопками на форме "Задачи": скрыть, переименовать или изменить цвет?

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

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

Проблема заключается в том, что эти кнопки не являются статичными элементами формы, которые можно просто отредактировать в конфигураторе — для этого подойдёт инструмент настройки прав доступа и поведения форм без программирования. Они создаются динамически на сервере каждый раз при открытии задачи. Наша цель — вмешаться в этот процесс и применить свои правила видимости, наименований и оформления.

Анализ механизма формирования кнопок

Прежде чем приступить к написанию кода, давайте разберемся, как система формирует кнопки выполнения задачи. Ключевую роль в этом процессе играет процедура ОбновитьОбластьПросмотраНаКлиенте, которая вызывается на сервере. Именно она анализирует текущую задачу, доступные варианты ее выполнения (например, "Исполнено", "Согласовано", "Отклонено") и динамически создает соответствующие кнопки на форме. Эти кнопки помещаются в специальную группу элементов формы, которая называется ГруппаКомандыДляВыполнения.

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

Пошаговое решение: модификация кнопок через расширение

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

  1. Создание расширения и добавление формы.
    Создайте новое расширение конфигурации. В это расширение необходимо заимствовать форму ЗадачаИсполнителя.Форма.ФормаЗадачи (предварительно можно провести анализ состава расширений на наличие ошибок). Это позволит нам добавлять свои обработчики событий для этой формы.
  2. Создание обработчика события.
    Нам нужно вмешаться в работу процедуры ОбновитьОбластьПросмотраНаКлиенте. Для этого в расширенной форме создадим для этой процедуры обработчик события с типом вызова "После". Это гарантирует, что наш код выполнится уже после того, как стандартный механизм 1С создаст все кнопки, и мы сможем их модифицировать.
  3. Реализация программной логики.
    В созданном обработчике разместим код, который будет анализировать созданные кнопки и изменять их свойства. Ниже приведен пример такого кода, основанный на решении с форума, с подробными комментариями. В этом примере предполагается, что настройки для кнопок (новое имя, видимость, цвет) хранятся в специально созданном для этого регистре сведений кнпк_НастройкиКнопок. Вы можете адаптировать эту логику под свои нужды, например, зашив условия прямо в код.

Посмотрим на пример кода, который можно разместить в обработчике "После" процедуры ОбновитьОбластьПросмотраНаКлиенте.


&НаСервере
Процедура Расш_ОбновитьОбластьПросмотраНаКлиентеПосле(ДанныеОбластиДействия)

    // Префикс, который система использует для имен команд
    ПрефиксИмениКомандыРезультата = РаботаСЗадачамиКлиентСервер.ПрефиксИмениКомандыРезультата();
    
    // Получаем данные о доступных вариантах выполнения текущей задачи
    ДанныеВариантовВыполненияЗадачи = ДанныеОбластиДействия.ДанныеВариантовВыполненияЗадачи;
    
    // Перебираем все доступные результаты (например, "Согласовано", "Отклонено")
    Для Каждого ДоступныйРезультат Из ДанныеВариантовВыполненияЗадачи.ДоступныеРезультаты Цикл
        
        // В этом примере настройки хранятся в отдельном регистре сведений.
        // Создадим структуру для отбора записей из регистра по текущему действию и результату.
        ПараметрыОтбора = Новый Структура;
        ПараметрыОтбора.Вставить("НастройкаДействия", ДанныеОбластиДействия.ДействиеОбработки.НастройкаДействия);
        ПараметрыОтбора.Вставить("РезультатДействия", ДоступныйРезультат);
        
        // Получаем срез последних с нашими настройками
        СрезНастроек = РегистрыСведений.кнпк_НастройкиКнопок.СрезПоследних(, ПараметрыОтбора);
        
        // Если для данного результата найдена настройка, применяем ее
        Если СрезНастроек.Количество() > 0 Тогда
            НовыеНастройки = СрезНастроек[0];
            
            // Теперь самое важное: нужно найти соответствующий элемент (кнопку) на форме.
            // Для этого конструируем имя команды и имя элемента формы.
            
            ИдентификаторРезультата = ДоступныйРезультат.УникальныйИдентификатор;
            ИмяКомандыВыполнения = РаботаСЗадачамиКлиентСервер.ИмяКомандыВыполнения(ПрефиксИмениКомандыРезультата, ИдентификаторРезультата);
            
            // Определяем, используется ли электронная подпись для этого действия
            ЭтоРезультатСЭП = ДанныеВариантовВыполненияЗадачи.РезультатыСЭП.Найти(ДоступныйРезультат) <> Неопределено;
            
            // Имена элементов для кнопок с ЭП и без нее формируются по-разному
            Если ЭтоРезультатСЭП Тогда
                ИмяЭлементаВыполнения = РаботаСЗадачамиКлиентСервер.ИмяЭлементаВыполненияСРезультатомИЭП(ИмяКомандыВыполнения);
            Иначе
                ИмяЭлементаВыполнения = РаботаСЗадачамиКлиентСервер.ИмяЭлементаВыполненияСРезультатом(ИмяКомандыВыполнения);
            КонецЕсли;
            
            // Ищем элемент на форме по вычисленному имени
            ТекЭлемент = Элементы.ГруппаКомандыДляВыполнения.ПодчиненныеЭлементы.Найти(ИмяЭлементаВыполнения);
            
            // Если элемент найден, применяем наши настройки
            Если ТекЭлемент <> Неопределено Тогда
                ТекЭлемент.Видимость = НовыеНастройки.Видимость;
                ТекЭлемент.Заголовок = НовыеНастройки.НаименованиеНаФорме;
                
                // Цвет является составным типом, поэтому используем сериализатор для его установки
                Попытка
                    ТекЭлемент.ЦветТекста = СериализаторXDTO.XMLЗначение(Тип("Цвет"), НовыеНастройки.ЦветТекста);
                Исключение
                    // Обработка возможной ошибки
                КонецПопытки;
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;

КонецПроцедуры

Важный момент: в приведенном примере используется кастомный регистр сведений кнпк_НастройкиКнопок. Вам потребуется создать его самостоятельно в своем расширении. Он может иметь измерения, такие как "НастройкаДействия" и "РезультатДействия", и ресурсы: "Видимость" (Булево), "НаименованиеНаФорме" (Строка), "ЦветТекста" (ХранилищеЗначения). Такой подход делает решение гибким и позволяет настраивать кнопки в пользовательском режиме без изменения кода.

Практический пример: скрытие кнопки "Рассмотрено"

Давайте проанализируем реальную бизнес-задачу. Предположим, для входящих писем руководитель не должен просто "рассматривать" документ, а обязан сразу же направить его на исполнение или вернуть автору на доработку. В этом случае кнопка "Рассмотрено" становится лишней и даже вредной, так как она не подразумевает дальнейших действий.

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

Для этого нам нужно получить доступ к предмету задачи (нашему документу), чтобы проверить его вид.


&НаСервере
Процедура Расш_ОбновитьОбластьПросмотраНаКлиентеПосле(ДанныеОбластиДействия)

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

КонецПроцедуры

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

Альтернативные и сопутствующие настройки

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

В заключение, программная модификация формы "Задачи" через расширение является наиболее мощным и гибким инструментом для ее кастомизации — есть готовое расширение подсистемы задач и планирования в 1С:Документооборот 3.0. Рассмотренный подход позволяет не только скрывать или переименовывать кнопки, но и реализовывать более сложную логику, адаптируя интерфейс "1С:Документооборот 3.0" под любые требования вашего бизнеса.

← На главную