При разработке интерфейсов на управляемых формах в платформе «1С:Предприятие 8» программисты часто сталкиваются с ситуацией, когда программно заданная сортировка в динамическом списке ведет себя непредсказуемо. Например, у обычных пользователей список документов упорядочен строго по дате, а у администраторов или пользователей с полными правами строки отображаются в хаотичном порядке. При этом код инициализации списка написан корректно и выполняется без ошибок.
В этой статье мы подробно проанализируем, почему возникает эта проблема, разберем иерархию настроек компоновщика данных динамического списка и рассмотрим два надежных способа программной установки сортировки, которые гарантированно решат задачу.
Рассмотрим стандартную ситуацию. Разработчик в обработчике события ПриСозданииНаСервере пытается настроить порядок динамического списка следующим образом:
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Очищаем существующие элементы порядка
Список.Порядок.Элементы.Очистить();
// Добавляем новую сортировку по дате
НовыйПорядок = Список.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных("Дата");
НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
НовыйПорядок.Использование = Истина;
КонецПроцедуры
Этот код обращается напрямую к свойству Список.Порядок. На самом деле такое обращение эквивалентно изменению базовых (основных) настроек компоновщика данных: Список.КомпоновщикНастроек.Настройки.Порядок. На первый взгляд всё логично, однако на практике порядок может не примениться.
Дело в том, что в платформе «1С:Предприятие 8» реализован механизм автоматического сохранения настроек формы для каждого пользователя. К таким настройкам относятся видимость колонок, их ширина, положение, а также интерактивные отборы и сортировки. В системе действует жесткий приоритет наложения настроек компоновщика данных (от самого низкого к самому высокому):
Список.КомпоновщикНастроек.Настройки в коде.Список.КомпоновщикНастроек.ФиксированныеНастройки. Они имеют наивысший приоритет, и пользователь не может изменить их интерактивно.Что происходит в нашей ситуации: пользователи с ограниченными правами открывают эту форму впервые или просто никогда не меняли порядок колонок интерактивно. Для них отрабатывают настройки по умолчанию (уровень 2), и список сортируется правильно. Пользователь с полными правами (как правило, сам разработчик или администратор) в процессе тестирования или работы кликал по заголовкам колонок, настраивая список под себя. Платформа сохранила эти действия в пользовательские настройки (уровень 3). При повторном открытии формы эти сохраненные настройки накладываются поверх наших программных изменений и полностью затирают сортировку по дате, превращая список в «кашу».
Для решения этой проблемы мы можем использовать два подхода: программное изменение пользовательских настроек на клиенте или использование жестких фиксированных настроек на сервере.
Если мы хотим, чтобы при открытии формы у пользователя всегда устанавливалась правильная сортировка по умолчанию, но при этом у него оставалась возможность кликнуть по любой другой колонке и пересортировать список вручную, нам нужно управлять коллекцией ПользовательскиеНастройки.
Этот метод лучше всего реализовывать в обработчике события ПриОткрытии на стороне клиента. Давайте разберем этот процесс по шагам.
Проанализируем структуру пользовательских настроек. Нам необходимо обойти коллекцию настроек динамического списка, найти среди них элемент с типом ПорядокКомпоновкиДанных, очистить его старые значения и добавить наше правило сортировки по полю Дата.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Получаем коллекцию пользовательских настроек нашего динамического списка
ЭлементыПользовательскихНастроек = Список.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы;
// Перебираем элементы в поисках настроек порядка
Для Каждого Настройка Из ЭлементыПользовательскихНастроек Цикл
Если ТипЗнч(Настройка) = Тип("ПорядокКомпоновкиДанных") Тогда
// Очищаем сохраненную ранее пользовательскую сортировку
Настройка.Элементы.Очистить();
// Добавляем новое правило сортировки по дате
НовыйПорядок = Настройка.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных("Дата");
НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр; // по возрастанию
НовыйПорядок.Использование = Истина;
Прервать; // Элемент порядка найден и изменен, прерываем цикл
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Благодаря этому подходу сохраненные ранее настройки порядка конкретного пользователя очищаются в момент открытия формы, уступая место нашей сортировке. При этом интерактивность списка полностью сохраняется: пользователь может в любой момент кликнуть по другой колонке и упорядочить данные так, как ему удобно в данный момент.
Существуют задачи, когда бизнес-логика требует жесткого соблюдения порядка отображения данных. Например, в журнале регистрации или в ленте оперативных событий документы должны идти строго в хронологическом порядке, и пользователь вообще не должен иметь возможности нарушить эту последовательность.
В этом случае лучшим решением будет использование фиксированных настроек. Фиксированные настройки применяются на сервере, имеют приоритет выше пользовательских настроек и не позволяют пользователю интерактивно изменять заданные параметры.
Рассмотрим, как правильно настроить фиксированный порядок в обработчике ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Пример ограничения периода по правам доступа (из исходного вопроса)
Если НЕ РольДоступна("ПолныеПрава") Тогда
Элементы.Список.Период.Вариант = ВариантСтандартногоПериода.Сегодня;
КонецЕсли;
// Обращаемся к коллекции Фиксированных настроек динамического списка
ФиксированныйПорядок = Список.КомпоновщикНастроек.ФиксированныеНастройки.Порядок;
// Очищаем все жестко заданные правила сортировки
ФиксированныйПорядок.Элементы.Очистить();
// Добавляем обязательную сортировку по дате
НовыйПорядок = ФиксированныйПорядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
НовыйПорядок.Поле = Новый ПолеКомпоновкиДанных("Дата");
НовыйПорядок.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр; // по возрастанию
НовыйПорядок.Использование = Истина;
КонецПроцедуры
При использовании данного способа платформа применит сортировку по дате поверх любых пользовательских настроек. Обратите внимание: пользователь потеряет возможность кликать по заголовкам других колонок формы для изменения порядка отображения строк — сортировка по дате станет железным правилом для этого динамического списка.
Подводя итог, сопоставим оба метода, чтобы вы могли безошибочно выбрать подходящий вариант для решения вашей задачи:
Выбор конкретного метода зависит от требований к юзабилити разрабатываемой формы. Понимание иерархии настроек компоновщика данных 1С позволит вам избегать подобных "загадочных" проблем в будущем и создавать предсказуемые и удобные интерфейсы для пользователей с любым уровнем прав.