Сортируем ДанныеФормыДерево на клиенте

10.09.20

Разработка - Работа с интерфейсом

Иногда так хочется, но нечем...

 

У ДанныеФормыКоллекция для сортировки есть специальный метод Сортировать(). Он доступен на клиенте и, хоть и делает вызов сервера, но, по понятным причинам, срабатывает крайне быстро.

 

А вот ДанныеФормыДерево платформа обделила такой возможностью. Вместо этого программисты обычно переходят «на сервер», преобразуют ДанныеФормыДерево в полноценное ДеревоЗначений, сортируют и преобразуют обратно.

 

ДеревоЗначений    = ДанныеФормыВЗначение(ДанныеФормыДерево, Тип("ДеревоЗначений")); 
ДеревоЗначений.Строки.Сортировать("КолонкиСортировки", Истина); 
ЗначениеВДанныеФормы(ДанныеФормыДерево, ДеревоЗначений);

 

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

 

Для реализации Менеджер открытых форм опробовал разные алгоритмы сортировки ДанныеФормыДерево, доступные на клиенте. В результате, остановился на этом, что помогло ускорить открытие формы обработки в 2,5 раза.

 

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

 

 

P.S.: Есть альтернативные варианты процедуры? Выкладывайте в комментариях. Если наберётся достаточное количество интересных методов, то после можем провести нагрузочное тестирование, выложить результаты сравнения и выбрать процедуру-победитель.

 

 

&НаКлиентеНаСервереБезКонтекста
Процедура СортироватьДанныеФормыДерево(КоллекцияСортировки, КолонкаСортировки, ВключатьПодчиненные = Ложь)
	
	КоллекцияСтрок  = КоллекцияСортировки.ПолучитьЭлементы();
	
	СортироватьДанныеФормыКоллекция(КоллекцияСтрок, КолонкаСортировки);
	
	Если ВключатьПодчиненные Тогда
		Для Каждого ТекущаяСтрока Из КоллекцияСтрок Цикл
			СортироватьДанныеФормыДерево(ТекущаяСтрока, КолонкаСортировки, ВключатьПодчиненные);
		КонецЦикла;
	КонецЕсли;
	
КонецПроцедуры

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

 

УФ Сортировка Дерево ДанныеФормыДерево

См. также

Богатый редактор картинок, хранимых в базе, с возможностью РИСОВАНИЯ. Редактор внешних файлов картинок. Объект, расширяющий возможности работы с картинками из встроенного языка (Три в одном) + Обработка «Стандартизация картинок»

Работа с интерфейсом Рабочее место Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Обработка предназначена для редактирования картинок в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Также обработка может быть использована из встроенного языка как объект для редактирования картинок. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Данная обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    61713    43    59    

80

[Расширения] Динамическое управление видимостью и доступностью элементов форм (УФ) (8.3.6+)

Работа с интерфейсом Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Механизм «Динамическое управление доступом к элементам форм объектов 1С8» предназначен для обеспечения возможности оперативного управления видимостью и доступностью элементов форм документов и справочников продуктов фирмы «1С» «1С:Предприятие 8». Решение универсальное, встраивается в любую конфигурацию с минимальными доработками, что позволяет без проблем обновлять типовые решения.

5000 руб.

14.01.2016    54321    16    21    

42

Управление дашбордами

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    16626    21    4    

35

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2025    21    progmaster    7    

3

Модель состояния для MVC

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

1 стартмани

05.07.2022    3582    kalyaka    2    

27

Табло очереди заказов на экран телевизора

WEB-интеграция Работа с интерфейсом Платформа 1С v8.3 1С:Розница 2 Платные (руб)

Связка из веб-приложения и расширения для 1С: Розница 2.3.

3600 руб.

29.04.2022    12014    1    5    

10

Условное оформление элементов форм в пользовательском режиме 1С (управление видимостью и доступностью элементов форм)

Работа с интерфейсом Платформа 1С v8.3 Платные (руб)

Подсистема условного оформления элементов форм (далее подсистема) предназначена для настройки оформления элементов форм (видимость, доступность, цвет фона, цвет текста и прочее) в пользовательском режиме 1С. Также подсистему возможно использовать для ограничения доступа к реквизитам формы для определенных пользователей (или групп пользователей).

