При разработке интерфейсов на управляемых формах часто возникает задача выборочной блокировки строк табличной части. Например, когда пользователь выбирает определенные строки флагами, выполняет расчет по кнопке, и после этого обработанные строки должны стать недоступными для повторного изменения. Разберем основные и надежные способы реализации такого поведения в 1С:Предприятие 8.3.
Самый простой и визуально наглядный механизм блокировки отдельных ячеек или строк — это использование Условного оформления управляемой формы. Свойство ТолькоПросмотр в условном оформлении позволяет запретить редактирование полей, если строка удовлетворяет заданному условию.
Разберем по шагам, как настроить это правило:
Булево (например, РасчетОкончен). При выполнении обработки для выбранных строк будем устанавливать данный флаг в значение Истина.Истина.Объект.ТЧ.РасчетОкончен равно Истина. Важно: условие должно указывать именно на реквизит строки текущей таблицы, а не на общий реквизит формы.ТЧВыбор, ТЧКоличество, ТЧСумма). Если требуется заблокировать всю строку, добавим все редактируемые колонки.Если требуется создать данное правило динамически при открытии формы, программно опишем его в серверном обработчике. Посмотрим на пример кода:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Создаем элемент условного оформления
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
// Устанавливаем параметр "Только просмотр"
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
// Формируем условие: колонка РасчетОкончен = Истина
ЭлементУсловия = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.ТЧ.РасчетОкончен");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементУсловия.ПравоеЗначение = Истина;
ЭлементУсловия.Использование = Истина;
// Указываем оформляемое поле (конкретная колонка)
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("ТЧВыбор");
КонецПроцедуры
Проанализируем важный нюанс: условное оформление и визуальное свойство ТолькоПросмотр отвечают за отображение, но пользователь все еще может удалить строку клавишей Delete или изменить ее горячими клавишами. Для полной и строгой защиты данных необходимо использовать обработчики событий самой таблицы формы на клиенте.
Рассмотрим реализацию событий ПередНачаломИзменения и ПередУдалением:
&НаКлиенте
Процедура ТЧПередНачаломИзменения(Элемент, Отказ)
ТекущиеДанные = Элемент.ТекущиеДанные;
// Проверяем, заполнена ли строка и выполнен ли расчет
Если ТекущиеДанные <> Неопределено И ТекущиеДанные.РасчетОкончен Тогда
// Запрещаем переход в режим редактирования ячейки или строки
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ТЧПередУдалением(Элемент, Отказ)
ТекущиеДанные = Элемент.ТекущиеДанные;
// Запрещаем удаление уже рассчитанных строк
Если ТекущиеДанные <> Неопределено И ТекущиеДанные.РасчетОкончен Тогда
Отказ = Истина;
ПоказатьОповещениеПользователя("Ошибка", , "Нельзя удалять уже рассчитанные строки!");
КонецЕсли;
КонецПроцедуры
В некоторых случаях разработчики переключают свойство ТолькоПросмотр у элементов формы при перемещении курсора по таблице. Выясним особенности и ограничения этого подхода.
&НаКлиенте
Процедура ТЧПриАктивизацииСтроки(Элемент)
СтрокаТаблицы = Элемент.ТекущиеДанные;
// Обязательно проверяем на Неопределено, чтобы избежать ошибок при пустой таблице
Если СтрокаТаблицы = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтрокаТаблицы.РасчетОкончен Тогда
Элементы.ТЧВыбор.ТолькоПросмотр = Истина;
Иначе
Элементы.ТЧВыбор.ТолькоПросмотр = Ложь;
КонецЕсли;
КонецПроцедуры
Обратите внимание: элемент Элементы.ТЧВыбор представляет собой колонку целиком для всей таблицы. Изменение его свойства переключает доступность всей колонки в зависимости от активной строки. При быстрой навигации или пакетной обработке данных предпочтительнее комбинировать Условное оформление и событие ПередНачаломИзменения.
Неопределено или Null), булево поле переходит в третье неопределенное состояние. Убедитесь, что реквизит имеет строгий тип Булево, а при создании новых строк ему явно присваивается значение Ложь.