Почему не работает сортировка при использовании ВыбратьЭлементыПоРеквизиту в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке на платформе 1С:Предприятие 7.7 мы часто сталкиваемся с необходимостью выборки элементов справочника, отфильтрованных по определенному реквизиту. Однако при попытке совместить такую выборку с сортировкой по коду через ПорядокКодов(), мы обнаруживаем, что элементы возвращаются в произвольном порядке. Давайте разберем, почему это происходит и как решить данную задачу.

Причина возникновения проблемы

Основная причина кроется в архитектуре работы индексов базы данных 1С 7.7. Метод ВыбратьЭлементыПоРеквизиту() предназначен для быстрого поиска элементов по значению конкретного реквизита. Для работы этого механизма 1С использует индекс, построенный именно по этому реквизиту.

Когда вы вызываете ВыбратьЭлементыПоРеквизиту(), система принудительно переключается на использование индекса по данному реквизиту. В этот момент настройки сортировки, заданные методами ПорядокКодов() или ПорядокНаименований(), игнорируются, так как база данных не может одновременно использовать индекс реквизита для фильтрации и индекс кода для сортировки. Результаты будут следовать в том порядке, в котором они физически записаны в индексе выбранного реквизита.

Способ решения №1: Использование таблицы значений

Если объем данных не является критически огромным (сотни тысяч записей), самым простым и производительным штатным способом будет выгрузка выборки в ТаблицаЗначений с последующей сортировкой в оперативной памяти. Это позволит избежать перебора записей с условиями Если внутри цикла.

Рассмотрим пошаговый алгоритм:

  1. Создаем объект Справочник.
  2. Выполняем ВыбратьЭлементыПоРеквизиту() без предварительного задания порядка.
  3. Выгружаем полученные данные в ТаблицаЗначений.
  4. Сортируем полученную таблицу методом Сортировать().

// Пример реализации сортировки через ТЗ
Спр = СоздатьОбъект("Справочник.НомераСФ");
ТЗ = СоздатьОбъект("ТаблицаЗначений");
ТЗ.НоваяКолонка("Элемент");
ТЗ.НоваяКолонка("Код");

Спр.ВыбратьЭлементыПоРеквизиту("ДатаСФ", ЦелеваяДата, 1, 0);
Пока Спр.ПолучитьЭлемент() = 1 Цикл
    ТЗ.НоваяСтрока();
    ТЗ.Элемент = Спр.ТекущийЭлемент();
    ТЗ.Код = Число(Спр.Код);
КонецЦикла;

ТЗ.Сортировать("Код");

Этот подход работает значительно быстрее, чем ручной перебор и сравнение значений в цикле, так как сортировка происходит средствами платформы внутри оптимизированной структуры данных.

Способ решения №2: Прямые SQL-запросы

Для профессиональной разработки, особенно в клиент-серверных вариантах работы, рекомендуется использовать внешние компоненты, такие как 1С++. Прямые запросы к SQL-серверу позволяют формировать выборки любой сложности, объединяя фильтрацию по реквизиту и сортировку по любому полю в рамках одного запроса.

Преимущества прямого запроса:

Рассмотрим структуру запроса:


// Концептуальный пример запроса через 1С++
ТекстЗапроса = "
|SELECT ID as [Элемент $Справочник.НомераСФ], CODE as Код
|FROM $Справочник.НомераСФ
|WHERE $ДатаСФ = :ДатаПараметр
|ORDER BY CODE ASC";

Резюме

Итак, мы выяснили, что ПорядокКодов() не работает совместно с ВыбратьЭлементыПоРеквизиту(), так как последний метод жестко переключает индекс выборки. Чтобы получить отсортированный список, мы рекомендуем использовать один из двух вариантов:

Использование сложных конструкций с ручным поиском максимума и минимума внутри цикла Пока не рекомендуется, так как это нерационально расходует ресурсы и усложняет поддержку кода.

← На главную