6000 руб.

18.01.2022    8774    1    2    

6
Вознаграждение за ответ
Показать полностью
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. alex15650 211 18.06.19 10:57 Сейчас в теме
ДанныеФормыДерево вообще обделили, и поиск тоже хочется..
2. SeiOkami 3418 18.06.19 10:58 Сейчас в теме
(1) хорошая идея, добавлю в заметки
3. karpik666 3759 18.06.19 11:00 Сейчас в теме
На каком количестве элементов проверялась сортировка? 1С при этом не формирует неявных серверных вызовов?
4. SeiOkami 3418 18.06.19 11:25 Сейчас в теме
(3) боялись серверных вызовов, ибо используется метод Сдвинуть(), но не обнаружили ни по счётчику вызовов, ни по замеру производительности.

Проверяли так - генерили примитивную таблицу формы из рандомных чисел, а потом сортировали. Перебирали разные алгоритмы. Этим добились того, что 1000 элементов таблицы с рандомными числами диапазоном до 1000 сортируются меньше секунды. 10 000 строк с рандомом до 10 000 тратит время на сортировку ≈ 3 секунды.

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

+ заметили в некоторых ситуациях такую вещь, что перепрыгивание на сервер иногда занимает совершенно неразумное время. Доходило до абсурдного, что для редактирования таблицы данных на сервере, приходилось использовать бесконтекстный вызов сервера, а передавать туда массив со структурами, обрабатывать там в ТЗ, корректировать,обратно превращать в массив со структурами, возвращать как результат функции, а далее уже на клиенте содержимое помещать в таблицу формы. Костыль редкостный, но увеличивал скорость работы в несколько раз.

Попробуем проанализировать ситуацию, если что-то интересное - будет статья.
markers; SergeRSA; acanta; +3 Ответить
5. karpik666 3759 18.06.19 11:28 Сейчас в теме
(4) то есть использовались только числа? Попробуйте такое же количество, но ссылочных элементов, очень интересно как отработает Обработка представления для этих элементов без серверных вызовов, и кэширует ли 1С все представления на клиенте для такого количества элементов
7. SeiOkami 3418 18.06.19 11:36 Сейчас в теме
(5)
Да, скорее всего не так классно будет.

Просто в разработке сортировок по ссылке стараемся максимально избегать. Даже уже привык сортировать по примитивным типам, которые заранее готовятся специально.

Однако, в данном алгоритме именно сортировка используется только один раз на уровень дерева - СортироватьПоЗначению(). Метод платформенный, никаких "ручных" сравнений нет. Но потестировать нужно, интересно
8. karpik666 3759 18.06.19 11:42 Сейчас в теме
(7) это понятно, но ваш пример далек от реальности, так как вы используйте примитивные типы, то неявных серверных вызовов и не будет, но мне больше кажется, что такой вариант будет все равно вызывать метод сервера. Сам ранее пытался писать код, который максимально бы работал на клиенте, но все старания разбивались о работу самой 1С, которая фоном делала серверные вызовы для кода. которая в теории должен был исполняться только на клиенте.
9. SeiOkami 3418 18.06.19 11:47 Сейчас в теме
(8) пока что в этом алгоритме не замечено было, но Вы правы - нужно проверить на ссылочных типах.
11. SeiOkami 3418 18.06.19 12:12 Сейчас в теме +5 $m
(9)
(8)
Проверил на ссылке. Добавил ссылочную колонку в таблицу формы. Заполнил таблицу ссылками на существующие документы (выбрал первые 10 000 документов и разбросал рандомно по таблице). Сортировка заняла 4 секунды и счётчик вызовов не показал.

