Как реализовать программное условное оформление в 1С:ERP по дополнительным реквизитам номенклатуры?

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

При работе с крупными конфигурациями, такими как 1С:ERP Управление предприятием 2 или 1С:Комплексная автоматизация, часто возникает задача визуального выделения строк в табличных частях документов. Одной из наиболее востребованных функций является раскраска строк в зависимости от значений дополнительных реквизитов номенклатуры. Поскольку дополнительные реквизиты хранятся в отдельной табличной части справочника, настроить такое оформление через стандартный конструктор в конфигураторе бывает затруднительно или невозможно без написания кода. Для вывода этих данных без самостоятельного программирования можно применить расширение для отображения дополнительных реквизитов в табличной части.

В этой статье мы подробно разберем, как программно реализовать условное оформление в документе ЗаказКлиента, чтобы фон строк в таблице Товары менялся в зависимости от значения дополнительного реквизита «Хар-ка формирования запасов». Мы проанализируем типичные ошибки, выясним, почему нельзя выполнять запросы в цикле, и рассмотрим два эффективных способа решения задачи.

Проблема производительности: почему запрос в цикле — это плохо

Разберем типичную ситуацию: разработчик пытается в цикле по строкам табличной части выполнять запрос к базе данных, чтобы получить значение дополнительного реквизита для каждой номенклатуры. Это в корне неверный подход. Если в документе будет 100 строк, система выполнит 100 обращений к серверу БД, что приведет к значительным задержкам при открытии формы или изменении данных.

Правильная стратегия заключается в том, чтобы получить все необходимые данные одним запросом. Проанализируем, как это сделать правильно:

  1. Сначала мы собираем все уникальные ссылки на номенклатуру из табличной части в массив.
  2. Затем передаем этот массив в запрос.
  3. Получаем результат и на его основе строим правила условного оформления.

Способ 1: Программное добавление элементов условного оформления

Этот метод подразумевает создание правил в коллекции УсловноеОформление формы. Рассмотрим пример кода, который необходимо разместить в процедуре ПриСозданииНаСервере или в специализированной процедуре установки оформления.

Для начала подготовим данные. Выясним значения дополнительного реквизита для всей номенклатуры в документе:


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

КонецПроцедуры

Рассмотрим подробнее, что здесь происходит. Мы используем объект ПолеКомпоновкиДанных, чтобы указать платформе, к какому полю данных (реквизиту объекта) или элементу формы (колонке) относится условие. Важно помнить: в отборе мы используем путь к данным (например, Объект.Товары.Номенклатура), а в полях оформления — имена элементов формы (например, ТоварыНоменклатура). Чтобы быстрее формировать нужные программные конструкции, можно использовать инструмент для генерации кода условного оформления.

Способ 2: Использование вспомогательного реквизита формы (рекомендуемый)

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

Разберем по шагам:

  1. Добавим в Реквизиты формы (не в метаданные конфигурации!) для таблицы Товары новую колонку, например, ХаркаДляОформления (тип: Строка или Число).
  2. При открытии формы или изменении номенклатуры будем заполнять эту колонку значением из дополнительного реквизита.
  3. В Условном оформлении создадим всего несколько правил, которые будут проверять значение этой технической колонки.

Это значительно упрощает логику. Нам не нужно создавать правило для каждой отдельной номенклатуры. Мы создаем правила для типов характеристик. Например, "Если ХаркаДляОформления = 'Заказ', то цвет зеленый".


// Пример заполнения реквизита формы при изменении номенклатуры
&НаСервере
Процедура ЗаполнитьПризнакОформленияДляСтроки(НомерСтроки)
    
    ТекущаяСтрока = Объект.Товары[НомерСтроки];
    // Получаем значение доп. реквизита через запрос или функцию БСП
    ЗначениеДопРеквизита = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ТекущаяСтрока.Номенклатура, "ХаркаФормированияЗапасов"); 
    
    // Записываем в колонку формы
    ТекущаяСтрока.ХаркаДляОформления = Строка(ЗначениеДопРеквизита);
    
КонецПроцедуры

Теперь в УсловномОформлении достаточно настроить отбор по полю Объект.Товары.ХаркаДляОформления. Этот метод работает гораздо быстрее, так как платформе не нужно сравнивать ссылки номенклатуры в каждой строке, она просто проверяет готовое строковое значение в текущей строке таблицы.

Разбор типичных ошибок: Элементы vs ЭтаФорма

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

Также важно различать контексты: ЭтаФорма в модуле управляемой формы является ссылкой на саму форму. Выражения Элементы, ЭтаФорма.Элементы и ЭтотОбъект.Элементы в контексте модуля формы идентичны. Ошибка "Метод объекта не обнаружен (ВыгрузитьКолонку)" возникает, когда вы пытаетесь вызвать метод таблицы значений у данных формы (коллекции строк). Чтобы использовать методы таблицы значений, нужно сначала преобразовать данные формы в значение с помощью функции РеквизитФормыВЗначение("Объект").

Резюме

Для реализации качественного условного оформления по дополнительным реквизитам в 1С:ERP:

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

← На главную