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