Скорее всего СписокЗначений.СортироватьПоЗначению() использует ГУИДы, а не представления, поэтому обращений на сервер и не требовалось
Alogy; karpik666; +2 Ответить
13. karpik666 3759 18.06.19 12:18 Сейчас в теме
(11) проблема не в самом методе сортировки, а в выводе дерева на экран, так как в ссылочном поле происходит северная обработка представления, потому и было интересно как поведет себя 1с. Спасибо, будет желание еще сам проверю работу этого метода
6. karpik666 3759 18.06.19 11:30 Сейчас в теме
(4) при личной проверке довольно часто выходит, что безконтекстная передача таблицы формы может быть дольше, чем контекстный серверный вызов, все зависит от того, какой объем информации содержится в остальных элементах, если по сравнениню с таблицей их пренебрежительно мало, то лучше контекстный вызов.
10. Evg-Lylyk 4547 18.06.19 12:12 Сейчас в теме
(0) Сталкивался с подобной проблемой, чуток анализировал вопрос понял что для большого количества строк на сервере быстрее
Описанный вариант кажется не оптимальным создает массив сдвигает, быструю сортировку пробовали?
12. SeiOkami 3418 18.06.19 12:16 Сейчас в теме
(10) пробовали с десяток разных алгоритмов, уже и не вспомню. Но остановились на этом. И заполнение списка значений здесь привело хороший прирост. Этот объект быстро сортирует.

Если у вас есть процедура быстрее, то выкладывайте. Хочется найти "самую-самую" и закрепить в статье.

Когда появится время, сделаю специальный инструмент для удобного тестирования методов сортировки. Чтобы можно было свою процедуру легко вставить и гонять по скорости
14. Infector 199 18.06.19 15:19 Сейчас в теме
Есть стандартные команды сортировки для элементов форм. Чаще всего проще обратить на них внимание пользователей и как-то закрепить на командных панелях. Если же сортировать нужно, но без участия пользователей скорее всего этот объект использован не в тему.
15. starik-2005 3031 20.06.19 12:30 Сейчас в теме
А не пробовали сортировать "нативно"? Тем же квиксортом?
19. Cyberhawk 135 15.10.20 18:41 Сейчас в теме
(15) А под "нативно" что имеется в виду?
28. kalyaka 1050 14.04.22 10:29 Сейчас в теме
(19) можно использовать разные алгоритмы сортировки, реализация на 1с рассмотрена в статье Популярные алгоритмы сортировки массивов
16. AlexBober78 21.06.19 18:46 Сейчас в теме
Что-то не выкладывают альтернативные варианты)
Вообще, какой-нибудь конкурс устроить. Пусть и символический.
И обработку общую сделать. Для теста с генерацией данных.
17. пользователь 01.11.19 16:41
Сообщение было скрыто модератором.
...
18. user1284652 01.11.19 16:43 Сейчас в теме
В общем, самая "нативная" сортировка (не без участия jQuery) у меня получилась следующим образом:
Все данные в ячейках я вношу в data-attribute, которые легализованы в HTML5. Чтобы метод sort() работал так, как мне надо -- данные привожу в к нижнему регистру и заменяю кавычки на апострофы, чтобы не возникла конфликта на уровне HTML.
20. e745030 29.07.21 17:21 Сейчас в теме
СписокЗначенийСортировки = Новый СписокЗначений;
	ДеревоДляСортировки = ДеревоСФормы.ПолучитьЭлементы();
	
	Счетчик = 0;
	Для Каждого СтрокаДерева Из ДеревоДляСортировки Цикл
		СписокЗначенийСортировки.Добавить(СтрокаДерева.ОсновнаяСистема, Счетчик);
		Счетчик = Счетчик + 1;
	КонецЦикла;
	
	СписокЗначенийСортировки.СортироватьПоЗначению();
	
	НеобходимыйНомерСтроки = 0;
	СмещениеВниз = 0;
	
	Для Каждого ЗначениеСортировки Из СписокЗначенийСортировки Цикл
		ТекущийНомерСтроки = Число(ЗначениеСортировки.Представление);
		
		Если ТекущийНомерСтроки < НеобходимыйНомерСтроки  Тогда
			ТекущийНомерСтроки = ТекущийНомерСтроки + СмещениеВниз;
		КонецЕсли;
		
		Если ТекущийНомерСтроки <> НеобходимыйНомерСтроки Тогда
			ДеревоДляСортировки.Сдвинуть(ТекущийНомерСтроки, НеобходимыйНомерСтроки - ТекущийНомерСтроки);
			
			СмещениеВниз = СмещениеВниз + 1;		
		КонецЕсли;
		
		НеобходимыйНомерСтроки = НеобходимыйНомерСтроки + 1;
	КонецЦикла;
