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

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

В процессе разработки конфигураций на платформе 1С часто возникает задача визуального выделения данных в формах для удобства пользователя. Одна из таких задач — раскрасить строки табличной части документа в зависимости от значения реквизита, который находится не в самой строке, а в связанном с ней элементе справочника — для этого отлично подойдёт расширение для условного оформления табличных частей. Например, в документе "Заказ клиента" нужно выделить строки с товарами, которые относятся к определенной ценовой группе. Часто разработчикам также требуется выводить дополнительные визуальные индикаторы, такие как картинка проведенности на форме документа или общее состояние объектов на форме.

Проанализируем ситуацию: у нас есть документ с табличной частью Товары. В этой табличной части есть колонка Номенклатура (ссылка на справочник "Номенклатура"). У справочника "Номенклатура" есть реквизит ЦеноваяГруппа (ссылка на справочник "Ценовые группы"). Наша цель — раскрасить строки в табличной части Товары в разные цвета в зависимости от значения поля Номенклатура.ЦеноваяГруппа.

Попытка настроить условное оформление, указав в качестве левого значения путь Объект.Товары.Номенклатура.ЦеноваяГруппа, может не сработать с первого раза, что вызывает вопросы о возможностях платформы. Давайте разберем два надежных способа решения этой задачи: прямой доступ к данным через точку и использование вспомогательной колонки на форме.

Решение 1: Прямой доступ к реквизиту через точку

Вопреки распространенному мнению, платформа 1С в управляемых формах позволяет обращаться к реквизитам через точку в настройках условного оформления. Этот способ является наиболее правильным и лаконичным. Ошибка чаще всего кроется не в невозможности такого обращения, а в деталях настройки элемента условного оформления. Чтобы реализовать это максимально эффективно, можно использовать готовые инструменты для программного изменения форм, которые ускоряют разработку — в этом поможет инструментарий для программной настройки управляемых форм.

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

  1. Получаем коллекцию элементов условного оформления формы.

    Для начала нам нужен доступ к коллекции, куда мы будем добавлять нашу настройку.

    
    // Процедура выполняется на сервере
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        
        // Получаем коллекцию элементов условного оформления
        УсловноеОформлениеЭлементы = ЭтаФорма.УсловноеОформление.Элементы;
    
    КонецПроцедуры
    
  2. Добавляем новый элемент оформления и настраиваем условие (отбор).

    Создадим новый элемент и зададим для него условие. Условие — это ключевая часть, именно здесь мы укажем путь к реквизиту связанного справочника.

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

    Важно понимать, что строка "Объект.Товары.Номенклатура.ЦеноваяГруппа" — это путь к данным, который платформа обрабатывает с помощью механизмов системы компоновки данных. Объект — основной реквизит формы, Товары — имя табличной части объекта, Номенклатура — реквизит табличной части, ЦеноваяГруппа — реквизит справочника "Номенклатура".

  3. Настраиваем само оформление.

    Теперь определим, как именно будут выглядеть строки, для которых выполнится наше условие. Например, зададим цвет фона. Если вы хотите настраивать внешний вид интерфейса «на лету», вам может пригодиться специальный редактор форм в режиме предприятия.

    
    // Получаем доступ к параметрам оформления
    Оформление = ЭлементУО.Оформление;
        
    // Устанавливаем нужный параметр, например, цвет фона
    Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(230, 255, 230)); // Светло-зеленый
    
  4. Указываем оформляемые поля.

    Это еще один критически важный шаг, на котором часто совершают ошибку. Мы должны явно указать, к каким колонкам на форме применять настроенное оформление. Если этого не сделать, оформление не применится. Если нужно раскрасить всю строку, необходимо перечислить все видимые колонки.

    
    // Получаем коллекцию оформляемых полей
    ОформляемыеПоля = ЭлементУО.Поля.Элементы;
    
    // Добавляем поле для оформления (указываем ИМЯ КОЛОНКИ НА ФОРМЕ)
    Поле = ОформляемыеПоля.Добавить();
    Поле.Поле = Новый ПолеКомпоновкиДанных("ТоварыНоменклатура");
    
    Поле = ОформляемыеПоля.Добавить();
    Поле.Поле = Новый ПолеКомпоновкиДанных("ТоварыКоличество");
    
    Поле = ОформляемыеПоля.Добавить();
    Поле.Поле = Новый ПолеКомпоновкиДанных("ТоварыЦена");
    
    Поле = ОформляемыеПоля.Добавить();
    Поле.Поле = Новый ПолеКомпоновкиДанных("ТоварыСумма");
    

    Обратите внимание: мы используем имена элементов формы (колонок таблицы), а не путь к данным объекта. Если нужно оформить всю строку, можно оставить коллекцию полей пустой — тогда платформа применит оформление ко всей строке.

Собрав все вместе, получим готовый код для процедуры ПриСозданииНаСервере:


&НаСервере
Процедура НастроитьУсловноеОформлениеНаСервере()
    
    // Получаем ссылку на нужную ценовую группу
    ОптоваяГруппа = Справочники.ЦеновыеГруппы.НайтиПоНаименованию("Оптовая");
    Если НЕ ЗначениеЗаполнено(ОптоваяГруппа) Тогда
        Возврат;
    КонецЕсли;

    // Очистим старые настройки, если они добавлялись динамически
    ЭтаФорма.УсловноеОформление.Элементы.Очистить();
    
    // Создаем новый элемент оформления для оптовой группы
    ЭлементУО = ЭтаФорма.УсловноеОформление.Элементы.Добавить();
    
    // 1. Настраиваем ОТБОР
    Отбор = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.Номенклатура.ЦеноваяГруппа");
    Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    Отбор.ПравоеЗначение = ОптоваяГруппа;
    
    // 2. Настраиваем ОФОРМЛЕНИЕ
    ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(230, 255, 230));
    
    // 3. Указываем ПОЛЯ ОФОРМЛЕНИЯ (в данном случае не указываем, чтобы применилось ко всей строке)
    // Если нужно только к определенным колонкам, нужно их добавить в коллекцию ЭлементУО.Поля.Элементы
    
