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