Показать
Поручик; +1 Ответить
21. markers 274 29.12.21 12:35 Сейчас в теме
SeiOkami, огромное спасибо! Если кому совсем лень и нужна возможность изменять направление сортировки, то милости просим:
&НаКлиентеНаСервереБезКонтекста
Процедура СортироватьДанныеФормыДерево(КоллекцияСортировки, КолонкаСортировки, ВключатьПодчиненные = Ложь, ПоВозрастанию = Истина)
	
	КоллекцияСтрок = КоллекцияСортировки.ПолучитьЭлементы();
	
	СортироватьДанныеФормыКоллекция(КоллекцияСтрок, КолонкаСортировки, ПоВозрастанию);
	
	Если ВключатьПодчиненные Тогда
		
		Для Каждого ТекущаяСтрока Из КоллекцияСтрок Цикл
			
			СортироватьДанныеФормыДерево(ТекущаяСтрока, КолонкаСортировки, ВключатьПодчиненные, ПоВозрастанию);
			
		КонецЦикла;
		
	КонецЕсли;
	
КонецПроцедуры

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

Ну и в друг, кому будет нужно: Интерактивный отбор в дереве
22. TimurD 6 31.03.22 09:40 Сейчас в теме
Самому как-то понадобилось использовать методы Найти и НайтиСтроки на клиенте у дерева. Реализовал алгоритм (по итогу сравнивал структуры), но на практике выяснил, что при большом дереве (от 1000 элементов примерно) производительность проседала. Сортировки и отборы на клиенте вещь, конечно хорошая, но если там данных немного. В остальных случаях лучше ходить на сервер, типа выбираем меньшее из зол.
23. Aleksey_Abramov 04.04.22 12:34 Сейчас в теме
Работает. Вставил в свой код. Плюсую. Но мне не понятно, как это работает? Уже нервничать начинаю.
Объясните кусок кода:
Для Каждого ТекущаяСтрока Из КоллекцияСтрок Цикл
		
		ТекущееЗначение = ТекущаяСтрока[КолонкаСортировки];
		
		ПараметрыЗначения = ПараметрыЗначений.Получить(ТекущееЗначение);
		Если ПараметрыЗначения = Неопределено Тогда
			ПараметрыЗначения = Новый Массив;
			ПараметрыЗначений.Вставить(ТекущееЗначение, ПараметрыЗначения);
			СортированныеЗначения.Добавить(ТекущееЗначение);
		КонецЕсли;
		
		ПараметрыЗначения.Добавить(ТекущаяСтрока);
		
	КонецЦикла;
Показать

Для чего здесь массив ПараметрыЗначения? Он ведь постоянно создаётся новый. Потом вставляется в ПараметрыЗначений этот пустой массив, а только потом в него добавляется элемент. И опять новый массив. Мне кажется тут что-то лишнее. Если нет, объясните, что в нём и зачем он в дальнейшем?
24. SeiOkami 3418 04.04.22 12:42 Сейчас в теме
(23)
Он создаётся новый для каждого уникального значения колонки. Т.е., если в коллекции будет 100 строк с одинаковым значением колонки, то массив будет создан один раз и наполнен этими 100 строками.
25. Aleksey_Abramov 04.04.22 13:06 Сейчас в теме
(24) В моём случае разные строки. Но непонятно, зачем создаётся этот массив, потом он пустым вставляется в соответствие, а только потом в массив добавляется значение и он потом затирается. Или если добавить массив в соответствие, а потом в массив добавить элемент. То и в соответствии этот массив изменится? Думаю понятно выразил мысль)
26. SeiOkami 3418 04.04.22 13:27 Сейчас в теме
(25)
Или если добавить массив в соответствие, а потом в массив добавить элемент

Ага, именно так)

