К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как отсортировать список значений в 1С

Разбираем способы сортировки списка значений в 1С: метод СортироватьПоЗначению, сортировка по представлению, через таблицу значений и запрос. Примеры кода и типичные ошибки.

Список значений — один из базовых коллекций во встроенном языке 1С, который используется для передачи параметров, хранения отобранных данных и заполнения элементов формы. По умолчанию элементы располагаются в порядке добавления, и рано или поздно возникает задача упорядочить их по значению, представлению или другому признаку.

В языке 1С нет универсального метода «отсортировать как угодно»: у объекта СписокЗначений есть только один штатный метод сортировки — по значению. Все остальные сценарии решаются обходными путями: через промежуточную таблицу значений, запрос или ручной алгоритм. Ниже разобраны все рабочие варианты с примерами кода и указанием ограничений каждого.

Сортировка по значению штатным методом

Единственный встроенный метод сортировки у списка значений — СортироватьПоЗначению(). Он принимает один необязательный параметр — направление сортировки из системного перечисления НаправлениеСортировки: Возр (по возрастанию) или Убыв (по убыванию). Если параметр не указан, применяется сортировка по возрастанию.

// Пример 1. Сортировка списка чисел

Список = Новый СписокЗначений;

Список.Добавить(150);

Список.Добавить(23);

Список.Добавить(78);

Список.СортироватьПоЗначению(НаправлениеСортировки.Возр);

// Результат: 23, 78, 150

Список.СортироватьПоЗначению(НаправлениеСортировки.Убыв);

// Результат: 150, 78, 23

Метод корректно работает со сравнимыми типами: числами, строками, датами, ссылками. Строки сортируются по алфавиту с учётом регистра и правил сравнения, принятых в информационной базе. Даты упорядочиваются по хронологии.

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

Сортировка по представлению через таблицу значений

Штатного метода «СортироватьПоПредставлению» у списка значений нет, хотя представление часто важнее самого значения — например, когда список содержит ссылки на контрагентов, а пользователь должен видеть их по алфавиту наименований. Задача решается через промежуточную таблицу значений.

// Пример 2. Сортировка списка по представлению

Процедура СортироватьСписокПоПредставлению(Список, ПоВозрастанию = Истина)

Таблица = Новый ТаблицаЗначений;

Таблица.Колонки.Добавить("Значение");

Таблица.Колонки.Добавить("Представление");

Таблица.Колонки.Добавить("Пометка");

Для Каждого Элемент Из Список Цикл

Строка = Таблица.Добавить();

Строка.Значение = Элемент.Значение;

Строка.Представление = Элемент.Представление;

Строка.Пометка = Элемент.Пометка;

КонецЦикла;

Направление = ?(ПоВозрастанию, "Возр", "Убыв");

Таблица.Сортировать("Представление " + Направление);

Список.Очистить();

Для Каждого Строка Из Таблица Цикл

Список.Добавить(Строка.Значение, Строка.Представление, Строка.Пометка);

КонецЦикла;

КонецПроцедуры

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

Тот же приём работает и для сортировки по любому производному признаку: длине строки, реквизиту ссылки, результату функции. Достаточно добавить в таблицу вычисляемую колонку и сортировать по ней.

Сортировка списка ссылок по реквизиту через запрос

Когда список содержит ссылки на справочник или документы, а отсортировать нужно по реквизиту (например, контрагентов по коду или документы по дате), самый быстрый и надёжный путь — запрос. Платформа передаст сортировку на сторону СУБД, что особенно важно при больших объёмах.

// Пример 3. Сортировка списка ссылок по наименованию через запрос

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Контрагенты.Ссылка КАК Ссылка

|ИЗ

| Справочник.Контрагенты КАК Контрагенты

|ГДЕ

| Контрагенты.Ссылка В (&СписокСсылок)

|

|УПОРЯДОЧИТЬ ПО

| Контрагенты.Наименование";

Запрос.УстановитьПараметр("СписокСсылок", Список.ВыгрузитьЗначения());

Список.Очистить();

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Список.Добавить(Выборка.Ссылка);

КонецЦикла;

Метод ВыгрузитьЗначения() превращает список в обычный массив, который можно передать параметром в запрос. Условие В (&СписокСсылок) отберёт только нужные ссылки, а конструкция УПОРЯДОЧИТЬ ПО вернёт их в требуемом порядке.

У этого подхода есть побочный эффект, о котором нужно помнить: запрос вернёт только существующие в базе ссылки. Если в списке есть «битые» ссылки на удалённые объекты, они из результата пропадут. В большинстве случаев это даже полезно, но если потеря элементов недопустима — используйте сортировку через таблицу значений.

Сортировка динамического списка на форме

Отдельный случай — динамический список на управляемой форме (список документов, справочника в форме списка). Это не объект СписокЗначений, а самостоятельный механизм с собственной настройкой порядка. Сортировать его перебором элементов нельзя — нужно менять настройку Порядок.

// Пример 4. Программная сортировка динамического списка формы

ПолеПорядка = Список.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));

ПолеПорядка.Поле = Новый ПолеКомпоновкиДанных("Дата");

ПолеПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;

ПолеПорядка.Использование = Истина;

Если динамический список построен на произвольном запросе, альтернатива — добавить конструкцию УПОРЯДОЧИТЬ ПО прямо в текст запроса. Но помните: жёстко заданный порядок в запросе отключает возможность интерактивной сортировки по колонкам для пользователя, если не включён режим динамического считывания с соответствующими настройками.

