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