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

Особенность заключается в том, что здесь нет универсального "лучшего" способа: выбор метода зависит от версии платформы, типа данных и даже от того, нужно ли сохранять исходный порядок элементов. Мы проанализируем плюсы и минусы каждого подхода, покажем реальные примеры кода и дадим рекомендации, когда какой метод применять. Если вы когда-нибудь терялись в документации или не могли выбрать между Сортировать() и ручной сортировкой — эта статья для вас.

⚠️ Внимание: В статье рассматриваются методы для 1С:Предприятие 8.3 и 8.2. Некоторые функции (например, лямбда-выражения) доступны только в последних версиях платформы. Для уточнения поддерживаемых возможностей проверьте версию вашей конфигурации в Справка → О программе.

1. Встроенный метод Сортировать() — проще не бывает

Самый очевидный и распространённый способ упорядочить массив — использовать встроенный метод Сортировать(). Он работает с любыми одномерными массивами и поддерживает как сортировку по возрастанию, так и по убыванию. Главное преимущество метода — лаконичность кода и высокая скорость выполнения для большинства задач.

Пример сортировки массива чисел по возрастанию:

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

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

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

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

МассивЧисел.Сортировать(); // Результат: 1, 5, 9

Для сортировки по убыванию добавьте параметр НаправлениеСортировки.Убывание:

МассивЧисел.Сортировать(НаправлениеСортировки.Убывание); // Результат: 9, 5, 1
  • Плюсы: Минимальный код, высокая скорость, поддерживается всеми версиями платформы.
  • Минусы: Не работает с многомерными массивами. Для сложных объектов (например, структур) требуется дополнительная настройка.
  • 🔹 Особенность: Исходный массив изменяется. Если нужно сохранить оригинал, предварительно создайте копию с помощью МассивЧисел.Скопировать().
📊 Какой тип сортировки вы используете чаще?
По возрастанию
По убыванию
Сложные критерии (по нескольким полям)
Не сортирую массивы

2. Сортировка структур и объектов по ключу

Когда массив состоит из структур или объектов (например, справочников), простого Сортировать() недостаточно. Здесь нужно указать, по какому именно свойству выполнять упорядочивание. Для этого используется метод СортироватьПоКлючу() или лямбда-выражения (в 1С 8.3.10+).

Пример сортировки массива структур по полю "Цена":

МассивТоваров = Новый Массив;

МассивТоваров.Добавить(Новый Структура("Наименование,Цена", "Товар1", 150));

МассивТоваров.Добавить(Новый Структура("Наименование,Цена", "Товар2", 100));

МассивТоваров.Добавить(Новый Структура("Наименование,Цена", "Товар3", 200));

// Сортировка по возрастанию цены

