Примеры кастомной сортировки значений

Примеры кастомной сортировки значений на языке программирования 1С:Предприятие. Примеры позволяют быстро разобраться в вопросе и использовать код в своих разработках

Сортировка массива чисел по возрастанию и убыванию

// Базовая сортировка массива чисел стандартными методами
Процедура СортировкаЧисел()

    МассивЧисел = Новый Массив;
    МассивЧисел.Добавить(5);
    МассивЧисел.Добавить(2);
    МассивЧисел.Добавить(8);
    МассивЧисел.Добавить(1);
    МассивЧисел.Добавить(9);
    МассивЧисел.Добавить(3);
    
    Сообщить("Исходный массив: " + Строка(МассивЧисел));
    
    // Сортировка по возрастанию
    МассивЧисел.Сортировать(НаправлениеСортировки.Возр);
    Сообщить("По возрастанию: " + Строка(МассивЧисел));
    
    // Сортировка по убыванию
    МассивЧисел.Сортировать(НаправлениеСортировки.Убыв);
    Сообщить("По убыванию: " + Строка(МассивЧисел));
    
КонецПроцедуры

Сортировка таблицы значений по одной колонке

// Сортировка таблицы значений по указанному полю
Процедура СортировкаТаблицыПоКолонке()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Наименование");
    Таблица.Колонки.Добавить("Количество");
    Таблица.Колонки.Добавить("Сумма");
    
    Таблица.Добавить().Наименование = "Ноутбук"; Таблица[0].Количество = 5; Таблица[0].Сумма = 250000;
    Таблица.Добавить().Наименование = "Монитор"; Таблица[1].Количество = 10; Таблица[1].Сумма = 150000;
    Таблица.Добавить().Наименование = "Клавиатура"; Таблица[2].Количество = 3; Таблица[2].Сумма = 6000;
    Таблица.Добавить().Наименование = "Мышь"; Таблица[3].Количество = 7; Таблица[3].Сумма = 3500;
    
    // Сортировка по наименованию (по возрастанию)
    Таблица.Сортировать("Наименование");
    Сообщить("Сортировка по наименованию:");
    Для Каждого Строка Из Таблица Цикл
        Сообщить(Строка.Наименование + " | " + Строка.Количество + " | " + Строка.Сумма);
    КонецЦикла;
    
    // Сортировка по количеству (по убыванию)
    Таблица.Сортировать("Количество УБЫВ");
    Сообщить("Сортировка по количеству (убывание):");
    Для Каждого Строка Из Таблица Цикл
        Сообщить(Строка.Наименование + " | " + Строка.Количество + " | " + Строка.Сумма);
    КонецЦикла;
    
КонецПроцедуры

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

// Многоуровневая сортировка таблицы значений
Процедура МногоуровневаяСортировка()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Категория");
    Таблица.Колонки.Добавить("Товар");
    Таблица.Колонки.Добавить("Цена");
    
    Таблица.Добавить().Категория = "Электроника"; Таблица[0].Товар = "Телефон"; Таблица[0].Цена = 30000;
    Таблица.Добавить().Категория = "Электроника"; Таблица[1].Товар = "Ноутбук"; Таблица[1].Цена = 50000;
    Таблица.Добавить().Категория = "Мебель"; Таблица[2].Товар = "Стул"; Таблица[2].Цена = 3000;
    Таблица.Добавить().Категория = "Электроника"; Таблица[3].Товар = "Планшет"; Таблица[3].Цена = 20000;
    Таблица.Добавить().Категория = "Мебель"; Таблица[4].Товар = "Стол"; Таблица[4].Цена = 10000;
    
    // Сортировка: сначала по категории (возрастание), затем по цене (убывание)
    Таблица.Сортировать("Категория, Цена УБЫВ");
    
    Сообщить("Сортировка по категории и цене:");
    Для Каждого Строка Из Таблица Цикл
        Сообщить(Строка.Категория + " | " + Строка.Товар + " | " + Строка.Цена);
    КонецЦикла;
    
КонецПроцедуры

Кастомная сортировка с использованием функции сравнения

