Разработка и Конфигурация · 10 мин
Как отсортировать выборку в 1С: все рабочие способы
Как отсортировать выборку в 1С: УПОРЯДОЧИТЬ ПО в запросе, сортировка динамического списка, таблицы значений и СКД. Примеры кода, ошибки и FAQ.
Под «выборкой» в 1С обычно понимают результат запроса, динамический список на форме, таблицу значений или данные отчёта на СКД. В каждом случае сортировка устроена по-разному, и попытка применить один приём ко всем ситуациям — самая частая причина того, что порядок строк «не слушается».
Правильный способ зависит от того, где данные появляются. Если порядок нужен в момент получения данных из базы — сортируйте в запросе. Если пользователь должен сам менять порядок в списке — настраивайте динамический список. Если данные уже собраны в памяти — используйте методы сортировки таблицы значений. Ниже разобраны все четыре сценария с примерами кода и типичными ошибками.
Сортировка в запросе: УПОРЯДОЧИТЬ ПО
Основной инструмент — секция УПОРЯДОЧИТЬ ПО в конце текста запроса. Она указывает, по каким полям и в каком направлении сервер вернёт строки. Направление задаётся ключевыми словами ВОЗР (по возрастанию, используется по умолчанию) и УБЫВ (по убыванию).
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления
|
|УПОРЯДОЧИТЬ ПО
| Наименование УБЫВ";
Результат = Запрос.Выполнить().Выбрать();
Сортировать можно по нескольким полям — они перечисляются через запятую, и для каждого задаётся своё направление. Порядок полей важен: сначала строки сравниваются по первому полю, при равенстве — по второму и так далее. Например, УПОРЯДОЧИТЬ ПО Дата УБЫВ, Номер УБЫВ выдаст документы от новых к старым, а внутри одной даты — по убыванию номера.
Допустимо упорядочивание по полю, которого нет в списке выборки, если оно доступно в источнике. Однако лучше включать такое поле в выборку — это упрощает отладку и проверку результата глазами.
Сортировка по представлению и по ссылке: в чём подвох
Частая ситуация: разработчик сортирует по полю типа «Ссылка» и получает внешне хаотичный порядок. Это нормально: ссылка сортируется по внутреннему значению, а не по наименованию или номеру, которые видит пользователь. Чтобы получить «человеческий» порядок, сортируйте по реквизиту — Наименование, Дата, Номер.
Обратный подвох — сортировка по строковому полю, где хранятся числа. Строки «10», «2», «100» отсортируются как «10», «100», «2», потому что сравнение идёт посимвольно. Если нужен числовой порядок, храните значение в числовом реквизите или приводите тип в запросе через ВЫРАЗИТЬ(... КАК ЧИСЛО(...)).
Ещё одна тонкость — поля с NULL. В результатах соединений пустые значения обычно попадают в начало при сортировке по возрастанию. Если это мешает, оберните поле в ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) и сортируйте по результату.
Сортировка динамического списка на форме
Динамический список (список документов, справочника в форме) строится на запросе, и у него есть собственное свойство Порядок. Если основной запрос списка уже содержит УПОРЯДОЧИТЬ ПО, пользовательская сортировка через шапку таблицы может не работать — жёстко заданный порядок в тексте запроса «перекрывает» настройки.
Чтобы пользователь мог сам менять сортировку, уберите секцию УПОРЯДОЧИТЬ ПО из текста запроса динамического списка и задайте начальный порядок программно:
ЭлементПорядка = Список.Порядок.Элементы.Добавить(
Тип("ЭлементПорядкаКомпоновкиДанных"));
ЭлементПорядка.Поле = Новый ПолеКомпоновкиДанных("Дата");
ЭлементПорядка.ТипУпорядочивания =
НаправлениеСортировкиКомпоновкиДанных.Убыв;
ЭлементПорядка.Использование = Истина;
Такой порядок станет начальным, но пользователь сможет изменить его кликом по заголовку колонки или через «Настройку списка». Если же порядок должен быть неизменным (например, очередь задач по приоритету) — наоборот, оставьте УПОРЯДОЧИТЬ ПО в тексте запроса и отключите пользовательскую настройку порядка.
Как выбрать способ
Сортировка таблицы значений и массива
Когда данные уже получены и лежат в таблице значений, применяется метод Сортировать(). Параметр — строка с именами колонок и направлением: ТаблицаРезультатов.Сортировать("Дата Убыв, Сумма Возр"). Метод меняет саму таблицу, новую не создаёт, поэтому при необходимости сохранить исходный порядок сделайте копию через Скопировать().
Для массива структур или произвольных данных встроенной сортировки нет. Практичный приём — выгрузить данные в таблицу значений, отсортировать её и прочитать обратно. Это быстрее и надёжнее, чем писать собственный алгоритм сортировки на встроенном языке.
Отдельный случай — дерево значений. Метод Сортировать() у дерева по умолчанию сортирует только верхний уровень. Чтобы отсортировать иерархию на всех уровнях, передайте второй параметр Истина: Дерево.Сортировать("Наименование", Истина).
ТЗ = Запрос.Выполнить().Выгрузить();
ТЗ.Сортировать("Дата Убыв, Наименование Возр");
Для Каждого Строка Из ТЗ Цикл
// обработка в нужном порядке
КонецЦикла;Сортировка в отчётах на СКД
В отчётах на системе компоновки данных порядок задаётся не в запросе, а на закладке «Сортировка» настроек отчёта. Если оставить УПОРЯДОЧИТЬ ПО в тексте запроса схемы, это лишь ограничит гибкость: пользовательские настройки сортировки будут конфликтовать с жёстким порядком запроса.
Правильная схема: в запросе схемы компоновки секцию упорядочивания не пишут (либо оставляют только технически необходимую), а нужный порядок по умолчанию задают в настройках схемы на вкладке «Сортировка». Тогда пользователь отчёта сможет менять порядок через кнопку «Настройки» без доработки конфигурации.
Проверить результат просто: сформируйте отчёт, откройте настройки и убедитесь, что в списке сортировки доступны нужные поля и их можно переставлять. Если поле недоступно для сортировки — проверьте, что оно включено в выбранные поля или вычисляемые поля схемы.
Если сортировка «не работает» в списке или отчёте, в девяти случаях из десяти причина — жёстко прописанный УПОРЯДОЧИТЬ ПО в тексте запроса. Начинайте поиск проблемы именно с него.
Производительность и ограничения
Сортировка больших выборок выполняется на сервере СУБД и может быть дорогой, если по полю сортировки нет подходящего индекса. Для типовых реквизитов (дата, номер, наименование) индексы обычно уже существуют, а вот сортировка по вычисляемому выражению или по полю через несколько соединений может заметно замедлить запрос на больших таблицах.
Если выборка используется для обхода и обработки, а порядок не влияет на результат, лучше вообще убрать упорядочивание — это ускорит выполнение. И наоборот: при пакетной обработке с прерыванием (например, обработка по 1000 записей) стабильная сортировка обязательна, иначе одни записи обработаются дважды, а другие — ни разу. В таких сценариях добавляйте в конец списка сортировки уникальное поле (ссылку), чтобы порядок был детерминированным.
Как проверить, что сортировка работает правильно
Минимальная проверка — взять первые и последние строки результата и убедиться, что значения поля сортировки идут в ожидаемом направлении. Для сортировки по нескольким полям найдите строки с одинаковым значением первого поля и проверьте порядок внутри группы по второму полю.
Для динамических списков проверяйте два режима: начальный порядок при открытии формы и смену сортировки пользователем. Для отчётов — формирование с настройками по умолчанию и с пользовательской сортировкой. Если в обоих режимах порядок предсказуем, настройка выполнена корректно.
Как проверить результат
Значения поля идут монотонно в заданном направлении
Порядок меняется от запуска к запуску или выглядит случайным
Клик по заголовку колонки меняет порядок
Клик не действует — вероятно, порядок зашит в текст запроса
2 идёт раньше 10
10 идёт раньше 2 — поле строковое, нужно приведение типа
Частые вопросы
Как отсортировать по убыванию в запросе 1С?
Добавьте ключевое слово УБЫВ после имени поля в секции УПОРЯДОЧИТЬ ПО, например: УПОРЯДОЧИТЬ ПО Дата УБЫВ. Для возрастания укажите ВОЗР или не указывайте ничего — возрастание применяется по умолчанию.
Почему сортировка в динамическом списке не реагирует на клик по колонке?
Скорее всего, в тексте запроса динамического списка прописана секция УПОРЯДОЧИТЬ ПО. Она фиксирует порядок и блокирует пользовательскую сортировку. Уберите секцию из запроса и задайте начальный порядок через свойство Порядок списка.
Как отсортировать таблицу значений по нескольким колонкам?
Передайте в метод Сортировать() строку с перечислением колонок и направлений через запятую: ТЗ.Сортировать("Дата Убыв, Сумма Возр"). Сравнение идёт слева направо: сначала по первой колонке, при равенстве — по следующей.
Чем АВТОУПОРЯДОЧИВАНИЕ отличается от УПОРЯДОЧИТЬ ПО?
АВТОУПОРЯДОЧИВАНИЕ включает автоматический порядок: ссылки сортируются по основному представлению (наименованию, дате и номеру документа). Это удобно для быстрого результата, но медленнее и менее предсказуемо, чем явный УПОРЯДОЧИТЬ ПО. В прикладном коде предпочтительнее явное упорядочивание.
Можно ли сортировать по полю, которого нет в выборке?
Да, если поле доступно в источнике запроса. Однако для отладки удобнее включать его в выборку — тогда порядок легко проверить визуально по результату.
Что важно запомнить
Сортировку выполняйте там, где данные появляются: УПОРЯДОЧИТЬ ПО — в запросе, свойство Порядок — в динамическом списке, Сортировать() — в таблице значений, настройки СКД — в отчётах. Не дублируйте жёсткий порядок в запросе там, где пользователь должен менять сортировку сам, и следите за типом поля: строки и ссылки сортируются не так, как ожидает пользователь.