Работа с динамическими списками — одна из самых частых задач при разработке управляемого интерфейса в 1С. Если с программной установкой отбора (фильтрации) большинство разработчиков справляются быстро, то управление порядком (сортировкой) часто вызывает вопросы. Это связано с тем, что динамический список базируется на механизме Системы компоновки данных (СКД), и управление его свойствами требует понимания структуры компоновщика настроек.
В этой статье мы подробно разберем, как программно упорядочить данные в списке, рассмотрим различные методы доработки динамических списков, включая различия между фиксированными и пользовательскими настройками, а также проанализируем влияние этих действий на производительность системы.
Прежде чем переходить к коду, давайте разберем, где именно хранится информация о сортировке. Объект ДинамическийСписок имеет свойство КомпоновщикНастроек. Внутри него есть несколько уровней настроек, которые и определяют итоговое поведение списка:
Рассмотрим ситуацию: если мы программно меняем порядок в основных настройках, а у пользователя в этот момент уже сохранена своя личная сортировка, то наши изменения могут просто «не взлететь». Именно поэтому важно понимать, на каком уровне мы вносим правки, и как работает сохранение настроек формы для всех пользователей.
Если нам нужно быстро установить сортировку при открытии формы или по нажатию кнопки, мы можем обратиться напрямую к коллекции элементов порядка. Рассмотрим пример, в котором мы очищаем текущую сортировку и устанавливаем свою по полю Дата в убывающем порядке.
// Очищаем существующие элементы порядка, чтобы они не конфликтовали с новыми
Список.Порядок.Элементы.Очистить();
// Добавляем новый элемент порядка
НовыйПорядок = Список.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
// Настраиваем поле, по которому будет идти сортировка
НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных("Дата");
// Указываем направление сортировки: Возр (по возрастанию) или Убыв (по убыванию)
НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
// Обязательно включаем использование этого элемента
НовыйПорядок.Использование = Истина;
// Режим отображения позволяет видеть эту настройку в стандартном окне настроек
НовыйПорядок.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Авто;
Этот метод работает хорошо, когда список простой и мы не боимся перетереть настройки пользователя. Однако в современных конфигурациях на платформе 8.3 рекомендуется работать через пользовательские настройки.
Платформа 1С сохраняет настройки пользователя (отборы, группировки, порядок) отдельно. Чтобы программно изменить именно ту сортировку, которую видит и может редактировать пользователь, нам нужно найти элемент порядка в коллекции пользовательских настроек по его уникальному идентификатору.
Давайте проанализируем следующий алгоритм:
// 1. Находим идентификатор пользовательской настройки для порядка
ИдентификаторНастройки = Список.Порядок.ИдентификаторПользовательскойНастройки;
// 2. Ищем сам объект порядка в пользовательских настройках по этому ID
ЭлементПользовательскойНастройки = Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ИдентификаторНастройки);
Если ТипЗнч(ЭлементПользовательскойНастройки) = Тип("ПорядокКомпоновкиДанных") Тогда
// Очищаем старые настройки пользователя
ЭлементПользовательскойНастройки.Элементы.Очистить();
// Добавляем новое правило сортировки
НовыйПорядок = ЭлементПользовательскойНастройки.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных("Номер");
НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
НовыйПорядок.Использование = Истина;
КонецЕсли;
Этот способ является наиболее корректным с точки зрения UX (User Experience). Пользователь увидит, что список отсортирован, и при необходимости сможет зайти в настройки и изменить их. Если использовать фиксированные настройки, пользователь окажется «заперт» в рамках вашей логики сортировки.
Иногда требуется реализовать поведение, при котором список сортируется в зависимости от того, на какой колонке сейчас стоит курсор пользователя. Это можно сделать, комбинируя свойства элемента формы и программное добавление порядка.
Рассмотрим пример реализации:
// Предположим, ТекущийЭлемент - это таблица формы, отображающая наш динамический список
ТекущаяКолонка = Элементы.Список.ТекущийЭлемент;
// Получаем имя поля, связанного с колонкой
ИмяПоля = ТекущаяКолонка.ПутьКДанным;
// Важно: ПутьКДанным может содержать префикс "Объект." или "Список.", его нужно отсечь
ИмяПоляДляСКД = СтрЗаменить(ИмяПоля, "Список.", "");
Порядок = Список.Порядок;
Порядок.Элементы.Очистить();
НовыйПорядок = Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных(ИмяПоляДляСКД);
НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
НовыйПорядок.Использование = Истина;
Программная установка порядка — это не просто изменение интерфейса, это изменение SQL-запроса, который 1С отправляет к СУБД. Выясним причины, по которым сортировка может замедлять работу системы:
1. Отсутствие индексов. Если вы устанавливаете порядок по реквизиту, который не является индексированным, СУБД придется сканировать всю таблицу. Всегда проверяйте, стоит ли галочка Индексировать у реквизита в конфигураторе, если планируете часто использовать его для сортировки.
2. Сортировка по вычисляемым полям. Если в тексте запроса динамического списка вы используете конструкции ВЫБОР КОГДА... или сложные соединения, и пытаетесь отсортировать результат по этому «виртуальному» полю, индексы использоваться не будут. Это приведет к значительным тормозам на больших объемах данных.
3. Свойство Автопорядок. В свойствах динамического списка в конфигураторе есть флаг Автопорядок. Если он включен, система автоматически добавляет поле Ссылка в конец списка полей сортировки. Это гарантирует стабильность выборки при постраничном выводе, но иногда может конфликтовать с вашей сложной программной логикой. Если вы строите очень специфическую сортировку, иногда Автопорядок стоит выключить.
4. Иерархия. Помните, что в иерархических списках (деревьях) программная сортировка работает внутри каждого уровня иерархии. То есть сначала сортируются группы верхнего уровня, а затем — элементы внутри каждой группы. Смешать элементы разных групп обычной сортировкой не получится.
Для программного управления порядком в ДинамическийСписок мы используем объект ЭлементПорядкаКомпоновкиДанных. Наиболее гибким и правильным подходом является модификация коллекции ПользовательскиеНастройки, так как это не вступает в конфликт с механизмами платформы по сохранению настроек пользователя. Всегда учитывайте наличие индексов в базе данных, чтобы ваше решение работало быстро даже при сотнях тысяч записей.