// Пользовательская сортировка через функцию сравнения (для массива)
Функция СравнитьПоДлинеСтроки(Значение1, Значение2)
    
    Длина1 = СтрДлина(Значение1);
    Длина2 = СтрДлина(Значение2);
    
    Если Длина1 < Длина2 Тогда
        Возврат -1;
    ИначеЕсли Длина1 > Длина2 Тогда
        Возврат 1;
    Иначе
        Возврат 0;
    КонецЕсли;
    
КонецФункции

Процедура КастомнаяСортировкаМассива()

    МассивСтрок = Новый Массив;
    МассивСтрок.Добавить("яблоко");
    МассивСтрок.Добавить("груша");
    МассивСтрок.Добавить("вишня");
    МассивСтрок.Добавить("апельсин");
    МассивСтрок.Добавить("слива");
    
    Сообщить("Исходный массив: " + Строка(МассивСтрок));
    
    // Сортируем по длине строки
    МассивСтрок.Сортировать(Новый СравнениеЗначений(ЭтотОбъект, "СравнитьПоДлинеСтроки"));
    
    Сообщить("Сортировка по длине строки: " + Строка(МассивСтрок));
    
КонецПроцедуры

Сортировка списка значений с произвольным порядком

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

    Список = Новый СписокЗначений;
    Список.Добавить("Отгружен");
    Список.Добавить("Новый");
    Список.Добавить("В работе");
    Список.Добавить("Завершен");
    Список.Добавить("Отменен");
    
    // Задаем порядок сортировки
    Порядок = Новый Соответствие;
    Порядок.Вставить("Новый", 1);
    Порядок.Вставить("В работе", 2);
    Порядок.Вставить("Отгружен", 3);
    Порядок.Вставить("Завершен", 4);
    Порядок.Вставить("Отменен", 5);
    
    // Кастомная сортировка
    Для Инд = 1 По Список.Количество() - 1 Цикл
        Для Сч = 0 По Список.Количество() - Инд - 1 Цикл
            Приоритет1 = Порядок.Получить(Список[Сч].Значение);
            Приоритет2 = Порядок.Получить(Список[Сч + 1].Значение);
            
            Если Приоритет1 > Приоритет2 Тогда
                Временный = Список[Сч];
                Список[Сч] = Список[Сч + 1];
                Список[Сч + 1] = Временный;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    Сообщить("Сортировка с приоритетом:");
    Для Каждого Элемент Из Список Цикл
        Сообщить(Элемент.Значение);
    КонецЦикла;
    
КонецПроцедуры

Сортировка структуры по значению

// Сортировка пар ключ-значение по значению
Процедура СортировкаСтруктурыПоЗначению()

    Данные = Новый Структура;
    Данные.Вставить("Иванов", 150);
    Данные.Вставить("Петров", 300);
    Данные.Вставить("Сидоров", 200);
    Данные.Вставить("Кузнецов", 100);
    Данные.Вставить("Смирнов", 250);
    
    // Преобразуем в массив для сортировки
    МассивПар = Новый Массив;
    Для Каждого КлючЗначение Из Данные Цикл
        Пара = Новый Структура;
        Пара.Вставить("Ключ", КлючЗначение.Ключ);
        Пара.Вставить("Значение", КлючЗначение.Значение);
        МассивПар.Добавить(Пара);
    КонецЦикла;
    
    // Сортируем по значению
    Для Инд = 0 По МассивПар.Количество() - 1 Цикл
        Для Сч = 0 По МассивПар.Количество() - Инд - 2 Цикл
            Если МассивПар[Сч].Значение > МассивПар[Сч + 1].Значение Тогда
                Временный = МассивПар[Сч];
                МассивПар[Сч] = МассивПар[Сч + 1];
                МассивПар[Сч + 1] = Временный;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    Сообщить("Сортировка по значению (возрастание):");
    Для Каждого Пара Из МассивПар Цикл
        Сообщить(Пара.Ключ + ": " + Пара.Значение);
    КонецЦикла;
    
КонецПроцедуры

Сортировка с игнорированием регистра и специальных символов