МассивТоваров.Сортировать(Функция(Элемент1, Элемент2)

Возврат Элемент1.Цена > Элемент2.Цена;

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

Для сортировки по нескольким полям (например, сначала по цене, затем по наименованию) используйте цепочку условий:

МассивТоваров.Сортировать(Функция(Элемент1, Элемент2)

Если Элемент1.Цена = Элемент2.Цена Тогда

Возврат Элемент1.Наименование > Элемент2.Наименование;

Иначе

Возврат Элемент1.Цена > Элемент2.Цена;

КонецЕсли;

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

💡

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

3. Ручная сортировка: когда встроенных методов недостаточно

В некоторых случаях стандартные методы не подходят:

  • 🔄 Нужна стабильная сортировка (сохранение порядка равных элементов).
  • 📊 Требуется нестандартный алгоритм (например, сортировка по пользовательской функции).
  • 🖥️ Работа с устаревшими версиями , где нет лямбда-выражений.

В таких ситуациях приходится реализовывать сортировку вручную.

Самый популярный алгоритм для ручной сортировки — "пузырёк" (Bubble Sort). Он прост в реализации, но подходит только для небольших массивов:

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

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

Для i = 0 По n - 1 Цикл

Для j = 0 По n - i - 2 Цикл

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

Буфер = Массив[j];

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

Массив[j + 1] = Буфер;

КонецЕсли;

КонецЦикла;

КонецЦикла;

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

Для больших массивов лучше использовать "быструю сортировку" (QuickSort), но её реализация сложнее. Готовые процедуры можно найти в базе знаний ИТС или на форумах разработчиков.

Когда стоит избегать ручной сортировки?

Ручные алгоритмы целесообразны только в крайних случаях. Они проигрывают встроенным методам по скорости в 10–100 раз. Например, сортировка пузырьком массива из 10 000 элементов может занять несколько секунд, тогда как Сортировать() справится за миллисекунды. Используйте ручные методы только если:

1. Нужна совместимость со старыми версиями (до 8.2).

2. Требуется нестандартная логика, которую нельзя выразить через лямбда-выражения.

3. Вы работаете с экзотическими структурами данных (например, связными списками).

4. Сортировка с использованием запросов 1С

Если массив данных хранится в базе (например, это выборка документов или справочников), эффективнее сортировать его непосредственно в запросе . Это снижает нагрузку на сервер и ускоряет обработку.

Пример запроса с сортировкой по дате и сумме:

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

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

"ВЫБРАТЬ

| Документ.Ссылка КАК Ссылка,

| Документ.Дата КАК Дата,

| Документ.СуммаДокумента КАК Сумма

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Документ

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

| Дата УБЫВ,

| Сумма УБЫВ";

Результат = Запрос.Выполнить().Выгрузить();

Преимущества этого подхода:

  • Производительность: Сортировка выполняется на стороне СУБД, что в разы быстрее, чем обработка на клиенте.
  • 🔧 Гибкость: Можно сортировать по нескольким полям, использовать агрегатные функции (ГРУППИРОВКА, ИТОГИ).
  • 📌 Актуальность: Данные сортируются в момент выборки, что гарантирует их свежесть.

⚠️ Внимание: Если после выполнения запроса вы модифицируете полученный массив (например, добавляете вычисляемые поля), сортировка может сбиться. В таких случаях сначала обработайте данные, а затем сортируйте.

5. Оптимизация сортировки больших массивов

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

  1. Разделение массива. Разбейте большой массив на части, отсортируйте каждую отдельно, затем объедините (алгоритм "разделяй и властвуй").
  2. Индексирование. Если массив часто сортируется по одному и тому же полю, создайте индексированную коллекцию (например, Структура или Соответствие).
  3. Кэширование. Сохраняйте отсортированные данные в временное хранилище (например, ХранилищеЗначения), если они используются многократно.

Пример оптимизированной сортировки с разделением:

Процедура БыстраяСортировка(Массив, Начало, Конец)

Если Начало >= Конец Тогда

Возврат;

КонецЕсли;

Опорный = Массив[Конец];

i = Начало;

Для j = Начало По Конец - 1 Цикл

Если Массив[j] <= Опорный Тогда

Буфер = Массив[i];

Массив[i] = Массив[j];

Массив[j] = Буфер;

i = i + 1;

КонецЕсли;

КонецЦикла;

Буфер = Массив[i];

Массив[i] = Массив[Конец];

Массив[Конец] = Буфер;

БыстраяСортировка(Массив, Начало, i - 1);

БыстраяСортировка(Массив, i + 1, Конец);

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

// Использование:

БыстраяСортировка(МассивЧисел, 0, МассивЧисел.Количество() - 1);

Метод сортировки Скорость (10 000 элементов) Память Когда использовать
Сортировать() ~10 мс Низкая Простые массивы, стандартные задачи
Лямбда-выражение ~15 мс Низкая Сложные критерии, структуры
Запрос 1С ~5 мс Средняя Данные из базы, большие выборки
Быстрая сортировка (QuickSort) ~8 мс Высокая Очень большие массивы, ручная оптимизация
Пузырёк (Bubble Sort) ~2000 мс Низкая Учебные задачи, массивы < 100 элементов

6. Сортировка многомерных массивов

Стандартный метод Сортировать() не работает с многомерными массивами. Чтобы отсортировать, например, двумерный массив (таблицу), нужно:

  1. Выбрать столбец, по которому будет выполняться сортировка.
  2. Реализовать алгоритм, который переставляет строки целиком.

Пример сортировки двумерного массива по первому столбцу:

Массив2D = Новый Массив;

Массив2D.Добавить(Новый Массив(3, "Товар3"));

Массив2D.Добавить(Новый Массив(1, "Товар1"));

Массив2D.Добавить(Новый Массив(2, "Товар2"));

// Сортировка по первому элементу (числу) в каждой строке

Массив2D.Сортировать(Функция(Строка1, Строка2)

Возврат Строка1[0] > Строка2[0];

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

Для сортировки по нескольким столбцам используйте цепочку условий, как в примере с структурами.

Убедитесь, что все строки имеют одинаковую длину|Проверьте типы данных в сортируемом столбце (числа/строки)|Сохраните резервную копию массива|Тестируйте сортировку на небольшом фрагменте данных-->

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

Даже опытные разработчики иногда допускают ошибки при сортировке массивов в . Вот самые распространённые:

  • 🚫 Сортировка несуществующего массива. Всегда проверяйте, что массив инициализирован: Если Массив = Неопределено Тогда ...
  • 🔢 Сравнение разных типов. При сортировке чисел и строк одновременно (5 и "10") результат будет некорректным. Приводите данные к одному типу.
  • 🔄 Изменение массива во время сортировки. Не добавляйте или удаляйте элементы в процессе — это приведёт к ошибке.
  • 📉 Игнорирование регистра. При сортировке строк "А" и "а" могут располагаться не так, как вы ожидаете. Используйте Строка1.Сравнить(Строка2, Ложь) для регистронезависимого сравнения.

Критическая ошибка: При сортировке массива ссылок на объекты (например, элементы справочника) никогда не сравнивайте ссылки напрямую через = или >. Вместо этого используйте уникальные идентификаторы (Ссылка.УникальныйИдентификатор()), иначе сортировка будет неустойчивой.

💡

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

8. Альтернативные подходы: когда сортировка не нужна

Иногда задачу можно решить без сортировки, что ускорит выполнение кода:

  • 🔍 Поиск без сортировки. Если нужно найти максимальное/минимальное значение, используйте Массив.Максимум() или Массив.Минимум().
  • 📋 Группировка. Для анализа данных вместо сортировки применяйте Группировка в запросах или Соответствие.
  • 🔄 Отложенная сортировка. Если массив выводится пользователю (например, в таблицу на форме), сортируйте его только при необходимости (по требованию).

Пример поиска максимального элемента без сортировки:

МаксимальноеЗначение = МассивЧисел.Максимум(); // Быстрее, чем сортировка + взятие последнего элемента

⚠️ Внимание: В 1С:Предприятие 8.3.14+ появились новые методы для работы с массивами (Найти(), ВзятьЭлементы()), которые могут заменить сортировку в некоторых сценариях. Проверьте их наличие в вашей версии платформы.

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

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

Используйте лямбда-выражение с цепочкой условий. Например, для сортировки массива структур сначала по Цена, затем по Наименование:

Массив.Сортировать(Функция(Эл1, Эл2)

Если Эл1.Цена = Эл2.Цена Тогда

Возврат Эл1.Наименование > Эл2.Наименование;

Иначе

Возврат Эл1.Цена > Эл2.Цена;

КонецЕсли;

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

Почему после сортировки массива объектов 1С появляются ошибки?

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

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

Элемент.Прочитать(); // Явная подгрузка данных

КонецЦикла;

Также проверьте, что сравниваемые поля не содержат NULL.

Как отсортировать массив дат?

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

МассивДат.Сортировать(НаправлениеСортировки.Убывание);

Если даты хранятся в виде строк, сначала преобразуйте их в тип Дата.

Можно ли сортировать массив без изменения оригинала?

Да. Сначала создайте копию массива:

МассивКопия = МассивИсходный.Скопировать();

МассивКопия.Сортировать();

Или используйте конструктор Новый Массив(МассивИсходный).

Как ускорить сортировку массива из 100 000 элементов?

Для таких объёмов:

  1. Используйте запрос (если данные из базы).
  2. Применяйте алгоритм QuickSort (см. пример в разделе 5).
  3. Разбейте массив на части, отсортируйте их параллельно (в отдельных потоках, если поддерживается).

Избегайте BubbleSort — он будет работать часами.