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