КонецПроцедуры

Решение 2: Использование дополнительной колонки на форме

Иногда прямой доступ к данным не работает (например, из-за особенностей версии платформы) или кажется слишком сложным. В таких случаях можно применить более универсальный подход, похожий на то, как реализуются дополнительные колонки в справочнике и подборах номенклатуры для УТ 11.5. Суть его в том, чтобы вынести нужный для анализа реквизит (ЦеноваяГруппа) в отдельную, "техническую" колонку на форме, а затем настроить условное оформление уже на нее.

Разберем этот метод по шагам.

  1. Добавляем реквизит в табличную часть на форме.

    Откройте форму документа в конфигураторе. В дереве реквизитов формы найдите табличную часть (например, Товары) и добавьте к ней новый реквизит. Назовем его, к примеру, ЦеноваяГруппаНоменклатуры. Стоит отметить, что существует способ добавления реквизитов и элементов формы на управляемые формы легко и просто без кодирования, что может сэкономить время. Важно: этот реквизит добавляется именно в форму, а не в объект метаданных "Документ". Он не будет храниться в базе данных.

    Перетащите этот новый реквизит в таблицу на форме, чтобы создать колонку. Позже ее можно сделать невидимой для пользователя, так как она нужна только для работы механизма условного оформления.

  2. Заполняем данными новую колонку.

    Теперь нам нужно заполнять эту колонку актуальными данными в двух случаях: при загрузке формы и при изменении номенклатуры в строке.

    Заполнение при загрузке формы:

    
    &НаСервере
    Процедура ПриЧтенииНаСервере(ТекущийОбъект)
        // Обходим строки табличной части объекта
        Для Каждого СтрокаТоваров Из ТекущийОбъект.Товары Цикл
            // Находим соответствующую строку в элементах формы
            ДанныеСтрокиФормы = Элементы.Товары.ДанныеСтроки(СтрокаТоваров.ПолучитьИдентификатор());
            Если ДанныеСтрокиФормы <> Неопределено Тогда
                // Заполняем наш новый реквизит формы
                ДанныеСтрокиФормы.ЦеноваяГруппаНоменклатуры = СтрокаТоваров.Номенклатура.ЦеноваяГруппа;
            КонецЕсли;
        КонецЦикла;
    КонецПроцедуры
    

    Обновление при изменении номенклатуры:

    Создадим обработчик события ПриИзменении для поля Номенклатура в табличной части. Такой обмен данными между клиентом и сервером является стандартной практикой для управляемых форм.

    
    &НаКлиенте
    Процедура ТоварыНоменклатураПриИзменении(Элемент, ТекущиеДанные)
        // Получаем текущую строку табличной части
        СтрокаТЧ = Элементы.Товары.ТекущиеДанные;
        Если СтрокаТЧ = Неопределено Тогда
            Возврат;
        КонецЕсли;
    
        // Вызываем серверную процедуру для получения ценовой группы
        УстановитьЦеновуюГруппуНаСервере(СтрокаТЧ.Номенклатура, СтрокаТЧ.ПолучитьИдентификатор());
    КонецПроцедуры
    
    &НаСервереБезКонтекста
    Процедура УстановитьЦеновуюГруппуНаСервере(СсылкаНаНоменклатуру, ИдентификаторСтроки)
        Если ЗначениеЗаполнено(СсылкаНаНоменклатуру) Тогда
            ЦеноваяГруппа = СсылкаНаНоменклатуру.ЦеноваяГруппа;
            // Находим строку формы по идентификатору и изменяем ее данные
            ДанныеСтрокиФормы = Элементы.Товары.ДанныеСтроки(ИдентификаторСтроки);
            Если ДанныеСтрокиФормы <> Неопределено Тогда
                ДанныеСтрокиФормы.ЦеноваяГруппаНоменклатуры = ЦеноваяГруппа;
            КонецЕсли;
        КонецЕсли;
    КонецПроцедуры
    
  3. Настраиваем условное оформление.

    Теперь, когда у нас есть колонка с нужными данными прямо в таблице формы, настройка условного оформления становится тривиальной. Его можно сделать как интерактивно (через "Еще -> Настроить список..."), так и программно.

    Программная настройка будет выглядеть так:

    
    &НаСервере
    Процедура НастроитьУсловноеОформлениеПоКолонке()
        
        // Получаем ссылку на нужную ценовую группу
        ОптоваяГруппа = Справочники.ЦеновыеГруппы.НайтиПоНаименованию("Оптовая");
        
        ЭлементУО = ЭтаФорма.УсловноеОформление.Элементы.Добавить();
        
        // Левое значение теперь - это наша новая колонка!
        Отбор = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Товары.ЦеноваяГруппаНоменклатуры");
        Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        Отбор.ПравоеЗначение = ОптоваяГруппа;
        
        ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(230, 255, 230));
    
    КонецПроцедуры
    

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

← На главную