Мы создаём массив. И 1С размещает его где-то в памяти, а нам в переменную отдаёт ссылку на массив.
Мы эту ссылку помещаем в соответствие. И если где-то в коде (где угодно) мы этот массив изменим, то и в соответствии он изменится. Потому что там лежит ссылка на оригинал, который мы меняем (так же по ссылке).
Aleksey_Abramov; +1 Ответить
27. Aleksey_Abramov 10.04.22 17:37 Сейчас в теме
(26) Спасибо за ответы на мои странные вопросы) Разобрался.
SeiOkami; +1 Ответить
29. kalyaka 1050 14.04.22 10:56 Сейчас в теме
Предлагаю свой вариант решения на основе реализации абстрактных алгоритмов
В функциональном стиле:
ОтсортированныеЭлементыДерева = атдМассив
	.Массив(ЭлементыДерева)
	.СортироватьПо("Наименование")
	.ВМассив()
;
В процедурном:
ОтсортированныеЭлементыДерева = ОбщегоНазначенияКлиентСервер.СкопироватьМассив(ЭлементыДерева);
РаботаСМассивом.СортироватьПо(ОтсортированныеЭлементыДерева, "Наименование");
Пример можно посмотреть в демо базе
30. SeiOkami 3418 14.04.22 11:42 Сейчас в теме
(29)страница не найдена
Прикрепленные файлы:
31. kalyaka 1050 14.04.22 12:03 Сейчас в теме
(30) по всей видимости нужна регистрация на github. Еще демо-база прикреплена к статье Работа с абстрактным массивом
32. SeiOkami 3418 14.04.22 12:13 Сейчас в теме
(31) авторизовался
Всё равно 404)
Прикрепленные файлы:
33. kalyaka 1050 14.04.22 12:56 Сейчас в теме
(32)Извините, я оказывается не перевел релиз в publlish. Попробуйте теперь.
Если что, то вот ссылка на релиз https://github.com/KalyakinAG/adt-array/releases/tag/v1.0.5
35. SeiOkami 3418 21.04.22 17:12 Сейчас в теме
(29) посмотрел, интересный подход. Но, к сожалению, это будет работать однозначно намного медленнее хотя бы из-за создания объекта формы\обработки и использования Выполнить(""). А выложенная в посте функция сделана специально для быстрой сортировки на клиенте.
36. kalyaka 1050 21.04.22 19:19 Сейчас в теме
(35)Ну объект там создается один раз при открытии формы и далее используется неограниченное количество раз.

В процедурном варианте объект вообще не создается.

Вместо Выполнить() используется Вычислить(). Разница не только в том, что вторая использует выражение, но и в том, что Вычислить() работает на всех клиентах в отличии от Выполнить().

Пожертвовав универсальностью можно заменить Вычислить() на функцию "Сравнить(А.Наименование, Б.Наименование)", быстродействие процентов на 20% примерно прибавится.
Вот что у меня получилось для двух алгоритмов: нативный и ваш:
---
Вариант нативно 2: 13 мс
Вариант нативно 2: 12 мс
Вариант нативно 2: 9 мс
Вариант нативно 2: 9 мс
Вариант нативно 2: 8 мс
Вариант список значений: 10 мс
Вариант список значений: 12 мс
Вариант список значений: 13 мс
Вариант список значений: 13 мс
Вариант список значений: 10 мс
---
Функция Сравнить(А, Б)
	Если А = Б Тогда
		Возврат 0;
	КонецЕсли;
	Если А < Б Тогда
		Возврат -1;
	КонецЕсли;
	Возврат 1;
КонецФункции
Показать

Видно, что мой алгоритм даже работает быстрее. В моем алгоритме нет лишнего преобразования в массив, а алгоритм сортировки использован "Быстрая сортировка" (в платформе скорее всего такой же).

Но, здесь я использовал жестко заданное поле "Наименование" (можно любое другое, важно, что в алгоритме оно жестко прописывается). Поле можно передавать в функцию, тогда вызов будет "Сравнить(А[Поле], Б[Поле])" - скорость почти прежняя.

