Как программно настроить сортировку в динамическом списке 1С

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

Работа с динамическими списками — одна из самых частых задач при разработке управляемого интерфейса в 1С. Если с программной установкой отбора (фильтрации) большинство разработчиков справляются быстро, то управление порядком (сортировкой) часто вызывает вопросы. Это связано с тем, что динамический список базируется на механизме Системы компоновки данных (СКД), и управление его свойствами требует понимания структуры компоновщика настроек.

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

Понимание структуры порядка в динамическом списке

Прежде чем переходить к коду, давайте разберем, где именно хранится информация о сортировке. Объект ДинамическийСписок имеет свойство КомпоновщикНастроек. Внутри него есть несколько уровней настроек, которые и определяют итоговое поведение списка:

  1. Настройки (Settings): базовые настройки, заданные в конфигураторе (иногда удобно использовать отдельную подсистему предопределенных настроек для управления ими).
  2. Пользовательские настройки (UserSettings): то, что пользователь может изменить сам через меню «Настроить список».
  3. Фиксированные настройки (FixedSettings): жесткие ограничения, накладываемые разработчиком, которые пользователь не может изменить или отключить.

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

Способ 1. Простая установка порядка через объект Порядок

Если нам нужно быстро установить сортировку при открытии формы или по нажатию кнопки, мы можем обратиться напрямую к коллекции элементов порядка. Рассмотрим пример, в котором мы очищаем текущую сортировку и устанавливаем свою по полю Дата в убывающем порядке.


// Очищаем существующие элементы порядка, чтобы они не конфликтовали с новыми
Список.Порядок.Элементы.Очистить();

// Добавляем новый элемент порядка
НовыйПорядок = Список.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));

// Настраиваем поле, по которому будет идти сортировка
НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных("Дата");

// Указываем направление сортировки: Возр (по возрастанию) или Убыв (по убыванию)
НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;

// Обязательно включаем использование этого элемента
НовыйПорядок.Использование = Истина;

// Режим отображения позволяет видеть эту настройку в стандартном окне настроек
НовыйПорядок.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Авто;

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

Способ 2. Работа через пользовательские настройки (актуально для 8.3.5 и выше)

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

Давайте проанализируем следующий алгоритм:


// 1. Находим идентификатор пользовательской настройки для порядка
ИдентификаторНастройки = Список.Порядок.ИдентификаторПользовательскойНастройки;

// 2. Ищем сам объект порядка в пользовательских настройках по этому ID
ЭлементПользовательскойНастройки = Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ИдентификаторНастройки);

Если ТипЗнч(ЭлементПользовательскойНастройки) = Тип("ПорядокКомпоновкиДанных") Тогда
    
    // Очищаем старые настройки пользователя
    ЭлементПользовательскойНастройки.Элементы.Очистить();
    
    // Добавляем новое правило сортировки
    НовыйПорядок = ЭлементПользовательскойНастройки.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
    НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных("Номер");
    НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
    НовыйПорядок.Использование = Истина;
    
КонецЕсли;

Этот способ является наиболее корректным с точки зрения UX (User Experience). Пользователь увидит, что список отсортирован, и при необходимости сможет зайти в настройки и изменить их. Если использовать фиксированные настройки, пользователь окажется «заперт» в рамках вашей логики сортировки.

Способ 3. Динамическая сортировка и программное изменение элементов формы

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

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


// Предположим, ТекущийЭлемент - это таблица формы, отображающая наш динамический список
ТекущаяКолонка = Элементы.Список.ТекущийЭлемент;

// Получаем имя поля, связанного с колонкой
ИмяПоля = ТекущаяКолонка.ПутьКДанным; 
// Важно: ПутьКДанным может содержать префикс "Объект." или "Список.", его нужно отсечь
ИмяПоляДляСКД = СтрЗаменить(ИмяПоля, "Список.", "");

Порядок = Список.Порядок;
Порядок.Элементы.Очистить();

НовыйПорядок = Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных(ИмяПоляДляСКД);
НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
НовыйПорядок.Использование = Истина;

Важные нюансы и производительность

Программная установка порядка — это не просто изменение интерфейса, это изменение SQL-запроса, который 1С отправляет к СУБД. Выясним причины, по которым сортировка может замедлять работу системы:

1. Отсутствие индексов. Если вы устанавливаете порядок по реквизиту, который не является индексированным, СУБД придется сканировать всю таблицу. Всегда проверяйте, стоит ли галочка Индексировать у реквизита в конфигураторе, если планируете часто использовать его для сортировки.

2. Сортировка по вычисляемым полям. Если в тексте запроса динамического списка вы используете конструкции ВЫБОР КОГДА... или сложные соединения, и пытаетесь отсортировать результат по этому «виртуальному» полю, индексы использоваться не будут. Это приведет к значительным тормозам на больших объемах данных.

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

4. Иерархия. Помните, что в иерархических списках (деревьях) программная сортировка работает внутри каждого уровня иерархии. То есть сначала сортируются группы верхнего уровня, а затем — элементы внутри каждой группы. Смешать элементы разных групп обычной сортировкой не получится.

Резюме

Для программного управления порядком в ДинамическийСписок мы используем объект ЭлементПорядкаКомпоновкиДанных. Наиболее гибким и правильным подходом является модификация коллекции ПользовательскиеНастройки, так как это не вступает в конфликт с механизмами платформы по сохранению настроек пользователя. Всегда учитывайте наличие индексов в базе данных, чтобы ваше решение работало быстро даже при сотнях тысяч записей.

← На главную