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