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