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

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

Как отсортировать массив в 1С: рабочие способы с примерами

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

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

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

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

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

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

Для сравнения смешанных типов не существует однозначного правила: что «больше» — строка «Абонент» или ссылка на элемент справочника? Поэтому разработчики платформы вынесли сортировку в специализированные объекты, где тип данных и критерий сравнения определены явно: СписокЗначений, ТаблицаЗначений, ДеревоЗначений, динамический список.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

КонецЦикла;

Таблица.Сортировать("Цена Возр, Наименование Возр");

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

Если после сортировки нужен снова именно массив структур, пройдите по строкам таблицы циклом и соберите новый массив. Имейте в виду, что типизация колонок таблицы значений влияет на сравнение: если колонка «Цена» объявлена без описания типов и в неё попали строки, сортировка будет строковой, а не числовой — «10» окажется раньше «9».

Собственный алгоритм: пузырьковая сортировка

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

Процедура СортироватьПоДлинеСтроки(Массив)

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

Для ИндексВнешний = 0 По Количество - 2 Цикл

Для ИндексВнутренний = 0 По Количество - 2 - ИндексВнешний Цикл

Если СтрДлина(Массив[ИндексВнутренний]) > СтрДлина(Массив[ИндексВнутренний + 1]) Тогда

Временное = Массив[ИндексВнутренний];

Массив[ИндексВнутренний] = Массив[ИндексВнутренний + 1];

Массив[ИндексВнутренний + 1] = Временное;

КонецЕсли;

КонецЦикла;

КонецЦикла;

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

Обратите внимание на индексацию: массивы в 1С индексируются с нуля, поэтому верхняя граница цикла — Количество - 2, а не Количество - 1. Ошибка в границе приведёт к выходу за пределы массива и исключению «Индекс находится за границами массива».

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

Какой способ выбрать в разных ситуациях

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

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

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

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

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

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

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

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

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

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

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

Для Индекс = 0 По ОтсортированныйМассив.ВГраница() Цикл

Сообщить(Строка(Индекс) + ": " + ОтсортированныйМассив[Индекс]);

КонецЦикла;

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

Типичные ошибки
01
Сортировка чисел как строк: "10" оказывается перед "9", потому что сравнение идёт посимвольно. Приводите значения к числу или типизируйте колонку.
02
Выход за границы массива в ручном алгоритме: цикл до Количество() вместо Количество() - 2 вызывает исключение.
03
Ожидание, что СортироватьПоЗначению() изменит исходный массив: метод сортирует список, результат нужно забрать через ВыгрузитьЗначения().
04
Смешение типов в одном массиве: порядок сравнения разных типов неочевиден и результат выглядит случайным.

Производительность и ограничения

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

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

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

Итог

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

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

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

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

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

Как отсортировать массив ссылок на справочник по наименованию?

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

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

Это признак строковой сортировки: значения хранятся как строки либо колонка таблицы не типизирована и получила строковые данные. Сравнение идёт посимвольно, поэтому «10» меньше «2». Приведите значения функцией Число() или задайте колонке ОписаниеТипов с типом «Число».

Меняет ли СортироватьПоЗначению() исходный массив?

Нет. Метод вызывается у объекта СписокЗначений и упорядочивает только его. Исходный массив остаётся неизменным; чтобы получить отсортированный массив, используйте метод ВыгрузитьЗначения() и присвойте результат переменной.

Что быстрее: сортировка в коде или в запросе?

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

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

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