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

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

Как отсортировать элементы массива в 1С

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

Массив в 1С — одна из самых используемых коллекций, но у разработчиков регулярно возникает вопрос: как упорядочить его элементы. Встроенного метода сортировки у объекта «Массив» долгое время не было, поэтому программисты применяли обходные пути — перекладывали данные в таблицу значений или список значений. Начиная с современных версий платформы 1С:Предприятие 8.3 у массива появился собственный метод Сортировать(), который закрывает большинство задач.

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

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

Штатный метод Сортировать() у массива

В актуальных версиях платформы 1С:Предприятие 8.3 у объекта «Массив» есть метод Сортировать(). Он упорядочивает элементы по возрастанию прямо в исходном массиве — новый объект не создаётся, изменяется текущий. Это важно учитывать: если исходный порядок где-то ещё нужен, сначала сделайте копию массива.

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

МассивЧисел = Новый Массив;

МассивЧисел.Добавить(42);

МассивЧисел.Добавить(7);

МассивЧисел.Добавить(15);

МассивЧисел.Сортировать();

// Результат: 7, 15, 42

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

Сортировка по убыванию и нестандартному порядку

Штатный метод сортирует только по возрастанию. Если нужен обратный порядок, самое простое решение — отсортировать массив, а затем развернуть его. Встроенного метода «развернуть» у массива нет, поэтому используют цикл с обменом элементов или перекладывание в новый массив с конца.

МассивЧисел.Сортировать();

// Разворот для порядка по убыванию

КоличествоЭлементов = МассивЧисел.Количество();

МассивПоУбыванию = Новый Массив;

Для Индекс = 1 По КоличествоЭлементов Цикл

МассивПоУбыванию.Добавить(МассивЧисел[КоличествоЭлементов - Индекс]);

КонецЦикла;

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

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

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

Порядок действий со списком значений
  1. 1
    Создайте объект СписокЗначений и перенесите в него элементы массива циклом
  2. 2
    Вызовите Список.СортироватьПоЗначению(НаправлениеСортировки.Убыв) или без параметра для возрастания
  3. 3
    Очистите исходный массив и заполните его заново значениями из отсортированного списка
  4. 4
    Проверьте результат, выведя элементы в сообщение или журнал
Список = Новый СписокЗначений;

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

Список.Добавить(Элемент);

КонецЦикла;

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

ИсходныйМассив.Очистить();

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

ИсходныйМассив.Добавить(ЭлементСписка.Значение);

КонецЦикла;

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

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

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

// Массив структур: Товар, Сумма

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

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

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

Для Каждого СтруктураДанных Из МассивСтруктур Цикл

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

ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураДанных);

КонецЦикла;

Таблица.Сортировать("Сумма Убыв, Товар Возр");

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

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

Массив.Сортировать()

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

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

Работает в любых версиях, поддерживает направление сортировки и сортировку по представлению. Требует двойного перекладывания данных.

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

Единственный удобный способ для массивов структур и сортировки по нескольким полям. Самый ресурсоёмкий вариант.

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

Полный контроль над логикой сравнения. Оправдан только при нестандартных правилах, иначе избыточен.

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

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

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

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

Для Индекс1 = 0 По КоличествоЭлементов - 2 Цикл

Для Индекс2 = Индекс1 + 1 По КоличествоЭлементов - 1 Цикл

Если Массив[Индекс1] > Массив[Индекс2] Тогда

Временный = Массив[Индекс1];

Массив[Индекс1] = Массив[Индекс2];

Массив[Индекс2] = Временный;

КонецЕсли;

КонецЦикла;

КонецЦикла;

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

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

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

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

Типичные ошибки
01
Сортировка массива со смешанными типами (числа и строки вместе) — метод Сортировать() завершится ошибкой сравнения
02
Ожидание, что Сортировать() вернёт новый массив — метод меняет исходный, и прежний порядок теряется
03
Сортировка ссылок на объекты напрямую — ссылки сравниваются по внутреннему представлению, а не по наименованию, порядок выглядит случайным
04
Потеря данных при перекладывании через список значений, если забыть перенести все элементы обратно в массив
05
Сортировка строк с числами как текст: строка «10» окажется раньше строки «2» — приводите значения к числу перед сравнением

Отдельная ловушка — сортировка строк, содержащих числа. Алфавитный порядок расположит «10» перед «2», потому что сравниваются символы, а не значения. Если порядок должен быть числовым, преобразуйте строки в числа до сортировки либо дополните строки ведущими нулями до одинаковой длины.

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

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

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

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

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

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

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

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

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

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

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

Типы данных
Норма

Все элементы сохранили исходный тип

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

Числа превратились в строки после промежуточной коллекции

Частые вопросы о сортировке массивов в 1С

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

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

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

Напрямую — никак, массив не умеет сравнивать структуры. Перенесите данные в таблицу значений с соответствующими колонками, вызовите Таблица.Сортировать("ИмяПоля Возр") и при необходимости соберите массив обратно в новом порядке.

Почему сортировка ссылок даёт странный порядок?

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

Что делать, если в массиве смешанные типы данных?

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

Какой способ быстрее для большого массива чисел?

Штатный Массив.Сортировать() — он выполняется на уровне платформы без перекладывания данных. Способы через список и таблицу значений медленнее из-за двойного копирования, а собственный пузырьковый алгоритм на больших объёмах проигрывает им всем.

Итог

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

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