Как в 1С отсортировать данные запроса в соответствии с порядком элементов в переданном списке?

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

В практике разработки на платформе 1С часто возникает задача: передать в запрос список элементов (например, Склады, Номенклатуру или Контрагентов) и получить результат именно в том порядке, в котором они были расположены в исходном СпискеЗначений или Массиве. По умолчанию СУБД возвращает данные в произвольном порядке или по индексам таблиц базы данных. Рассмотрим подробно несколько эффективных способов решения этой задачи: от простых программных методов до использования стандартных подсистем.

Метод 1. Использование временной таблицы с индексом порядка

Этот метод считается наиболее профессиональным и гибким. Он позволяет передать в запрос любую последовательность и гарантированно получить её на выходе. Разберем по шагам алгоритм реализации:

  1. Создадим ТаблицуЗначений с двумя колонками: ссылкой на объект и числовым полем для хранения индекса (порядка).
  2. Заполним эту таблицу данными из нашего списка, присваивая каждой строке порядковый номер.
  3. Передадим таблицу в запрос как параметр и поместим её во временную таблицу.
  4. Выполним соединение основной таблицы данных с этой временной таблицей и укажем сортировку по полю порядка.

Проанализируем пример кода:


// 1. Подготовка данных
ТаблицаПорядка = Новый ТаблицаЗначений;
ТаблицаПорядка.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("СправочникСсылка.Склады"));
ТаблицаПорядка.Колонки.Добавить("Порядок", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0)));

Для Каждого ЭлементСписка Из ИсходныйСписокСкладов Цикл
    НоваяСтрока = ТаблицаПорядка.Добавить();
    НоваяСтрока.Ссылка = ЭлементСписка.Значение;
    НоваяСтрока.Порядок = ИсходныйСписокСкладов.Индекс(ЭлементСписка);
КонецЦикла;

// 2. Выполнение запроса
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТЗ_Порядок.Ссылка КАК Склад,
    |	ТЗ_Порядок.Порядок КАК НомерПорядка
    |ПОМЕСТИТЬ ВТ_Порядок
    |ИЗ
    |	&ТаблицаПорядка КАК ТЗ_Порядок
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |	Склады.Ссылка КАК Ссылка,
    |	Склады.Наименование КАК Наименование,
    |	ВТ_Порядок.НомерПорядка КАК НомерПорядка
    |ИЗ
    |	Справочник.Склады КАК Склады
    |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Порядок КАК ВТ_Порядок
    |		ПО Склады.Ссылка = ВТ_Порядок.Склад
    |
    |УПОРЯДОЧИТЬ ПО
    |	НомерПорядка";

Запрос.УстановитьПараметр("ТаблицаПорядка", ТаблицаПорядка);
РезультатЗапроса = Запрос.Выполнить();

Этот способ позволяет избежать ограничений на количество элементов в списке и работает максимально быстро на уровне SQL-сервера.

Метод 2. Конструкция ВЫБОР КОГДА в тексте запроса

Если список элементов небольшой и фиксированный (например, 3-5 складов), можно воспользоваться оператором ВЫБОР непосредственно в предложении УПОРЯДОЧИТЬ ПО. Рассмотрим ситуацию, когда нам нужно вывести определенные склады первыми:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Склады.Ссылка КАК Ссылка,
    |	Склады.Наименование КАК Наименование
    |ИЗ
    |	Справочник.Склады КАК Склады
    |ГДЕ
    |	Склады.Ссылка В(&СписокСкладов)
    |
    |УПОРЯДОЧИТЬ ПО
    |	ВЫБОР
    |		КОГДА Склады.Ссылка = &Склад1 ТОГДА 1
    |		КОГДА Склады.Ссылка = &Склад2 ТОГДА 2
    |		ИНАЧЕ 3
    |	КОНЕЦ";

Важный нюанс: Данный метод не рекомендуется использовать для больших списков (более 20-30 элементов), так как это значительно усложняет план выполнения запроса в СУБД и может привести к ошибкам парсинга при слишком большом количестве условий.

Метод 3. Использование функционала БСП «Настройка порядка элементов»

В современных конфигурациях на базе Библиотеки стандартных подсистем (БСП) предусмотрен штатный механизм для управления порядком. Если вам нужно, чтобы склады во всех отчетах всегда выводились в определенном пользовательском порядке, выполним следующие действия:

Этот подход освобождает программиста от необходимости "хардкодить" правила сортировки и передает управление бизнес-пользователям.

Метод 4. Дополнительные реквизиты и сведения (без изменения кода)

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

  1. В режиме "1С:Предприятие" создадим для справочника "Склады" дополнительный реквизит типа Число с названием "ПриоритетСортировки".
  2. Пользователь заполняет этот реквизит для каждого склада (10, 20, 30...).
  3. В любом отчете на базе Системы компоновки данных (СКД) этот реквизит будет доступен в настройках сортировки.

Разберем преимущество: это не портит наименования объектов (что важно для обменов с внешними системами) и позволяет легко менять приоритеты без участия разработчика.

Метод 5. Сортировка по списку в Системе компоновки данных (СКД)

Проанализируем ситуацию, когда данные выводятся в отчет. СКД умеет работать с внешними наборами данных. Если мы сначала программно подготовим ТаблицуЗначений, отсортируем её методом ТаблицаЗначений.Сортировать("Порядок Возр") и передадим в СКД, компоновщик сохранит этот порядок при выводе, если в настройках самого отчета не задана иная сортировка.

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

Резюме и рекомендации

Выбор метода зависит от конкретных условий задачи:

← На главную