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