Как программно установить отбор в динамическом списке и запретить его изменение пользователем

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

В разработке на платформе 1С:Предприятие 8.3 часто возникает задача не просто отфильтровать данные в динамическом списке при открытии формы, но и сделать так, чтобы пользователь не мог этот отбор изменить, отключить или вовсе увидеть. Работа с КомпоновщикомНастроек в управляемых формах имеет свои нюансы, связанные с многоуровневой структурой настроек. В этой статье мы подробно разберем, как правильно управлять доступностью элементов отбора, разберем различия между типами настроек и научимся «лочить» (блокировать) фильтры.

Понимание структуры компоновщика настроек

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

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

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

Способ 1. Использование режима отображения «Недоступный»

Рассмотрим вариант, когда мы хотим, чтобы пользователь видел установленный отбор (например, по Организации), но не мог его изменить или снять галочку использования. Для этого используется свойство РежимОтображения элемента отбора.

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


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

    // 3. Вместо очистки всей коллекции (что может нарушить связи), 
    // лучше найти существующий элемент или аккуратно управлять составом
    ЭлементыПользовательскогоОтбора.Элементы.Очистить();
    
    // 4. Добавляем новый элемент отбора
    НовыйЭлемент = ЭлементыПользовательскогоОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    НовыйЭлемент.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("Организация");
    НовыйЭлемент.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
    НовыйЭлемент.ПравоеЗначение = ПолучитьОрганизацию(); // Ваша функция получения значения
    НовыйЭлемент.Использование  = Истина;
    
    // 5. Блокируем доступность (замок)
    // Режим Недоступный делает элемент видимым, но запрещает редактирование
    НовыйЭлемент.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;

КонецПроцедуры

Выясним причину, почему это иногда «не работает», как жаловался автор темы. Чаще всего это происходит из-за того, что программист меняет только основные Настройки, а в ПользовательскиеНастройки уже загружены старые значения из хранилища настроек пользователя (те, что сохранились с прошлого сеанса). Пользовательские настройки имеют высший приоритет, поэтому ваши программные изменения в Настройки.Отбор просто игнорируются системой.

Способ 2. Использование Фиксированных настроек

Если ваша задача — гарантированно ограничить данные (например, по разделению прав или специфике текущего режима работы), и при этом вам не нужно показывать этот фильтр пользователю, проанализируем работу с ФиксированныеНастройки. Это наиболее профессиональный и «чистый» способ установки программных ограничений.


// Пример установки "невидимого" и неизменяемого отбора
ФиксированныйОтбор = Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор;

// Очищаем старые фиксированные отборы, если нужно
ФиксированныйОтбор.Элементы.Очистить();

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

Важный нюанс: Отборы, добавленные в ФиксированныеНастройки, суммируются с пользовательскими отборами по логике «И». Это значит, что если вы зафиксировали Организацию "А", а пользователь в фильтрах выберет Организацию "Б", список просто окажется пустым, так как система будет искать записи, где Организация одновременно и "А", и "Б".

Сравнение режимов отображения

Рассмотрим подробнее свойство РежимОтображения. Оно может принимать три значения, которые кардинально меняют поведение интерфейса:

Типичные ошибки при работе с компоновщиком

Проанализируем основные грабли, на которые наступают разработчики:

  1. Очистка через Очистить(): В сообщении 0 автор использует МойОтбор.Элементы.Очистить(). Если этот отбор связан с визуальным элементом на форме (например, быстрым отбором), связь может «отвалиться». Вместо полной очистки лучше искать элемент по имени поля ЛевоеЗначение и обновлять его.
  2. Игнорирование ИдентификатораПользовательскойНастройки: Если вы создаете элемент отбора в КомпоновщикНастроек.Настройки.Отбор, но не присваиваете ему ИдентификаторПользовательскойНастройки, этот элемент никогда не попадет в ПользовательскиеНастройки и не будет виден на форме.
  3. Приоритет загрузки настроек: При открытии формы 1С сначала загружает настройки по умолчанию, а затем накладывает настройки, сохраненные конкретным пользователем. Если вы пишете код в ПриСозданииНаСервере, убедитесь, что вы работаете с актуальным состоянием компоновщика.

Рекомендуемый алгоритм установки «залоченного» отбора

Посмотрим на пример кода, который объединяет лучшие практики: проверку на существование и установку режима недоступности.


&НаСервере
Процедура УстановитьЖесткийОтборНаСервере(ИмяПоля, ЗначениеОтбора)

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

Подводя итог, можно сказать: если вам нужно скрыть данные от пользователя навсегда — используйте ФиксированныеНастройки. Если нужно показать фильтр, но запретить его трогать — используйте РежимОтображения.Недоступный в коллекции ПользовательскиеНастройки. Понимание разницы между этими уровнями позволит вам создавать надежные и предсказуемые интерфейсы в управляемых формах 1С.

← На главную