Ок, можно расширить количество полей сортировки, для этого нужно заменить на функцию СравнитьПо(А, Б, Поля). Вот что у меня получилось для полей сортировки "ВидНоменклатуры, Наименование":
---
Вариант нативно 3: 9 мс
Вариант нативно 3: 15 мс
Вариант нативно 3: 15 мс
Вариант нативно 3: 15 мс
Вариант нативно 3: 15 мс
---
Функция СравнитьПо(А, Б, Поля)
	Для Каждого Поле Из СтрРазделить(Поля, ", ", Ложь) Цикл
		Результат = Сравнить(А[Поле], Б[Поле]);
		Если Результат < 0 Тогда
			Возврат -1;
		ИначеЕсли Результат > 0 Тогда
			Возврат 1;
		КонецЕсли;
	КонецЦикла;
	Возврат 0;
КонецФункции
Показать

Что ж, результат немного хуже, но достаточно близок к вашему варианту. Однако этот алгоритм не имеет ограничения по количеству полей сортировки и он достаточно быстрый.

К этому посту прикреплена демо-обработка, запускать в демо-базе.
Прикрепленные файлы:
_ДемоАТДМассив.epf
37. kalyaka 1050 21.04.22 21:10 Сейчас в теме
(36)Исправил в обработке неточность: Вариант Нативно 3 (по полю), Вариант Нативно 4 (по нескольким полям). Типы дополнительных полей привел к простым, т.к. сортировка по составным полям будет явно проседать (практически запрос в цикле получится).
Прикрепленные файлы:
_ДемоАТДМассив.epf
38. kalyaka 1050 22.04.22 17:48 Сейчас в теме
(35)
сделана специально для быстрой сортировки на клиенте
Кстати все предложенные мной алгоритмы работают на клиенте без обращения на сервер, даже объектный вариант.
34. kalyaka 1050 18.04.22 19:52 Сейчас в теме
Добавил еще два варианта:

с использованием приоритетной очереди
ОтсортированныеЭлементыДерева = Новый Массив;
Для Каждого ЭлементДерева Из ЭлементыДерева Цикл
	РаботаСМассивом.ПоложитьВОчередьСПриоритетом(ОтсортированныеЭлементыДерева, ЭлементДерева, "Сравнить(А.Наименование, Б.Наименование)");
КонецЦикла;
нативный
&НаКлиенте
Процедура СортироватьЭлементыНативно(Элементы, ВыражениеПредиката, НижнийПредел, ВерхнийПредел)
    Начало = НижнийПредел;
    Конец = ВерхнийПредел;
    Б = Элементы[Цел((Начало + Конец)/2)];
    Пока Истина Цикл
        А = Элементы[Начало];
        Пока Вычислить(ВыражениеПредиката) < 0 Цикл // Элементы[Начало] < Б
            Начало = Начало + 1;                   
            А = Элементы[Начало];
        КонецЦикла;
        А = Элементы[Конец];
        Пока Вычислить(ВыражениеПредиката) > 0 Цикл // Элементы[Конец] > Б
            Конец = Конец - 1;                   
            А = Элементы[Конец];
        КонецЦикла; 
        Если Начало <= Конец Тогда               
            //  Дерево значений
            //  Начало -> Конец
            //  Конец -> Начало 
            
            ШагСдвига = Конец - Начало;
            Если НЕ ШагСдвига = 0 Тогда
                Элементы.Сдвинуть(Начало, ШагСдвига);
                ШагСдвига = ШагСдвига - 1;
                Если НЕ ШагСдвига = 0 Тогда
                    Элементы.Сдвинуть(Конец - 1, -ШагСдвига);
                КонецЕсли;
            КонецЕсли;
            
            //  Дерево значений            
            Начало = Начало + 1;
            Конец = Конец - 1;            
        КонецЕсли;
        Если Начало > Конец Тогда                       
            Прервать;                        
        КонецЕсли;
    КонецЦикла;
    Если НижнийПредел < Конец Тогда         
        СортироватьЭлементыНативно(Элементы, ВыражениеПредиката, НижнийПредел, Конец);        
    КонецЕсли; 
    Если Начало < ВерхнийПредел Тогда                      
        СортироватьЭлементыНативно(Элементы, ВыражениеПредиката, Начало, ВерхнийПредел);        
    КонецЕсли;
    
КонецПроцедуры
Показать
Скачать демо можно из статьи или из github
Оставьте свое сообщение