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