Как программно отключить пользовательский отбор на форме выбора в 1С

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

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

Выясним причину возникновения ошибки

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

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

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

Способ 1. Отключение через свойства динамического списка

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

  1. Найдем на форме нужный динамический список (элемент с типом ДинамическийСписок).
  2. В палитре свойств найдем параметр АвтоматическоеСохранениеПользовательскихНастроек.
  3. Установим значение в Ложь.

Это предотвратит сохранение фильтров, которые пользователь наложил в прошлый раз. Однако, как справедливо заметили в теме, это решение не всегда универсально, так как лишает пользователя удобства сохранения других важных настроек (например, группировок или порядка). Поэтому перейдем к более гибким программным методам.

Способ 2. Программный обход коллекции пользовательских настроек

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

Проанализируем пример кода, который решает эту задачу. Мы создадим процедуру, которая будет искать элемент отбора по имени поля и отключать его использование.


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

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

Способ 3. Правильная установка программного отбора через БСП

Рассмотрим ситуацию, когда мы используем функции стандартных библиотек (БСП). Автор темы использовал ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка. Эта функция очень удобна, но она работает с коллекцией Настройки, а не с фиксированными настройками по умолчанию (хотя параметры позволяют это менять). Чтобы программный отбор не конфликтовал с пользовательским, важно понимать, в какой режим мы его устанавливаем. Для быстрого изучения подобных процедур и функций можно использовать справочник по методам БСП с примерами использования.

Посмотрим на правильную последовательность действий при работе с расширениями файлов (как в примере автора):

  1. Сначала удаляем или отключаем существующий пользовательский отбор по полю «Расширение».
  2. Затем устанавливаем новый отбор, при этом желательно перевести его в режим Недоступный для пользователя, чтобы он не мог его случайно изменить или увидеть дубликат в окне настроек.

// Пример корректной установки отбора
СписокРасширений = Новый Массив;
СписокРасширений.Добавить("pdf");
СписокРасширений.Добавить("jpg");

// 1. Сначала чистим пользовательские настройки (используем логику из Способа 2)
ОтключитьПользовательскийОтборНаСервере("Расширение");

// 2. Устанавливаем программный отбор через БСП
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
    Список, 
    "Расширение",
    СписокРасширений,
    ВидСравненияКомпоновкиДанных.ВСписке,
    "Фильтр по типу файлов", // Заголовок
    Истина,                  // Использование
    РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный
);

Нюансы работы с идентификаторами настроек

Выясним еще один важный технический момент. Каждый элемент в основных настройках компоновщика может иметь свойство ИдентификаторПользовательскойНастройки. Если это свойство заполнено (обычно это строка типа "Отбор" или GUID), то данный элемент «связан» с элементом в коллекции ПользовательскиеНастройки.

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

Рекомендации по очистке кэша настроек

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

  1. Зайдите в раздел Администрирование — Настройки пользователей и прав.
  2. Выберите пункт Очистка настроек.
  3. Найдите нужного пользователя и форму выбора, на которой возникает ошибка.
  4. Нажмите «Очистить».

Это позволит вам начать «с чистого листа» и убедиться, что ваш новый программный код корректно управляет фильтрами. Для комплексного анализа и удаления таких данных подойдёт обработка для просмотра и очистки хранилища настроек пользователей.

Подведем итоги

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

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

← На главную