Как программно запретить выбор определенного значения в переключателе на управляемых формах 1С?

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

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

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

Проблема стандартного свойства ДоступныеЗначения

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

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


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

Что увидит пользователь? К сожалению, визуально переключатель никак не изменится. Все пункты останутся активными на вид. При попытке нажать на «Заблокирован», значение в реквизите просто не установится или сбросится в пустое значение. Это вводит пользователя в заблуждение, так как он не понимает, почему кнопка нажимается, но ничего не происходит. Более того, свойство ДоступныеЗначения может некорректно синхронизироваться между сервером и клиентом, что делает этот метод ненадежным для управления интерфейсом.

Решение №1: Динамическое изменение СпискаВыбора

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

Разберем алгоритм по шагам:

  1. При изменении условий (например, в событии ПриИзменении связанного поля) вызываем серверный контекст.
  2. Очищаем текущий СписокВыбора переключателя.
  3. Заполняем его заново только теми значениями, которые разрешены в данный момент.

Посмотрим на пример кода:


&НаСервере
Процедура ОбновитьСписокВыбораНаСервере()
    
    Список = Элементы.ПолеПереключатель.СписокВыбора;
    Список.Очистить();
    
    Список.Добавить(Пречисления.Статусы.Активен, "Активен");
    
    // Условие: только администратор может ставить спец-статус
    Если РольДоступна("ПолныеПрава") Тогда
        Список.Добавить(Пречисления.Статусы.Архив, "Архив");
    КонецЕсли;
    
КонецПроцедуры

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

Решение №2: Использование Группы кнопок (Лучший визуальный вариант)

Если ваша задача — именно показать пользователю, что значение существует, но оно «серое» (недоступное), то стандартный переключатель нам не подходит. Профессиональным обходом является использование Группы кнопок.

Разберем, как это реализовать:

  1. Создаем на форме Группу элементов с видом Группа кнопок.
  2. Устанавливаем у группы свойство РежимПроверки (чтобы кнопки вели себя как переключатели).
  3. Внутри группы создаем обычные Кнопки формы для каждого значения.
  4. Для каждой кнопки мы можем индивидуально управлять свойством Доступность.

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


&НаКлиенте
Процедура УправлениеДоступностьюКнопок(УсловиеРазрешено)
    
    // Кнопка 1 всегда доступна
    Элементы.КнопкаСтатусНовый.Доступность = Истина;
    
    // Кнопка 2 зависит от условий
    Элементы.КнопкаСтатусАрхив.Доступность = УсловиеРазрешено;
    
КонецПроцедуры

При нажатии на любую из кнопок необходимо в обработчике прописывать изменение основного реквизита и визуально «нажимать» кнопку через свойство Пометка.

Решение №3: Комбинированный метод с подменой элементов

Проанализируем ситуацию, описанную в сообщении №16 форума. Автор предлагает интересный «костыль», который отлично работает визуально. Если значение должно стать недоступным, мы удаляем его из основного переключателя и одновременно включаем видимость другого элемента — Декорации или Надписи, которая имитирует этот пункт переключателя, но окрашена в серый цвет.

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

Решение №4: Использование Поля HTML-документа

Если требования к дизайну максимально строгие и вам нужны именно классические «кружочки» (Radio buttons), где один из них должен быть заблокирован, можно прибегнуть к использованию Поля HTML-документа. Это позволяет отрисовать любой интерфейс.

Разберем по шагам логику реализации:

  1. На форме размещается поле с типом ПолеHTMLДокумента.
  2. Формируется строка HTML, содержащая стандартные теги <input type="radio">.
  3. Для недоступных элементов добавляется атрибут disabled.
  4. С помощью стилей CSS задаются цвета и отступы.
  5. Обработка выбора происходит через событие ПриНажатии в 1С, куда HTML-страница передает данные через схему v8action.

Пример формирования строки для HTML-поля:


ТекстHTML = "
|<html>
|<body>
|  <input type='radio' name='stat' value='1' checked> Активен<br>
|  <input type='radio' name='stat' value='2' disabled> <span style='color:gray;'>Заблокирован</span>
|</body>
|</html>";

Хотя этот метод требует больше времени на реализацию, он дает 100% контроль над визуализацией каждого отдельного пункта переключателя.

Итоги и рекомендации

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

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

← На главную