Как сделать недоступной для редактирования колонку в конкретной строке табличной части?

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

При разработке интерфейсов на управляемых формах 1С часто возникает задача: запретить редактирование поля только для определенных строк таблицы (например, сделать недоступным выбор ставки НДС для определенных видов номенклатуры). Однако попытка напрямую изменить свойство элемента управления через Элементы.ТоварыСтавкаНДС.Доступность = Ложь приводит к тому, что колонка блокируется во всей табличной части сразу.

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

Почему блокируется вся колонка целиком?

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

Для управления доступностью конкретных ячеек строки в платформе 1С:Предприятие 8.3 применяются другие механизмы. Рассмотрим их подробнее.

Способ 1. Использование механизма «Условное оформление» (рекомендуемый способ)

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

Для блокировки ячейки используется параметр условного оформления ТолькоПросмотр или Доступность.

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

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

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


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

Совет по оптимизации: если условие проверяет данные через точку от ссылки (например, Объект.Товары.Номенклатура.ВидНоменклатуры), для повышения производительности рекомендуется добавить в табличную часть скрытый реквизит (например, булево СтавкаНДСНедоступна или ссылку на ВидНоменклатуры) и заполнять его при выборе товара. В таком случае условное оформление будет проверять данные текущей строки ТЧ напрямую, не подтягивая данные ссылки на клиенте.

Способ 2. Управление доступностью в событии «ПриАктивизацииСтроки»

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

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

Посмотрим на пример реализации:


&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
    
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем условие по данным текущей строки
    Элементы.ТоварыСтавкаНДС.ТолькоПросмотр = (ТекущиеДанные.ВидНоменклатуры = ЗапрещенныйВидНоменклатуры);
    
КонецПроцедуры

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

Способ 3. Блокировка в событиях начала редактирования

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

Разберем вариант с обработчиком события поля НачалоВыбора и Очистка:


&НаКлиенте
Процедура ТоварыСтавкаНДСНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено И ТекущиеДанные.ВидНоменклатуры = ЗапрещенныйВидНоменклатуры Тогда
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ТоварыСтавкаНДСОчистка(Элемент, СтандартнаяОбработка)
    
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено И ТекущиеДанные.ВидНоменклатуры = ЗапрещенныйВидНоменклатуры Тогда
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
    
КонецПроцедуры

Также можно использовать событие таблицы ПередНачаломИзменения, передавая в параметр Отказ = Истина, если редактирование инициировано в запрещенной колонке.

Итоги

Наиболее правильным, платформенным и визуально понятным для пользователя решением является Условное оформление с установкой свойства ТолькоПросмотр = Истина. Оно работает на стороне платформы без лишнего программного кода в событиях движения курсора и обеспечивает максимальную отзывчивость интерфейса.

← На главную