При работе с типовыми конфигурациями на базе обычных форм, такими как Комплексная автоматизация 1.1 или УПП 1.3, разработчики часто сталкиваются с необходимостью кастомизации стандартных отчетов. Одной из популярных задач является программная установка условного оформления. Например, нам нужно выделить цветом номенклатуру, принадлежащую к определенной категории, в отчете Анализ доступности товаров на складах.
Основная сложность здесь заключается в том, что категории и свойства в Универсальном отчете (который базируется на объекте ПостроительОтчета) являются динамическими полями. Мы не можем просто обратиться к ним по имени, как к обычному реквизиту. В этой статье мы разберем, почему возникает ошибка при добавлении отбора и как правильно сформировать техническое имя поля для успешного оформления.
Рассмотрим типичную ситуацию. Программист пытается добавить условие оформления, указывая в качестве поля отбора заголовок, который он видит в пользовательском интерфейсе, например, "Новый (категория Номенклатура)". Система выдает ошибку: Недопустимое значение параметра (параметр номер '1'). Это происходит потому, что метод Добавить() коллекции Отбор ожидает не пользовательское представление и не ссылку на объект, а конкретный путь к данным (имя поля), который понимает ПостроительОтчета.
Проанализируем ситуацию: когда в настройках отчета включен флаг УниверсальныйОтчет.ИспользоватьСвойстваИКатегории = Истина, система динамически модифицирует текст запроса, присоединяя таблицы категорий и свойств. Имена этих полей генерируются по определенному алгоритму, и именно их нужно использовать в коде.
Наиболее точный способ программно обратиться к категории — сконструировать имя поля самостоятельно. Выясним причину: Универсальный отчет формирует имена для категорий по следующему шаблону: [ИмяТаблицы]Категория[GUID_категории_без_тире]Категория.
Посмотрим на пример реализации этого метода в модуле объекта отчета:
// В процедуре УстановитьНачальныеНастройки или перед формированием
Условие = УниверсальныйОтчет.ПостроительОтчета.УсловноеОформление;
Условие.Очистить();
// Создаем новый элемент оформления
ЭлемУслОформл = Условие.Добавить("ВыделениеКатегории", "Выделение категории");
ЭлемУслОформл.Использование = Истина;
// Указываем область: в данном случае только поле "Номенклатура"
ЭлемОбласти = ЭлемУслОформл.Область.Добавить("Номенклатура");
// Получаем идентификатор нужной категории
КатегорияСсылка = Справочники.КатегорииОбъектов.НайтиПоНаименованию("Неликвидный");
Если НЕ КатегорияСсылка.Пустая() Тогда
УИД = КатегорияСсылка.УникальныйИдентификатор();
// Формируем техническое имя поля (убираем тире из GUID)
ИмяПоляКатегории = "НоменклатураКатегория" + СтрЗаменить(Строка(УИД), "-", "") + "Категория";
// Добавляем отбор
ЭлементОтбора = ЭлемУслОформл.Отбор.Добавить(ИмяПоляКатегории);
ЭлементОтбора.Значение = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Использование = Истина;
// Устанавливаем оформление (например, цвет фона)
ЭлемУслОформл.Оформление.ЦветФона.Значение = WebЦвета.Лосось;
ЭлемУслОформл.Оформление.ЦветФона.Использование = Истина;
КонецЕсли;
В данном коде мы сначала находим нужную категорию в справочнике КатегорииОбъектов. Затем мы получаем её УникальныйИдентификатор() и преобразуем его в строку, удаляя лишние символы (тире). Это критически важно, так как имена полей в 1С не могут содержать спецсимволы.
Если вы не хотите зависеть от алгоритмов формирования имен (которые теоретически могут измениться в новых релизах платформы или конфигурации), можно применить более гибкий подход. Рассмотрим подробнее вариант с перебором коллекции ДоступныеПоля Построителя отчета.
Разберем по шагам, как найти нужное поле по его пользовательскому представлению:
ИмяПоляДляОтбора = "";
ИскомоеПредставление = "Неликвидный (категория Номенклатура)";
Для Каждого Поле Из УниверсальныйОтчет.ПостроительОтчета.ДоступныеПоля Цикл
Если Поле.Представление = ИскомоеПредставление Тогда
ИмяПоляДляОтбора = Поле.ПутьКДанным;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЗначениеЗаполнено(ИмяПоляДляОтбора) Тогда
// Теперь мы можем безопасно использовать ИмяПоляДляОтбора в методе Добавить()
ЭлементОтбора = ЭлемУслОформл.Отбор.Добавить(ИмяПоляДляОтбора);
// ... дальнейшая настройка отбора ...
КонецЕсли;
Этот метод считается более надежным, так как он опирается на те данные, которые сам ПостроительОтчета уже загрузил в свою схему. Однако помните, что этот поиск сработает только после того, как отчет будет инициализирован и построитель сформирует список доступных полей.
Проанализируем несколько технических моментов, которые часто упускают из виду:
ЭлемУслОформл.Область. Если коллекция пуста, оформление применяется ко всей строке результата.УстановитьНачальныеНастройки, учитывайте, что настройки пользователя, сохраненные ранее, могут перекрыть ваши программные изменения. Для принудительного применения оформления используйте код непосредственно перед выполнением отчета.Свойство[GUID].Если ваш отчет имеет иерархическую структуру (например, группировка по иерархии номенклатуры), стоит учитывать, что категории обычно назначаются только элементам. Группы (папки) номенклатуры по умолчанию не будут соответствовать условию Категория = Истина, и их оформление не изменится. Если вам нужно подкрасить и родительские группы, логику отбора придется усложнить, проверяя вхождение в группу или используя дополнительные механизмы агрегации.
Таким образом, мы выяснили, что ключ к программному управлению оформлением в Универсальном отчете — это правильное определение ПутиКДанным для динамических полей. Используя либо прямой расчет имени через УникальныйИдентификатор, либо поиск в ДоступныхПолях, вы сможете гибко настраивать визуальное представление любых типовых отчетов под нужды пользователей.