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