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