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

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

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

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

Рассмотрим ситуацию: у нас есть табличная часть ОС (Основные средства) с колонкой-флажком ЖилищноеСтроительство. Нам нужно, чтобы при установке этого флажка колонка ДатаРегистрацииПрав становилась доступной, а при снятии — блокировалась. Попытка решить это через обработчик ПриИзменении на клиенте заставляет программиста вручную управлять свойством ТолькоПросмотр или Доступность элемента формы. Однако свойство элемента формы Элементы.ОСДатаРегистрацииПрав относится ко всей колонке целиком, а не к конкретной ячейке в строке. Чтобы управлять каждой строкой индивидуально, в старых версиях платформы приходилось использовать сложные обходы, что в управляемом приложении считается плохой практикой.

Выясним причину, почему разработчики типовых конфигураций (таких как 1С:ERP или 1С:Комплексная автоматизация) отказываются от обработчиков ПриИзменении для управления интерфейсом. Главная причина — декларативность. Вместо того чтобы писать код «если случилось А, сделай Б», мы описываем правило: «поле Б должно быть закрыто для редактирования, если в поле А стоит Ложь». Платформа сама следит за выполнением этого правила.

Решение через Условное оформление формы

Механизм Условного оформления позволяет динамически менять свойства ячеек (цвет, текст, видимость, доступность) на основе данных объекта. Рассмотрим подробнее, как реализовать программное создание такого оформления в модуле формы. Обычно это делается в процедуре, вызываемой при создании формы на сервере.

Разберем по шагам создание правила оформления, которое блокирует поле при определенном значении флажка:

  1. Создаем новый элемент условного оформления.
  2. Указываем поля, на которые будет распространяться оформление.
  3. Задаем условие (отбор), при котором правило должно сработать.
  4. Устанавливаем параметры оформления (например, ТолькоПросмотр = Истина).

Проанализируем пример кода, который решает задачу автора темы:


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

Почему это решение лучше циклов?

Рассмотрим ситуацию, когда разработчик пытается использовать цикл Для каждого Стр из Объект.ОС Цикл в процедуре ПриОткрытии. Посмотрим на недостатки этого метода:

Важно помнить, что свойство ТолькоПросмотр в Условном оформлении работает индивидуально для каждой ячейки в строке. Это именно то поведение, которого не хватает при попытке программно менять свойство Доступность у колонки Элементы.ИмяКолонки.

Автоматическое обновление при изменении флажка

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

Посмотрим на расширенный пример, где мы блокируем сразу несколько полей на основании одного условия, как это часто встречается в 1С:ERP:


// Пример блокировки группы полей для общей собственности
Элемент = УсловноеОформление.Элементы.Добавить();

// Добавляем несколько полей в одно правило
Элемент.Поля.Элементы.Добавить().Поле = Новый ПолеКомпоновкиДанных("ОСДоляВПравеЧислитель");
Элемент.Поля.Элементы.Добавить().Поле = Новый ПолеКомпоновкиДанных("ОСДоляВПравеЗнаменатель");

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

Элемент.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
Элемент.Оформление.УстановитьЗначениеПараметра("ОтметкаНезаполненного", Ложь);

Проанализируем ситуацию, когда необходимо не просто заблокировать поле, но и очистить его значение при снятии флажка. В этом случае одного Условного оформления будет недостаточно. Условное оформление отвечает только за визуальное представление и возможность редактирования. Если бизнес-логика требует удаления даты при снятии флага, вам всё же потребуется добавить обработчик ПриИзменении для флажка, где вы пропишете очистку связанного реквизита. Условное оформление при этом продолжит выполнять свою роль — визуально блокировать поле.

Таким образом, мы выяснили, что современный стандарт разработки в 1С подразумевает отделение визуальной логики (доступность, цвет, текст) от логики данных. Использование УсловногоОформления делает код чище, а интерфейс — отзывчивее для пользователя.

← На главную