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