// Кастомная сортировка строк с нормализацией
Функция НормализоватьСтроку(СтрокаДляНормализации)

    // Приводим к нижнему регистру
    Результат = НРег(СтрокаДляНормализации);
    
    // Удаляем специальные символы
    СпецСимволы = "!@#$%^&*()_+-=[]{};':\"\\|,.<>/?`~";
    Для Инд = 1 По СтрДлина(СпецСимволы) Цикл
        Символ = Сред(СпецСимволы, Инд, 1);
        Результат = СтрЗаменить(Результат, Символ, "");
    КонецЦикла;
    
    // Заменяем кириллицу (упрощенный пример)
    Результат = СтрЗаменить(Результат, "ё", "е");
    
    Возврат Результат;
    
КонецФункции

Функция СравнитьСНормализацией(Значение1, Значение2)
    
    Норм1 = НормализоватьСтроку(Значение1);
    Норм2 = НормализоватьСтроку(Значение2);
    
    Если Норм1 < Норм2 Тогда
        Возврат -1;
    ИначеЕсли Норм1 > Норм2 Тогда
        Возврат 1;
    Иначе
        Возврат 0;
    КонецЕсли;
    
КонецФункции

Процедура КастомнаяСортировкаСтрок()

    МассивСтрок = Новый Массив;
    МассивСтрок.Добавить("Яблоко!");
    МассивСтрок.Добавить("груша");
    МассивСтрок.Добавить("ВИШНЯ");
    МассивСтрок.Добавить("апельсин?");
    МассивСтрок.Добавить("Ёжик");
    
    Сообщить("Исходный массив: " + Строка(МассивСтрок));
    
    МассивСтрок.Сортировать(Новый СравнениеЗначений(ЭтотОбъект, "СравнитьСНормализацией"));
    
    Сообщить("Сортировка с нормализацией: " + Строка(МассивСтрок));
    
КонецПроцедуры

Сортировка объектов по нескольким свойствам

// Сортировка массива объектов по нескольким полям
Функция СравнитьОбъектыПоНесколькимПолям(Объект1, Объект2)

    // Сравниваем по категории
    Если Объект1.Категория < Объект2.Категория Тогда
        Возврат -1;
    ИначеЕсли Объект1.Категория > Объект2.Категория Тогда
        Возврат 1;
    КонецЕсли;
    
    // Если категории равны, сравниваем по цене (по убыванию)
    Если Объект1.Цена > Объект2.Цена Тогда
        Возврат -1;
    ИначеЕсли Объект1.Цена < Объект2.Цена Тогда
        Возврат 1;
    КонецЕсли;
    
    // Если и цена равна, сравниваем по наименованию
    Если Объект1.Наименование < Объект2.Наименование Тогда
        Возврат -1;
    ИначеЕсли Объект1.Наименование > Объект2.Наименование Тогда
        Возврат 1;
    КонецЕсли;
    
    Возврат 0;
    
КонецФункции

Процедура СортировкаОбъектов()

    // Создаем массив объектов (структур)
    МассивТоваров = Новый Массив;
    
    Товар1 = Новый Структура("Категория, Наименование, Цена", "Электроника", "Ноутбук", 50000);
    Товар2 = Новый Структура("Категория, Наименование, Цена", "Электроника", "Телефон", 30000);
    Товар3 = Новый Структура("Категория, Наименование, Цена", "Мебель", "Стол", 10000);
    Товар4 = Новый Структура("Категория, Наименование, Цена", "Электроника", "Планшет", 20000);
    Товар5 = Новый Структура("Категория, Наименование, Цена", "Мебель", "Стул", 3000);
    
    МассивТоваров.Добавить(Товар1);
    МассивТоваров.Добавить(Товар2);
    МассивТоваров.Добавить(Товар3);
    МассивТоваров.Добавить(Товар4);
    МассивТоваров.Добавить(Товар5);
    
    // Сортируем
    МассивТоваров.Сортировать(Новый СравнениеЗначений(ЭтотОбъект, "СравнитьОбъектыПоНесколькимПолям"));
    
    Сообщить("Сортировка по категории, затем по цене (убывание), затем по наименованию:");
    Для Каждого Товар Из МассивТоваров Цикл
        Сообщить(Товар.Категория + " | " + Товар.Наименование + " | " + Товар.Цена);
    КонецЦикла;
    
