В типовой конфигурации «1С:Управление производственным предприятием» (УПП) обработка «Печать прайс-листа» строит иерархию номенклатуры строго по алфавиту. Однако в реальном бизнесе часто возникает потребность выводить определенные группы товаров на первые позиции — например, сначала показывать самые маржинальные или ходовые товары (хотя бы топ-5 ключевых папок), а остальные выводить ниже.
Поскольку обработка использует объект ПостроительОтчета, многие разработчики сразу думают об изменении конфигурации и добавлении нового реквизита в справочник Номенклатура. Но снимать конфигурацию с поддержки крайне нежелательно. В этой статье мы подробно разберем, как решить эту задачу элегантно, сохранив конфигурацию типовой, с помощью механизма свойств объектов и внешней обработки.
Мы проанализируем ситуацию, разберем причины технических ограничений и пошагово реализуем три альтернативных метода решения.
---
Многие разработчики ошибочно полагают, что в регистре сведений ЗначенияСвойствОбъектов можно назначать свойства только для конечных элементов справочника. На самом деле, поскольку владельцем свойств выступает справочник Номенклатура в целом, мы можем назначать дополнительные реквизиты и свойства непосредственно его группам (папкам).
Рассмотрим подробнее по шагам, как реализовать этот механизм:
Шаг 1. Создание свойства для папок номенклатуры
СвойстваОбъектов.Число (длина 5, точность 1 или 0). Использование дробных чисел или разреженных индексов (с шагом 10, 20, 30...) избавит нас от необходимости массово пересчитывать индексы при добавлении новой папки в середину списка.Шаг 2. Создание внешней обработки
Для того чтобы не менять типовую конфигурацию, сохраним стандартную обработку ПечатьПрайсЛиста как внешнюю обработку (формат .epf). Работать мы будем непосредственно с ее кодом.
Шаг 3. Модификация текста запроса ПостроителяОтчета
Стандартный механизм динамического добавления свойств в УПП (процедура ДобавитьВТекстСвойстваИКатегории) связывает свойства с самим элементом номенклатуры, а не с его родителем. Поэтому нам необходимо вручную скорректировать запрос в коде обработки. Выясним причину: нам нужно левым соединением связать таблицу номенклатуры с регистром сведений ЗначенияСвойствОбъектов по полю Родитель.
Разберем пример модификации текста запроса перед его выполнением в ПостроительОтчета:
// Получаем исходный текст запроса построителя
ТекстЗапроса = ПостроительОтчета.Текст;
// Добавим связь с регистром значений свойств объектов для родительской папки
НовыйТекстЗапроса =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Номенклатура,
| ЕСТЬNULL(ПорядокПапок.Значение, 99999) КАК ИндексСортировкиПапки,
| // ... другие типовые поля запроса ...
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ПорядокПапок
| ПО Номенклатура.Родитель = ПорядокПапок.Объект
| И ПорядокПапок.Свойство = &СвойствоСортировки
|// ... остальная часть типового запроса ...";
// Устанавливаем измененный текст обратно в построитель
ПостроительОтчета.Текст = НовыйТекстЗапроса;
// Задаем параметр запроса - созданное нами свойство
ПостроительОтчета.Параметры.Вставить("СвойствоСортировки", ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Порядок в прайс-листе"));
Затем в настройках порядка ПостроительОтчета.Порядок (или непосредственно в тексте запроса в секции {УПОРЯДОЧИТЬ ПО ...}) устанавливаем сортировку сначала по полю ИндексСортировкиПапки, а уже затем по наименованию папки.
---
Если заказчику требуется управлять сортировкой «на лету» без необходимости заходить в карточки папок номенклатуры и прописывать свойства, можно реализовать визуальный выбор приоритетных групп прямо на форме внешней обработки.
Посмотрим на пример реализации данного подхода:
ПриоритетныеГруппы с единственной колонкой ГруппаНоменклатуры (тип СправочникСсылка.Номенклатура, с отбором «ЭтоГруппа = Истина»).ВЫБОР КОГДА для динамического построения запроса.Проанализируем программный код, который будет модифицировать запрос:
// Формируем текст условия ВЫБОР КОГДА на основе пользовательской таблицы
ТекстВыбора = "ВЫБОР ";
Индекс = 1;
Для Каждого СтрокаТЧ Из ПриоритетныеГруппы Цикл
ТекстВыбора = ТекстВыбора + "КОГДА Номенклатура.Родитель = &ГруппаСортировки" + Индекс + " ТОГДА " + Индекс + " ";
Индекс = Индекс + 1;
КонецЦикла;
ТекстВыбора = ТекстВыбора + "ИНАЧЕ 99999 КОНЕЦ КАК ПриоритетГруппы";
// Интегрируем полученное поле в текст запроса ПостроителяОтчета
ТекстЗапроса = ПостроительОтчета.Текст;
// Заменяем в блоке ВЫБРАТЬ или добавляем новое поле
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "Номенклатура.Ссылка КАК Номенклатура,", "Номенклатура.Ссылка КАК Номенклатура, " + ТекстВыбора + ",");
ПостроительОтчета.Текст = ТекстЗапроса;
// Передаем параметры в построитель
Индекс = 1;
Для Каждого СтрокаТЧ Из ПриоритетныеГруппы Цикл
ПостроительОтчета.Параметры.Вставить("ГруппаСортировки" + Индекс, СтрокаТЧ.ГруппаНоменклатуры);
Индекс = Индекс + 1;
КонецЦикла;
Этот метод максимально удобен для конечного пользователя, так как вся настройка сортировки происходит в одном месте непосредственно перед формированием прайс-листа.
---
Если результат нужен «вчера», а бюджета или времени на разработку внешних обработок нет, можно воспользоваться стандартными возможностями платформы 1С по упорядочиванию данных.
Рассмотрим два варианта изменения сортировки без изменения программного кода:
01. Компьютеры, 02. Мониторы, 03. Комплектующие. База автоматически отсортирует их по алфавиту в нужном порядке.ПостроителяОтчета (на вкладке «Сортировка») пользователь может установить сортировку по реквизиту Код вместо Наименование. В этом случае достаточно изменить коды у первых пяти ключевых папок номенклатуры (например, задать им коды 000000001, 000000002 и т.д.), чтобы они гарантированно выводились первыми.Несмотря на свою простоту, этот метод имеет очевидный недостаток — меняются наименования или коды папок непосредственно в информационной базе, что может повлиять на интеграцию с другими системами (например, с сайтом интернет-магазина) или затруднить поиск номенклатуры менеджерами в повседневной работе.
---
Мы детально разобрали проблему сортировки иерархии в прайс-листе УПП. Использование регистра сведений «Значения свойств объектов» в связке с внешней обработкой является наиболее гибким, архитектурно правильным и безопасным решением, которое сохраняет конфигурацию полностью типовой и позволяет легко обновлять систему в будущем.