Как программно настроить условное оформление по типу значения в табличной части 1С?

Программист 1С v8.3 (Управляемые формы)
← На главную

В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью визуально выделить строки в табличной части, основываясь на типе данных в колонке с составным типом. Например, если в одной колонке может храниться и СправочникСсылка.Валюты, и Строка, мы можем захотеть подсветить красным цветом только те строки, где выбрана валюта.

Однако стандартный механизм Условного оформления (УО) формы имеет ряд ограничений, которые не позволяют просто указать "ТипЗначения Равно Тип(Валюта)". В этой статье мы подробно разберем, почему так происходит, и найдем элегантное решение этой задачи.

Почему стандартный подход с Тип() не работает

Проанализируем ситуацию: когда мы настраиваем элемент отбора в УсловноеОформление.Элементы, мы работаем с объектами ЭлементОтбораКомпоновкиДанных. В свойство ЛевоеЗначение мы передаем ПолеКомпоновкиДанных (нашу колонку), а в ПравоеЗначение — значение для сравнения.

Многие начинающие разработчики пытаются написать следующий код:


ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.ТабличнаяЧасть1.Реквизит1");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Тип("СправочникСсылка.Валюты");

Разберем, в чем здесь ошибка. Система компоновки данных (которая "под капотом" управляет условным оформлением на формах) сравнивает именно значения. В колонке Реквизит1 хранятся ссылки на справочник или строки. А функция Тип() возвращает объект метаданных типа Тип. Ссылка на валюту никогда не будет равна объекту типа Тип, поэтому такое условие всегда будет ложным.

Также важно помнить, что в условном оформлении формы (в отличие от полноценных отчетов СКД) нам недоступны функции языка запросов вроде ТИПЗНАЧЕНИЯ() или оператор ССЫЛКА. Мы ограничены лишь теми полями, которые физически присутствуют в данных формы.

Попытка использования ВидСравнения.ВИерархии

Иногда возникает идея использовать ВидСравненияКомпоновкиДанных.ВИерархии, надеясь, что система поймет иерархию типов. Однако, как показывает практика, этот вид сравнения предназначен исключительно для работы с иерархическими справочниками или планами счетов. Попытка подставить туда тип данных приведет к тому, что оформление просто не сработает или вызовет ошибку при выполнении.

Решение проблемы через вспомогательный реквизит

Наиболее надежный и производительный способ решить задачу — это использование "фиктивного" или вспомогательного реквизита в табличной части. Рассмотрим этот алгоритм по шагам.

Шаг 1. Создание реквизита

Добавим в табличную часть объекта (или в реквизиты формы, если это коллекция формы) новый реквизит, назовем его, например, ПустаяСсылкаТипа. Тип этого реквизита должен совпадать с составным типом вашего основного поля (например, Реквизит1).

Шаг 2. Настройка связи по типу

В свойствах нового реквизита ПустаяСсылкаТипа установим свойство Связь по типу. В качестве поля-связи выберем наш основной Реквизит1. Это критически важный момент: платформа 1С автоматически будет менять тип реквизита ПустаяСсылкаТипа в зависимости от того, какой тип данных выбран в Реквизит1. При этом значение в ПустаяСсылкаТипа всегда будет оставаться пустым (пустая ссылка или пустая строка).

Шаг 3. Настройка Условного оформления

Теперь мы можем настроить отбор, сравнивая два поля между собой. Нам нужно выделить строки, где тип значения в Реквизит1 соответствует, например, справочнику Валюты. Для этого мы проверяем, что в Реквизит1 выбрана любая валюта (значение заполнено), а тип совпадает с тем, что "подсказал" нам вспомогательный реквизит.

Посмотрим на пример программной реализации такого оформления:


// Добавляем новый элемент условного оформления
ЭлементОформления = УсловноеОформление.ЭлементыДобавить();

// 1. Условие: проверяем, что значение в колонке соответствует пустой ссылке справочника Валюты
// Благодаря "Связи по типу", наше вспомогательное поле станет пустой ссылкой нужного типа автоматически
ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("Объект.ТабличнаяЧасть1.Реквизит1");
ЭлементОтбора.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
// Здесь мы сравниваем основной реквизит с его же "пустым" аналогом того же типа
ЭлементОтбора.ПравоеЗначение = Новый ПолеКомпоновкиДанных("Объект.ТабличнаяЧасть1.ПустаяСсылкаТипа");

// 2. Устанавливаем оформление (например, красный цвет текста)
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветТекста", WebЦвета.Красный);

// 3. Указываем поля, к которым применяется оформление
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("ТабличнаяЧасть1Реквизит1");

Важное примечание: Если вам нужно выделить именно заполненные значения определенного типа, условие будет чуть сложнее. Вы можете использовать проверку на то, что значение Не Равно пустой ссылке при условии, что тип уже определен. Но чаще всего разработчики используют вспомогательную колонку для хранения явного признака (например, перечисления или строки "ЭтоВалюта"), который заполняется в событии ПриИзменении основного реквизита.

Альтернативный метод: Сравнение с диапазоном (для ссылок)

Если в составном типе присутствует только один ссылочный тип и строка, можно прибегнуть к хитрости. Пустая ссылка любого справочника при сравнении ведет себя специфически. Рассмотрим ситуацию, когда нам нужно отличить СправочникСсылка.Валюты от всего остального в составном типе.

Выясним, как работает сравнение:

Проанализируем пример кода для этого случая:


ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.ТабличнаяЧасть1.Реквизит1");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
ЭлементОтбора.ПравоеЗначение = Справочники.Валюты.ПустаяСсылка();

Осторожно! Этот метод имеет недостатки. Если в составном типе данных присутствуют другие справочники, это условие может начать "ловить" и их, так как сравнение ссылок разных типов в 1С происходит по их внутренним идентификаторам (UUID) и типам метаданных. Поэтому метод со вспомогательным реквизитом и связью по типу остается самым надежным.

Почему не стоит использовать перебор строк в цикле?

Часто возникает соблазн просто пройтись по табличной части циклом и раскрасить строки вручную. Выясним причину, почему это плохая идея для управляемых форм:

  1. Производительность: Условное оформление выполняется на уровне платформенного движка отрисовки. Это происходит мгновенно при прокрутке списка.
  2. Динамичность: Если пользователь добавит новую строку или изменит значение в существующей, оформление, заданное через УсловноеОформление, применится автоматически. Если же вы "красите" строки кодом, вам придется вешать обработчики на каждое изменение данных, что усложняет код и замедляет работу интерфейса.

Таким образом, использование скрытого вспомогательного реквизита с установленной Связью по типу — это наиболее профессиональное решение, которое сохраняет высокую скорость работы интерфейса и чистоту программного кода. Для автоматической генерации программных настроек подойдёт конструктор кода условного оформления для табличных частей документов.

← На главную