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