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

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

Как упорядочить массив в 1С

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

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

Важно понимать ограничения каждого способа. СписокЗначений хранит элементы с представлением и умеет сортировать их встроенным методом, но принимает не все типы. ТаблицаЗначений сортирует быстро и поддерживает несколько колонок, однако требует дополнительного кода на перенос данных. Собственный алгоритм универсален, но медленнее на больших массивах и легче даёт ошибки в реализации.

Ниже разобраны все три способа с готовым кодом, сравнение их применимости, проверка результата и типичные ошибки, которые приводят к неверному порядку элементов или падению производительности.

Почему в 1С нет прямой сортировки массива

Объект Массив во встроенном языке 1С — это базовая коллекция с минимальным набором методов: Добавить(), Вставить(), Удалить(), Найти(), Количество() и несколько других. Методов сортировки и реверса в нём нет. Это осознанное решение платформы: для упорядочивания предполагается использовать специализированные коллекции — СписокЗначений, ТаблицаЗначений, а для запросов к базе данных — конструкцию УПОРЯДОЧИТЬ ПО в языке запросов.

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

Способ 1. Сортировка через СписокЗначений

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

Функция СортироватьМассив(Массив)

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

Список.ЗагрузитьЗначения(Массив);

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

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

КонецФункции

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

Ограничение способа — в допустимых типах СписокЗначений. В него можно поместить значения примитивных типов, ссылки на объекты базы и некоторые другие типы, но не произвольные структуры или таблицы. Если массив содержит, например, структуры, этот способ не подойдёт.

Способ 2. Сортировка через ТаблицуЗначений

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

Функция СортироватьМассивТаблицей(Массив)

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

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

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

ТЗ.Добавить().Значение = Элемент;

КонецЦикла;

ТЗ.Сортировать("Значение Возр");

Возврат ТЗ.ВыгрузитьКолонку("Значение");

КонецФункции

Преимущество подхода — гибкость. Метод Сортировать() принимает строку с несколькими колонками и направлениями: ТЗ.Сортировать("Дата Возр, Сумма Убыв"). Если массив состоит из структур, можно развернуть поля структуры в колонки таблицы и сортировать по любой комбинации.

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

Способ 3. Собственный алгоритм сортировки

Если по каким-то причинам вспомогательные коллекции использовать нельзя (например, требуется нестандартное правило сравнения), сортировку пишут вручную. Классический вариант — пузырьковая сортировка:

Процедура СортироватьПузырьком(Массив)

Н = Массив.Количество();

Для И = 0 По Н - 2 Цикл

Для Ж = 0 По Н - 2 - И Цикл

Если Массив[Ж] > Массив[Ж + 1] Тогда

Врем = Массив[Ж];

Массив[Ж] = Массив[Ж + 1];

Массив[Ж + 1] = Врем;

КонецЕсли;

КонецЦикла;

КонецЦикла;

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

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

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

Сравнение способов и выбор подходящего

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

СписокЗначений

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

ТаблицаЗначений

Универсально и быстро, поддерживает сортировку по нескольким полям. Требует больше кода на перенос данных.

Свой алгоритм

Полный контроль над правилом сравнения. Медленно на больших массивах, легко допустить ошибку в индексах.

УПОРЯДОЧИТЬ ПО в запросе

Лучший вариант, если данные берутся из базы. Сортировка на стороне СУБД быстрее любой сортировки в коде.

Правило выбора простое. Данные из базы — сортируйте запросом. Простые типы, собранные программно, — СписокЗначений. Структуры, несколько критериев, большие объёмы — ТаблицаЗначений. Нестандартное правило сравнения и маленький массив — собственный алгоритм.

Проверка результата и типичные ошибки

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

Типичные ошибки
01
Сортировка чисел как строк: «10» оказывается раньше «2». Решение — привести значения к типу Число перед сортировкой.
02
Выход за границы массива в пузырьковой сортировке из-за неверной верхней границы цикла. Помните: индексация массива начинается с 0, последний индекс — Количество()-1.
03
Смешение типов в одном массиве: сравнение строки с числом даёт непредсказуемый порядок или ошибку. Держите типы однородными.
04
Попытка отсортировать массив структур через СписокЗначений — структуры нельзя добавить в список, возникнет ошибка.
05
Игнорирование направления сортировки: для убывания нужен явный параметр НаправлениеСортировки.Убыв.
Контрольные точки

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

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

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

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

Есть пары, где следующий меньше предыдущего

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

Совпадает с исходным массивом

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

Элементы потеряны или продублированы

Типы значений
Норма

Все элементы одного сравнимого типа

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

Смешаны строки и числа

Время выполнения
Норма

Сортировка тысяч элементов занимает доли секунды

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

Заметная пауза — вероятно, ручной алгоритм на большом массиве

Практические рекомендации

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

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

Итог

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

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

Частые вопросы

Можно ли отсортировать массив по убыванию?

Да. В СписокЗначений передайте в СортироватьПоЗначению() параметр НаправлениеСортировки.Убыв, в ТаблицеЗначений укажите в строке сортировки «Убыв» после имени колонки. Для собственного алгоритма поменяйте знак сравнения на противоположный.

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

Напрямую — никак. Создайте ТаблицуЗначений с колонками под нужные поля структуры, перенесите данные, отсортируйте методом Сортировать() и пройдите по таблице, собирая итоговый массив. Либо напишите собственный алгоритм, где сравниваются значения полей структур.

Почему числа сортируются как 1, 10, 2, 25?

Значения хранятся как строки, а строки сравниваются посимвольно. Перед сортировкой преобразуйте элементы в числа через Число() или обеспечьте правильный тип при заполнении массива.

Что быстрее: СписокЗначений или ТаблицаЗначений?

Оба метода сортировки реализованы на уровне платформы и работают быстро. Разница — в накладных расходах на перенос данных: СписокЗначений компактнее для простых типов, ТаблицаЗначений выигрывает при сортировке по нескольким полям. На практике выбирайте по удобству кода, а не по скорости.

Можно ли упорядочить массив ссылок по наименованию?

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

Как отсортировать массив в обратном порядке без повторной сортировки?

Пройдите по массиву с конца к началу и соберите новый массив: индексы от Количество()-1 до 0 с шагом -1. Это проще, чем менять логику сортировки, если обратный порядок нужен разово.