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

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

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

В управляемом интерфейсе элементы формы связаны с колонками таблицы, а не с отдельными ячейками. Если мы программно изменим свойство колонки Элементы.ИмяКолонки.Доступность = Ложь или ТолькоПросмотр = Истина, колонка заблокируется сразу во всей таблице для всех строк без исключения. Рассмотрим проверенные и архитектурно правильные способы решения этой проблемы.

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

Самый надежный и быстродействующий способ заблокировать ячейку для конкретных строк — применить механизм условного оформления формы или динамического списка. В условном оформлении для колонок доступно специальное свойство — «Только просмотр». Обратите внимание, что свойства «Доступность» в условном оформлении нет, а свойство «Видимость» скрывает колонку целиком для всей таблицы.

Условное оформление рассчитывается на стороне клиента. Если условие блокировки зависит от сложных данных (например, регистра сведений «ДополнительныеСведения»), делать запрос к серверу на каждую отрисовку нельзя. Разберем по шагам правильный алгоритм реализации:

  1. Добавляем служебный реквизит: в табличную часть объекта или в реквизит формы типа ТаблицаЗначений добавляем служебную булеву колонку (например, ИзмененияЗапрещены). Эту колонку не обязательно показывать пользователю на форме.
  2. Заполняем признак на сервере: пакетно рассчитываем значение флага при открытии формы или считывании данных, избегая множественных одиночных обращений к базе данных.
  3. Настраиваем условное оформление: указываем оформляемые поля, отбор по служебной колонке и устанавливаем свойство «Только просмотр».

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


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

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

Оптимизация получения условий блокировки (дополнительные сведения)

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

  1. Для динамического списка: левым соединением подключаем таблицу сведений прямо в текст запроса динамического списка. Полученное поле выводим в список и используем в стандартных настройках условного оформления без программного кода.
  2. Для табличной части документа: в процедурах ПриЧтенииНаСервере или ПриСозданииНаСервере считываем все необходимые сведения одним запросом по всем строкам таблицы сразу и проставляем значение в реквизит ИзмененияЗапрещены.
  3. При интерактивном изменении данных: если пользователь выбирает новое значение в строке (например, меняет номенклатуру), точечный серверный вызов для проверки условий блокировки следует вызывать строго в событии ПриИзменении этого поля, обновляя флаг только для активной строки.

Способ 2. Событийная блокировка через обработчик «ПриАктивизацииЯчейки»

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

Для перехвата фокуса на конкретной ячейке используется событие таблицы формы ПриАктивизацииЯчейки. Разберем реализацию:


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

Критически важное ограничение: обработчик ПриАктивизацииЯчейки вызывается при каждом перемещении курсора по ячейкам таблицы. В этом обработчике категорически запрещено делать контекстные и даже бесконтекстные серверные вызовы (&НаСервере), так как это приведет к серьезным задержкам и зависанию пользовательского интерфейса при банальной навигации по строкам. Все данные для проверки должны быть подготовлены на клиенте заранее.

Дополнительный контроль ввода данных

Чтобы гарантировать целостность данных и исключить случайную модификацию заблокированных полей, рекомендуется настроить событие таблицы формы ПередОкончаниемРедактирования:


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

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

← На главную