Разработка и Конфигурация · 9 мин
Как упорядочить массив в 1С
Способы упорядочить массив в 1С: пузырьковая сортировка, сортировка через СписокЗначений и ТаблицуЗначений. Примеры кода, сравнение методов, типичные ошибки.
Встроенный язык 1С не содержит метода Массив.Сортировать(), поэтому вопрос упорядочивания массива решается обходными путями. Разработчику доступны три рабочих подхода: собственный алгоритм сортировки (пузырьком, вставками), перенос данных в СписокЗначений с последующей сортировкой, либо использование ТаблицаЗначений и её методов Сортировать(). Выбор зависит от типа элементов, объёма данных и требований к производительности.
Важно понимать ограничения каждого способа. СписокЗначений хранит элементы с представлением и умеет сортировать их встроенным методом, но принимает не все типы. ТаблицаЗначений сортирует быстро и поддерживает несколько колонок, однако требует дополнительного кода на перенос данных. Собственный алгоритм универсален, но медленнее на больших массивах и легче даёт ошибки в реализации.
Ниже разобраны все три способа с готовым кодом, сравнение их применимости, проверка результата и типичные ошибки, которые приводят к неверному порядку элементов или падению производительности.
Почему в 1С нет прямой сортировки массива
Объект Массив во встроенном языке 1С — это базовая коллекция с минимальным набором методов: Добавить(), Вставить(), Удалить(), Найти(), Количество() и несколько других. Методов сортировки и реверса в нём нет. Это осознанное решение платформы: для упорядочивания предполагается использовать специализированные коллекции — СписокЗначений, ТаблицаЗначений, а для запросов к базе данных — конструкцию УПОРЯДОЧИТЬ ПО в языке запросов.
Из этого следует практический вывод: если данные ещё не собраны в массив, часто правильнее сразу выбрать подходящую коллекцию. Например, если элементы берутся из запроса, упорядочить их лучше на стороне СУБД через УПОРЯДОЧИТЬ ПО — это быстрее любой сортировки в коде. Массив же стоит сортировать только тогда, когда он формируется программно и источник упорядочить нельзя.
Способ 1. Сортировка через СписокЗначений
Самый компактный способ упорядочить массив простых типов (числа, строки, даты, ссылки) — перенести элементы в СписокЗначений, отсортировать его и выгрузить обратно в массив методом ВыгрузитьЗначения().
Функция СортироватьМассив(Массив)
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(Массив);
Список.СортироватьПоЗначению(НаправлениеСортировки.Возр);
Возврат Список.ВыгрузитьЗначения();
КонецФункции
Метод СортироватьПоЗначению() принимает направление: НаправлениеСортировки.Возр или НаправлениеСортировки.Убыв. Для убывающего порядка менять логику не нужно — достаточно другого параметра.
Ограничение способа — в допустимых типах СписокЗначений. В него можно поместить значения примитивных типов, ссылки на объекты базы и некоторые другие типы, но не произвольные структуры или таблицы. Если массив содержит, например, структуры, этот способ не подойдёт.
Способ 2. Сортировка через ТаблицуЗначений
Когда элементы массива — сложные объекты или требуется сортировка по нескольким признакам, используют ТаблицаЗначений. Элементы выгружаются в колонку, таблица сортируется встроенным методом, затем данные возвращаются в массив.
Функция СортироватьМассивТаблицей(Массив)
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Значение");
Для Каждого Элемент Из Массив Цикл
ТЗ.Добавить().Значение = Элемент;
КонецЦикла;
ТЗ.Сортировать("Значение Возр");
Возврат ТЗ.ВыгрузитьКолонку("Значение");
КонецФункции
Преимущество подхода — гибкость. Метод Сортировать() принимает строку с несколькими колонками и направлениями: ТЗ.Сортировать("Дата Возр, Сумма Убыв"). Если массив состоит из структур, можно развернуть поля структуры в колонки таблицы и сортировать по любой комбинации.
Недостаток — больший объём кода и накладные расходы на создание таблицы. Для массива из десяти чисел это избыточно, для массива структур с тысячами элементов — оправданно.
Способ 3. Собственный алгоритм сортировки
Если по каким-то причинам вспомогательные коллекции использовать нельзя (например, требуется нестандартное правило сравнения), сортировку пишут вручную. Классический вариант — пузырьковая сортировка:
Процедура СортироватьПузырьком(Массив)
Н = Массив.Количество();
Для И = 0 По Н - 2 Цикл
Для Ж = 0 По Н - 2 - И Цикл
Если Массив[Ж] > Массив[Ж + 1] Тогда
Врем = Массив[Ж];
Массив[Ж] = Массив[Ж + 1];
Массив[Ж + 1] = Врем;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Пузырьковая сортировка имеет квадратичную сложность: на массиве из нескольких тысяч элементов она уже заметно тормозит. Для больших объёмов лучше перенести данные в ТаблицуЗначений — её сортировка реализована на уровне платформы и работает значительно быстрее интерпретируемого цикла.
Собственный алгоритм оправдан, когда правило сравнения нестандартное: например, сначала чётные числа по возрастанию, затем нечётные. В этом случае условие внутри цикла заменяется на вызов функции сравнения.
Сравнение способов и выбор подходящего
Сравнение способов сортировки
Самый короткий код. Подходит для чисел, строк, дат, ссылок. Не принимает структуры и произвольные объекты.
Универсально и быстро, поддерживает сортировку по нескольким полям. Требует больше кода на перенос данных.
Полный контроль над правилом сравнения. Медленно на больших массивах, легко допустить ошибку в индексах.
Лучший вариант, если данные берутся из базы. Сортировка на стороне СУБД быстрее любой сортировки в коде.
Правило выбора простое. Данные из базы — сортируйте запросом. Простые типы, собранные программно, — СписокЗначений. Структуры, несколько критериев, большие объёмы — ТаблицаЗначений. Нестандартное правило сравнения и маленький массив — собственный алгоритм.
Проверка результата и типичные ошибки
После сортировки полезно пройти по массиву и убедиться, что каждый следующий элемент не меньше предыдущего (при возрастающем порядке). Это особенно актуально при собственном алгоритме, где ошибка в границах цикла встречается чаще всего.
Как проверить результат
Каждый следующий элемент не меньше предыдущего (при Возр)
Есть пары, где следующий меньше предыдущего
Совпадает с исходным массивом
Элементы потеряны или продублированы
Все элементы одного сравнимого типа
Смешаны строки и числа
Сортировка тысяч элементов занимает доли секунды
Заметная пауза — вероятно, ручной алгоритм на большом массиве
Практические рекомендации
Выносите сортировку в отдельную функцию общего модуля, если она нужна в нескольких местах конфигурации. Функция на основе СписокЗначений занимает четыре строки и легко тестируется. Для клиент-серверного приложения располагайте такие функции в серверном модуле, если массив формируется на сервере, — это избавит от лишних вызовов.
Если массив используется только для поиска и проверки вхождения, задумайтесь, нужна ли сортировка вообще: для этих задач лучше подходит Соответствие, где поиск выполняется быстро независимо от порядка. Сортировка оправдана, когда порядок важен для вывода пользователю, нумерации или последовательной обработки.
Что важно запомнить
Метода сортировки у массива в 1С нет. Для простых типов используйте СписокЗначений, для сложных данных и нескольких критериев — ТаблицаЗначений, для данных из базы — УПОРЯДОЧИТЬ ПО в запросе. Собственный алгоритм оставьте для нестандартных правил сравнения и маленьких массивов.
Частые вопросы
Можно ли отсортировать массив по убыванию?
Да. В СписокЗначений передайте в СортироватьПоЗначению() параметр НаправлениеСортировки.Убыв, в ТаблицеЗначений укажите в строке сортировки «Убыв» после имени колонки. Для собственного алгоритма поменяйте знак сравнения на противоположный.
Как отсортировать массив структур по одному из полей?
Напрямую — никак. Создайте ТаблицуЗначений с колонками под нужные поля структуры, перенесите данные, отсортируйте методом Сортировать() и пройдите по таблице, собирая итоговый массив. Либо напишите собственный алгоритм, где сравниваются значения полей структур.
Почему числа сортируются как 1, 10, 2, 25?
Значения хранятся как строки, а строки сравниваются посимвольно. Перед сортировкой преобразуйте элементы в числа через Число() или обеспечьте правильный тип при заполнении массива.
Что быстрее: СписокЗначений или ТаблицаЗначений?
Оба метода сортировки реализованы на уровне платформы и работают быстро. Разница — в накладных расходах на перенос данных: СписокЗначений компактнее для простых типов, ТаблицаЗначений выигрывает при сортировке по нескольким полям. На практике выбирайте по удобству кода, а не по скорости.
Можно ли упорядочить массив ссылок по наименованию?
Да. СписокЗначений сортирует ссылки по их представлению, что для большинства объектов совпадает с наименованием. Если нужен строгий порядок по реквизиту, надёжнее выполнить запрос с УПОРЯДОЧИТЬ ПО Наименование и выгрузить результат.
Как отсортировать массив в обратном порядке без повторной сортировки?
Пройдите по массиву с конца к началу и соберите новый массив: индексы от Количество()-1 до 0 с шагом -1. Это проще, чем менять логику сортировки, если обратный порядок нужен разово.