Переход от сортировки по разным колонкам и направлениям к сортировке по возрастанию одного ключаСуть алгоритма состоит в том, чтобы заменить сортировку таблицы по нескольким полям с разными направлениями на сортировку по одному полю-индексу по возрастанию. | | Автор статьи: Гений 1С | Редакторы: Последняя редакция №2 от 14.03.07 | История URL: http://kb.mista.ru/article.php?id=254 | |
Ключевые слова: алгоритм,сортировка,таблицы
Суть алгоритма состоит в том, чтобы заменить сортировку таблицы по нескольким полям с разными направлениями на сортировку по одному полю-индексу по возрастанию.
Возможно, метод мало применим в 1С, зато хорошо работает в JavaScript, где нет встроенных функций по сортировке таблиц (хэшей).
Предположим у нас есть таблица Т с колонками К1, …. КN.
Пусть мы хотим отсортировать таблицу по этим колонкам например К1 по возрастанию, К3 по убыванию, К2 по возрастанию.
Построим строковый индекс по следующему алгоритму:
Для Каждой Стр ИЗ Т Цикл
СтроковыйИндекс="";
Для Каждой Кол из КолонкиСортировки Цикл
ТекИндекс="";
Зн=Стр[Кол];
Если Зн имеет тип Число Тогда
ТекИндекс=ЧислоСимволовВЧисле(Зн)+Строка(Зн);
ИначеЕсли Зн имеет тип Дата Тогда
ТекИндекс=Формат(Зн,"ГГГГММДД"); //Порядок год-месяц-день
ИначеЕсли Зн имеет тип Строка Тогда
ТекИндекс=Строка(Зн);
КонецЦикла;
Если Кол.Направление="-" Тогда //Если направление по убыванию
ТекИндекс=ИнвертироватьИндекс(ТекИндекс);
КонецЕсли;
СтроковыйИндекс=СтроковыйИндекс+ТекИндекс;
КонецЦикла;
Стр.СтроковыйИндекс=СтроковыйИндекс;
КонецЦикла;
Стр.Сортировать("СтроковыйИндекс"); //Сортируем по возрастанию строкового индекса
Необходимо добиться того, чтобы все типы преобразовались в строку с соблюдением порядка сортировки.
Если в колонке хранится строка, то она переносится в индекс как есть.
"Вася" -> "Вася"
Если хранится число, то существует несколько способов преобразования числа в строку, чтобы соблюдался порядок сортировки. При этом преобразуется только целая часть числа, а после нее через точку записывается дробная часть:
19<134=истина
"19""1134" = ложь - без преобразование сравнение чисел не работает.
1. Выравнивание по длине. Число преобразуется в строку определенной длины. Недостающие разряды слева заменяются нулями. Однако метод не всегда применим, т.к. мы не всегда знаем максимальное число, которое может быть:
19 -> "00000019"
1134 -> "00001134"
"00000019""00001134" = истина
2. Хранения числа разрядов (тетрад) целой части числа - более компактный и универсальный вариант. Первые N символов строкового представления отводятся для отображения числа разрядов (тетрад), целой части числа. Это число дополнено слева нулями до N разрядов. Двух символов достаточно для сортировки 99-разрядных чисел (или 300-разрядных чисел в случае с тетрадами). А дальше идет целая часть числа, после нее через точку дробная. Если используются тетрады, то число выравнивается по тетрадам.
Пример с разрядами:
19 -> "0219" (02 - число разрядов, 19 - число)
2 -> "012" (01 - число разрядов, 2 - число)
1134 -> "041134" (02 - число разрядов, 1134 - число)
"0219""041134" = истина
"012""0219" = истина
Пример с тетрадами:
19 -> "01019" (01 - число тетрад, 019 - число, выровненное по тетрадам)
2 -> "01002" (01 - число тетрад, 002 - число, выровненное по тетрадам)
1134 -> "02001134" (02 - число тетрад, 001134 - - число, выровненное по тетрадам)
"01019""02001134" = истина
"01002""01019" = истина
Если хранится дата, то она преобразуется в строку формата ГГГГММДДЧЧММСС:
20 ноября 2006 -> "20061120"
"20061120" < "20061220" = истина
Если колонку нужно сортировать не по возрастанию, а по убыванию, то строка преобразуется в инвертированную - т.е. каждый символ в строке заменяется на символ с кодом 255-[Код символа]. Т.е. самый маленький символ с кодом 0 становится самым большим символом с кодом 255 и т.п.
Сортируем таблицу Т по полученному строковому индексу обычным сравнением строк по возрастанию. |