При разработке отчетов в 1С, особенно для торговых предприятий, мы часто сталкиваемся с задачей вывода размерных сеток. Казалось бы, простая задача, но если поле Размер имеет тип "Строка", стандартная сортировка платформы работает по алфавиту. В результате мы получаем нелогичный порядок: L, M, S, XL, XS (поскольку сортировка идет по первым буквам). В то время как пользователю необходим логический порядок: XS, S, M, L, XL.
Рассмотрим подробно все способы решения этой задачи — от архитектурно правильных изменений метаданных до "хитростей" в запросах и настройках Системы Компоновки Данных (СКД), которые позволяют добиться нужного результата без изменения конфигурации.
Компьютер не понимает семантику размера. Для него "XS" — это просто набор символов. Если в базе хранятся и буквенные размеры, и цифровые (например, "36", "38", "5", "100"), сортировка строк дает еще более странные результаты: "100" будет идти раньше, чем "36", так как символ "1" меньше символа "3".
Давайте разберем четыре основных метода, как мы можем научить систему сортировать размеры правильно.
Если у вас есть возможность вносить изменения в структуру конфигурации (вы разработчик и база не на полной поддержке без возможности изменений), этот вариант является наиболее предпочтительным и производительным.
Суть метода заключается в добавлении числового веса каждому размеру.
ЗначенияСвойствОбъектов, если используются характеристики, или отдельный справочник Размеры).ПорядокСортировки (тип Число).После этого в запросе СКД нам достаточно выбрать не просто ссылку на размер, но и этот реквизит. В настройках сортировки отчета мы указываем поле Размер.ПорядокСортировки.
Преимущества: работает быстро, легко настраивается пользователем в режиме Предприятия.
Если менять структуру базы нельзя, мы можем задать логику сортировки прямо в тексте запроса. Этот метод отлично подходит, когда набор размеров фиксирован и меняется редко.
Мы создадим в запросе временную таблицу, где явно укажем соответствие строки размера и его числового приоритета.
Рассмотрим пример кода запроса:
ВЫБРАТЬ
"XS" КАК НазваниеРазмера,
1 КАК Порядок
ПОМЕСТИТЬ втСортировка
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"S",
2
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"M",
3
// ... перечисляем все нужные варианты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Товары.Номенклатура,
Товары.Размер,
ЕСТЬNULL(втСортировка.Порядок, 99) КАК ПолеСортировки
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ втСортировка КАК втСортировка
ПО Товары.Размер = втСортировка.НазваниеРазмера
Далее в настройках СКД на вкладке "Сортировка" мы используем поле ПолеСортировки, но на вывод пользователю его не подаем. Записи, для которых размер не найден в нашей таблице, получат порядок 99 и уйдут в конец списка.
Этот способ позволяет решить задачу исключительно средствами СКД, не усложняя текст основного запроса лишними соединениями. Это особенно удобно, если вы редактируете только схему компоновки внешнего отчета.
Перейдем на вкладку Вычисляемые поля в конструкторе схемы компоновки данных.
ПорядокРазмера.Пример выражения для буквенных размеров:
ВЫБОР
КОГДА Размер = "XS" ТОГДА 1
КОГДА Размер = "S" ТОГДА 2
КОГДА Размер = "M" ТОГДА 3
КОГДА Размер = "L" ТОГДА 4
КОГДА Размер = "XL" ТОГДА 5
ИНАЧЕ 100
КОНЕЦ
Теперь перейдем на вкладку Настройки варианта отчета. В разделе "Сортировка" добавим наше поле ПорядокРазмера. В выбранные поля добавлять его не нужно, пользователь увидит только текст размера, но строки будут выстроены верно.
Часто встречается ситуация, когда размер записан строкой, но представляет собой число. Например: "5", "36", "100". Обычная сортировка выстроит их так: "100", "36", "5".
Чтобы исправить это без преобразования типов (которое может вызвать ошибку, если вдруг попадется буква), мы можем использовать метод дополнения нулями слева. Это также можно сделать в вычисляемом поле СКД.
Логика следующая: приведем все строки к одинаковой длине, добавив нули. Тогда "5" превратится в "005", "36" в "036", а "100" останется "100". Сортировка строк "005", "036", "100" даст корректный математический порядок.
Выражение для вычисляемого поля СКД:
// Добавляем слева нули, а затем берем правые N символов
Прав("00000" + Размер, 5)
Используйте это поле для сортировки цифровых размеров.
Если в одной колонке у вас могут встретиться и "XS", и "36", простого решения не существует. Вам потребуется создать сложное поле сортировки, которое сначала разделяет типы размеров, а затем сортирует внутри группы.
Проанализируем алгоритм для вычисляемого поля:
Однако, так как поле сортировки должно быть одного типа (обычно число), лучше разбить сортировку на два уровня в настройках СКД:
Уровень 1. Тип размера (Вычисляемое поле)
ВЫБОР
КОГДА Размер В ("XS", "S", "M", "L", "XL", "XXL") ТОГДА 1
ИНАЧЕ 2
КОНЕЦ
Уровень 2. Значение внутри типа
Здесь придется применить хитрость. Поскольку мы не можем в одном поле вернуть и число (для маппинга букв), и строку (для "036"), лучше все привести к строке фиксированной длины, которая будет служить ключом сортировки.
Пример универсального выражения для сортировки:
ВЫБОР
КОГДА Размер = "XS" ТОГДА "001"
КОГДА Размер = "S" ТОГДА "002"
КОГДА Размер = "M" ТОГДА "003"
КОГДА Размер = "L" ТОГДА "004"
// ...
// Для остальных (цифровых) считаем, что они идут после букв и сортируем их как числа через дополнение
ИНАЧЕ "9" + Прав("0000" + Размер, 4)
КОНЕЦ
В результате сортировка по этому полю даст:
Визуально это обеспечит идеальный порядок: сначала международные размеры по возрастанию, затем цифровые по возрастанию.
Мы рекомендуем, по возможности, использовать Способ 1 (добавление реквизита порядка в справочник). Это исключает хардкод (жестко прописанные значения) в коде конфигурации или внешних отчетах. Если появится новый размер (например, "XXXL"), пользователю достаточно будет зайти в карточку размера и поставить ему следующий порядковый номер, и все отчеты автоматически начнут сортировать его правильно.
Остальные способы подходят как временные решения или решения для специфических задач, где изменение структуры базы данных невозможно.