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