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

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

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

Почему нельзя использовать цикл для изменения доступности

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

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

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

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

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

Разберем пример программной настройки условного оформления при создании формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    УстановитьУсловноеОформлениеНаФорме();
КонецПроцедуры

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

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

Способ 2: Обработка события ПриАктивизацииСтроки

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

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


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

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

Способ 3: Запрет изменения через событие ПередНачаломИзменения

Если ваша задача — не визуально «засерить» ячейку, а жестко запретить ввод данных при определенных условиях, используйте событие самой таблицы ПередНачаломИзменения. В отличие от ПриИзменении, здесь есть параметр Отказ, который позволяет прервать действие пользователя.

Проанализируем пример кода:


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

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

Сравнение подходов и выводы

Для создания качественного интерфейса мы рекомендуем комбинировать эти методы:

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

Посмотрим на ситуацию с «пропадающими квадратиками» (флажками), о которой часто упоминают разработчики. Если вы используете условное оформление и устанавливаете параметр Видимость = Ложь, ячейка действительно станет пустой. Чтобы сохранить отображение значения, но запретить ввод, всегда используйте ТолькоПросмотр вместо Видимость или Доступность в настройках оформления.

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

← На главную