Как отсортировать таблицу значений в 1С по заданному нестандартному правилу символов?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с большими объемами текстовых данных в 1С часто возникает необходимость изменить стандартную логику сортировки. Стандартный метод ТаблицаЗначений.Сортировать() опирается на системные региональные настройки, которые часто игнорируют разницу между заглавными и строчными буквами, а также не учитывают специфический порядок категорий символов (например, когда англоязычные символы должны идти строго перед русскими). Разберем, как эффективно решить эту задачу для таблицы значений с 28 000+ записей.

Метод создания «ключа сортировки»

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

Для реализации этого подхода выполним следующие шаги:

  1. Добавим в ТаблицаЗначений дополнительную колонку Порядок с типом Строка.
  2. Для каждой строки таблицы вычислим значение этой колонки, основываясь на символьном составе исходной строки.
  3. Присвоим каждому символу уникальный префикс, соответствующий его приоритету (например, английские заглавные — «0», строчные — «1» и так далее).

Рассмотрим пример реализации на сервере:


Процедура СортироватьПоПравилуНаСервере(Таблица)
    ПорядокСимволов = Новый Соответствие;
    ТЗ = РеквизитФормыВЗначение("Таблица");
    ТЗ.Колонки.Добавить("Порядок", Новый ОписаниеТипов("Строка"));

    Для Каждого Стр Из ТЗ Цикл
        Массив = Новый Массив;
        Для Сч = 1 По СтрДлина(Стр.Значение) Цикл
            ТекущийСимвол = Сред(Стр.Значение, Сч, 1);
            Порядок = ПорядокСимволов[ТекущийСимвол];
            Если Порядок = Неопределено Тогда
                Порядок = ПорядокСимвола(ТекущийСимвол);
                ПорядокСимволов[ТекущийСимвол] = Порядок;
            КонецЕсли;
            Массив.Добавить(Порядок + ТекущийСимвол);
        КонецЦикла;
        Стр.Порядок = СтрСоединить(Массив);
    КонецЦикла;

    ТЗ.Сортировать("Порядок");
    ЗначениеВРеквизитФормы(ТЗ, "Таблица");
КонецПроцедуры

Функция ПорядокСимвола определяет вес каждого знака. Вы можете расширять её, добавляя любые специфические группы символов:


Функция ПорядокСимвола(Символ)
    Если Найти("ABCDEFGHIJKLMNOPQRSTUVWXYZ", Символ) > 0 Тогда Возврат "0" КонецЕсли;
    Если Найти("abcdefghijklmnopqrstuvwxyz", Символ) > 0 Тогда Возврат "1" КонецЕсли;
    Если Найти("АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ", Символ) > 0 Тогда Возврат "2" КонецЕсли;
    Если Найти("абвгдеёжзийклмнопрстуфхцчшщъыьэюя", Символ) > 0 Тогда Возврат "3" КонецЕсли;
    Если Найти("0123456789", Символ) > 0 Тогда Возврат "4" КонецЕсли;
    Возврат "5"
КонецФункции

Метод разделения на подтаблицы

Если производительность метода с посимвольным перебором оказывается недостаточной, воспользуемся альтернативным подходом. Мы можем разделить исходную ТаблицаЗначений на группы (например, группа «Английские», группа «Русские», группа «Цифры»), отсортировать каждую из них стандартным методом Сортировать(), а затем объединить их обратно.

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

Важные рекомендации по оптимизации

При работе с объемами данных более 20-30 тысяч записей, обратите внимание на следующие моменты:

1. Предварительная фильтрация: Если ваша задача подразумевает сортировку только по первому символу, нет смысла усложнять ключ для всей строки. Достаточно добавить колонку ИндексПриоритета (число), заполнить её на основании первого символа и сортировать таблицу по двум полям: ИндексПриоритета и Значение.

2. Учет регистра: Помните, что стандартная сортировка часто игнорирует регистр. Если для вас критично, чтобы заглавная буква стояла раньше строчной (например, «А» перед «а»), создание вспомогательного «ключа сортировки» — единственное надежное решение, так как стандартные методы не позволяют гибко настраивать правила сравнения строк по символам.

3. Использование ВРег(): Если специфические правила регистра не требуются, а нужно просто отсортировать таблицу «как есть», попробуйте сначала привести данные к верхнему регистру с помощью функции ВРег() в отдельной колонке — это часто ускоряет процесс поиска и классификации данных перед основным циклом обработки.

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

← На главную