КонецПроцедуры

Сортировка с учетом логики «сначала свои, потом чужие»

// Приоритетная сортировка: сначала элементы из заданного списка
Процедура ПриоритетнаяСортировка()

    СписокГородов = Новый СписокЗначений;
    СписокГородов.Добавить("Москва");
    СписокГородов.Добавить("Санкт-Петербург");
    СписокГородов.Добавить("Новосибирск");
    СписокГородов.Добавить("Екатеринбург");
    СписокГородов.Добавить("Казань");
    СписокГородов.Добавить("Нижний Новгород");
    СписокГородов.Добавить("Челябинск");
    
    // Список приоритетных городов
    Приоритетные = Новый Соответствие;
    Приоритетные.Вставить("Москва", 1);
    Приоритетные.Вставить("Санкт-Петербург", 2);
    Приоритетные.Вставить("Казань", 3);
    
    // Сортируем пузырьком с приоритетом
    Для Инд = 0 По СписокГородов.Количество() - 1 Цикл
        Для Сч = 0 По СписокГородов.Количество() - Инд - 2 Цикл
            
            Приоритет1 = Приоритетные.Получить(СписокГородов[Сч].Значение);
            Приоритет2 = Приоритетные.Получить(СписокГородов[Сч + 1].Значение);
            
            // Если значение не найдено в приоритетах, даем большой номер
            Если Приоритет1 = Неопределено Тогда
                Приоритет1 = 999;
            КонецЕсли;
            Если Приоритет2 = Неопределено Тогда
                Приоритет2 = 999;
            КонецЕсли;
            
            // Если оба в приоритете или оба не в приоритете - сортируем по алфавиту
            Если (Приоритет1 < 999 И Приоритет2 < 999) ИЛИ (Приоритет1 >= 999 И Приоритет2 >= 999) Тогда
                Если СписокГородов[Сч].Значение > СписокГородов[Сч + 1].Значение Тогда
                    Временный = СписокГородов[Сч];
                    СписокГородов[Сч] = СписокГородов[Сч + 1];
                    СписокГородов[Сч + 1] = Временный;
                КонецЕсли;
            Иначе
                // Сортируем по приоритету
                Если Приоритет1 > Приоритет2 Тогда
                    Временный = СписокГородов[Сч];
                    СписокГородов[Сч] = СписокГородов[Сч + 1];
                    СписокГородов[Сч + 1] = Временный;
                КонецЕсли;
            КонецЕсли;
            
        КонецЦикла;
    КонецЦикла;
    
    Сообщить("Приоритетная сортировка (сначала Москва, Питер, Казань):");
    Для Каждого Город Из СписокГородов Цикл
        Сообщить(Город.Значение);
    КонецЦикла;
    
КонецПроцедуры

Сортировка по вычисляемому полю

// Сортировка по значению, которое вычисляется на лету
Процедура СортировкаПоВычисляемомуПолю()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Товар", Новый ОписаниеТипов("Строка"));
    Таблица.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число"));
    Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
    
    Таблица.Добавить().Товар = "Ноутбук"; Таблица[0].Цена = 50000; Таблица[0].Количество = 2;
    Таблица.Добавить().Товар = "Монитор"; Таблица[1].Цена = 15000; Таблица[1].Количество = 5;
    Таблица.Добавить().Товар = "Клавиатура"; Таблица[2].Цена = 2000; Таблица[2].Количество = 10;
    Таблица.Добавить().Товар = "Мышь"; Таблица[3].Цена = 1000; Таблица[3].Количество = 20;
    
    // Добавляем вычисляемую колонку
    Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
    Для Каждого Строка Из Таблица Цикл
        Строка.Сумма = Строка.Цена * Строка.Количество;
    КонецЦикла;
    
    // Сортируем по вычисляемой сумме
    Таблица.Сортировать("Сумма УБЫВ");
    
    Сообщить("Сортировка по общей сумме товаров:");
    Для Каждого Строка Из Таблица Цикл
        Сообщить(Строка.Товар + " | Цена: " + Строка.Цена + 
                 " | Кол-во: " + Строка.Количество + 
                 " | Сумма: " + Строка.Сумма);
    КонецЦикла;
    