Для пользовательской сортировки без программирования достаточно щёлкнуть по заголовку колонки таблицы формы или воспользоваться командой «Настроить список» (меню «Ещё»), где порядок задаётся в разделе «Сортировка».

Сравнение способов сортировки

СортироватьПоЗначению()

Самый простой вариант для однотипных значений. Не работает с сортировкой по представлению и произвольным признакам.

Через таблицу значений

Универсальный способ: сортировка по представлению, пометке, вычисляемым полям. Требует ручного переноса данных и сохранения пометок.

Через запрос

Оптимален для списков ссылок и больших объёмов, сортировка на стороне СУБД. Теряются битые ссылки и пометки.

Настройка порядка динамического списка

Единственный правильный путь для списков на формах. Не применим к программным коллекциям.

Типичные ошибки и как их избежать

Первая распространённая ошибка — ожидание, что СортироватьПоЗначению() вернёт новый отсортированный список. Метод меняет текущий объект, и если переменная используется дальше в исходном порядке, логика программы нарушится. Перед сортировкой делайте копию через НовыйСписок = Список.Скопировать().

Вторая ошибка — попытка сортировать смешанный список, где часть значений заполнена ссылками, а часть — строками или не заполнена вообще. Неопределённые значения и NULL ведут себя при сравнении неочевидно. Перед сортировкой пройдите по списку и приведите значения к одному типу или отфильтруйте пустые.

Третья ошибка — потеря пометок и картинок элементов при пересоздании списка через таблицу значений. Метод Добавить() имеет параметры для значения, представления, пометки и картинки — переносите все используемые свойства, иначе интерфейсная логика (отмеченные пользователем элементы) сломается.

Типичные ошибки
01
Сортировка исходного списка без копии — теряется исходный порядок элементов, нужный дальше по алгоритму.
02
Перенос только значений без пометок — сбрасываются флажки, установленные пользователем.
03
Сортировка списка со смешанными типами — непредсказуемый порядок или ошибка сравнения.
04
Попытка отсортировать динамический список перебором — он не является объектом СписокЗначений, нужна настройка порядка компоновки.

Как проверить результат сортировки

Самый простой способ убедиться, что сортировка отработала, — вывести содержимое списка в цикле через Сообщить() или в окно служебных сообщений и визуально проверить порядок. Для отладки удобно использовать табло (окно «Вычислить выражение»): в нём можно развернуть список и посмотреть значения и представления каждого элемента.

Для автоматической проверки в тестах или отладочных процедурах сравните соседние элементы в цикле: если текущий элемент меньше предыдущего при сортировке по возрастанию — порядок нарушен. Также проверьте, что количество элементов до и после сортировки совпадает, а пометки сохранились у тех же значений.

Контрольные точки

Как проверить результат

Количество элементов
Норма

Совпадает с количеством до сортировки

Тревожный признак

Элементы пропали — вероятно, запрос отфильтровал битые ссылки

Порядок значений
Норма

Каждый следующий элемент больше или равен предыдущему (при сортировке по возрастанию)

Тревожный признак

Порядок хаотичный — в списке смешаны несравнимые типы

Пометки элементов
Норма

Флажки остались у тех же значений

Тревожный признак

Все пометки сброшены — при переносе не копировалось свойство Пометка

Часто задаваемые вопросы

Можно ли отсортировать список значений по убыванию?

Да, метод СортироватьПоЗначению принимает параметр направления: Список.СортироватьПоЗначению(НаправлениеСортировки.Убыв). По умолчанию, если параметр не указан, выполняется сортировка по возрастанию.

Почему СортироватьПоЗначению выдаёт ошибку или странный порядок?

Чаще всего причина в смешанных типах значений: например, в одном списке оказались числа и ссылки, или присутствуют незаполненные элементы со значением Неопределено. Приведите все значения к одному типу или отфильтруйте пустые перед сортировкой.

Как отсортировать список по представлению, если штатного метода нет?

Выгрузите элементы в таблицу значений с колонками «Значение», «Представление» и «Пометка», вызовите у таблицы метод Сортировать("Представление Возр"), затем очистите исходный список и заполните его заново из отсортированной таблицы, не забыв перенести пометки.

Что быстрее — сортировка через таблицу значений или через запрос?

Для списков из ссылок и больших объёмов быстрее запрос, так как сортировка выполняется на стороне СУБД. Для небольших списков примитивных значений разница незаметна, и проще использовать штатный метод или таблицу значений.

Как отсортировать список документов на форме по дате?

Если это динамический список, добавьте элемент порядка в настройку Список.Порядок с полем «Дата» и нужным направлением, либо включите УПОРЯДОЧИТЬ ПО в запрос списка. Пользователь может сделать то же самое интерактивно через «Настроить список» в меню «Ещё».

Сохраняются ли пометки при сортировке штатным методом?

Да, СортироватьПоЗначению перемещает элементы целиком вместе с представлениями, пометками и картинками. Пометки теряются только при ручном пересоздании списка, если разработчик не перенёс это свойство.

Итог

Что важно запомнить

По значению список сортируется методом СортироватьПоЗначению с указанием направления. По представлению и произвольным признакам — через таблицу значений с обязательным переносом пометок. Для списков ссылок эффективнее запрос, а динамический список формы сортируется настройкой порядка, а не перебором элементов.