Почему изменяется отбор динамического списка между событиями ПриСозданииНаСервере и ПриОткрытии?

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

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

Механизмы платформы: почему отбор подменяется неявно

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

  1. Восстановление пользовательских настроек. По умолчанию для управляемых форм включено сохранение пользовательских настроек. Платформа считывает из системного хранилища последние сохраненные настройки конкретного пользователя (включая отборы, порядок, группировки) и применяет их к динамическому списку.
  2. Обработка механизма «Связи параметров выбора» (ChoiceParameterLinks). Если форма открывается для выбора значения из поля ввода другого объекта (например, выбор контактного лица в документе с заполненным партнером), платформа автоматически передает значение отбора через структуру Параметры.Отбор и применяет его к списку.
  3. Разделение коллекций настроек компоновщика. Динамический список оперирует несколькими независимыми уровнями условий: основными отборами (Список.Отбор), фиксированными настройками (Список.ФиксированныеНастройки.Отбор) и пользовательскими настройками (Список.КомпоновщикНастроек.ПользовательскиеНастройки). Отборы, установленные платформой или кодом как фиксированные, не отображаются в стандартном окне пользовательской настройки списка, но жестко ограничивают выборку.
  4. Ограничения прав доступа (RLS и БСП). В типовых конфигурациях (таких как «1С:Управление торговлей») для внешних пользователей или пользователей с ограниченными правами механизмы подсистемы управления доступом накладывают системные отборы в зависимости от назначенных прав и привязанных партнеров/организаций.

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

Если форма открывается с переданными параметрами отбора, но вам требуется полностью контролировать логику инициализации списка и предотвратить неявное наложение условий платформой, отключим стандартную обработку в процедуре ПриСозданииНаСервере:


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

Способ 2. Использование фиксированных настроек динамического списка

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


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

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

Выясним причину, если отбор затирается сохраненной настройкой формы пользователя. Чтобы перехватить момент наложения сохраненных настроек, используем специальное серверное событие формы ПриЗагрузкеПользовательскихНастроекНаСервере:


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

Способ 4. Проверка связей параметров выбора в элементе-источнике

Посмотрим на свойства реквизита в форме, откуда вызывается форма выбора:

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

Способ 5. Сброс кэшированных настроек конкретного пользователя

Если поведение списка вызвано устаревшими некорректными настройками, сохраненными в системной таблице настроек, сбросим их программно с помощью объекта ХранилищеСистемныхНастроек:


// Сброс сохраненных настроек формы для текущего или указанного пользователя
КлючОбъекта = "Справочник.КонтактныеЛицаПартнеров.Форма.ФормаВыбора/Настройки";
ХранилищеСистемныхНастроек.Удалить(КлючОбъекта, "", ИмяПользователя);

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

← На главную