КонецПроцедуры

Сортировка с ранжированием

// Сортировка с присвоением рангов (место в рейтинге)
Процедура СортировкаСРанжированием()

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Филиал");
    Таблица.Колонки.Добавить("Выручка");
    Таблица.Колонки.Добавить("Прибыль");
    
    Таблица.Добавить().Филиал = "Северный"; Таблица[0].Выручка = 1000000; Таблица[0].Прибыль = 200000;
    Таблица.Добавить().Филиал = "Южный"; Таблица[1].Выручка = 1500000; Таблица[1].Прибыль = 300000;
    Таблица.Добавить().Филиал = "Западный"; Таблица[2].Выручка = 800000; Таблица[2].Прибыль = 150000;
    Таблица.Добавить().Филиал = "Восточный"; Таблица[3].Выручка = 1200000; Таблица[3].Прибыль = 250000;
    Таблица.Добавить().Филиал = "Центральный"; Таблица[4].Выручка = 2000000; Таблица[4].Прибыль = 400000;
    
    // Сортируем по выручке
    Таблица.Сортировать("Выручка УБЫВ");
    
    // Добавляем колонку с рангом
    Таблица.Колонки.Добавить("Место");
    Ранг = 1;
    Для Каждого Строка Из Таблица Цикл
        Строка.Место = Ранг;
        Ранг = Ранг + 1;
    КонецЦикла;
    
    Сообщить("Рейтинг филиалов по выручке:");
    Для Каждого Строка Из Таблица Цикл
        Сообщика(Строка.Место + ". " + Строка.Филиал + " - выручка: " + Строка.Выручка);
    КонецЦикла;
    
    // Сортировка с учетом одинаковых значений (пропуск рангов)
    Таблица.Сортировать("Прибыль УБЫВ");
    Таблица.Колонки.Добавить("Рейтинг");
    
    ТекущийРанг = 1;
    ПредыдущаяПрибыль = 0;
    СчетчикПропусков = 0;
    
    Для Каждого Строка Из Таблица Цикл
        Если Строка.Прибыль <> ПредыдущаяПрибыль Тогда
            ТекущийРанг = ТекущийРанг + СчетчикПропусков;
            СчетчикПропусков = 1;
            ПредыдущаяПрибыль = Строка.Прибыль;
        Иначе
            СчетчикПропусков = СчетчикПропусков + 1;
        КонецЕсли;
        Строка.Рейтинг = ТекущийРанг;
    КонецЦикла;
    
    Сообщить("Рейтинг филиалов по прибыли (с учетом одинаковых значений):");
    Для Каждого Строка Из Таблица Цикл
        Сообщика(Строка.Рейтинг + ". " + Строка.Филиал + " - прибыль: " + Строка.Прибыль);
    КонецЦикла;
    
КонецПроцедуры

Примечания

// Важные особенности кастомной сортировки:
// 1. Для массивов используется метод Сортировать(Направление) или Сортировать(СравнениеЗначений)
// 2. Для таблиц значений используется метод Сортировать(СтрокаСортировки)
// 3. Строка сортировки может содержать несколько полей: "Поле1 УБЫВ, Поле2, Поле3 УБЫВ"
// 4. Для сложной логики сортировки используйте класс СравнениеЗначений и функцию сравнения
// 5. Функция сравнения должна возвращать -1, 0, 1
// 6. При сортировке больших объемов данных предпочтительнее использовать запросы
// 7. СписокЗначений можно преобразовать в массив для последующей сортировки
// 8. Для сортировки структуры преобразуйте ее в массив или таблицу значений
// 9. При сортировке по вычисляемым полям добавьте колонку в таблицу значений
// 10. Для ранжирования после сортировки добавьте соответствующий реквизит
// 11. Учитывайте регистр при сортировке строк - используйте НРег() при необходимости
// 12. Для пользовательских объектов реализуйте функцию сравнения с нужными полями

Поделиться с друзьями
Smirnov code
Добавить комментарий