Почему очищается значение отбора при программном открытии формы выбора в 1С и как это исправить?

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

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

Анализ проблемы: почему сбрасывается значение отбора

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


СтандартнаяОбработка = Ложь;
ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора(, Элемент);
ФормаВыбора.РежимВыбора = Истина;

СЗ = Новый СписокЗначений;
СЗ.Добавить(Справочники.Контрагенты.НайтиПоКоду("001"));
СЗ.Добавить(Справочники.Контрагенты.НайтиПоКоду("002"));

ФормаВыбора.Отбор.Ссылка.Использование = Истина;
ФормаВыбора.Отбор.Ссылка.Значение = СЗ;
ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке; // Ошибка здесь
ФормаВыбора.Открыть();

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

Причина поведения платформы: в объекте ЭлементОтбора свойство Значение жестко связано со свойством ВидСравнения. По умолчанию элемент отбора имеет вид сравнения Равно. Когда в коде строкой ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке; меняется тип операции сравнения, платформа автоматически переинициализирует свойство Значение типом по умолчанию для выбранного вида сравнения (создается новый пустой СписокЗначений). В результате ранее присвоенный заполненный список значений просто затирается.

Решение проблемы для обычных форм

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

  1. Устанавливаем ВидСравнения — платформа подготовит внутренний контейнер нужного типа.
  2. Заполняем свойство Значение — передаем подготовленные данные.
  3. Устанавливаем свойство Использование в значение Истина — активируем отбор.

Посмотрим на исправленный рабочий пример кода:


СтандартнаяОбработка = Ложь;

// Получаем форму выбора
ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора(, Элемент);
ФормаВыбора.РежимВыбора = Истина;

// Формируем список значений для фильтрации
СЗ = Новый СписокЗначений;
Ссылка1 = Справочники.Контрагенты.НайтиПоКоду("001");
Если ЗначениеЗаполнено(Ссылка1) Тогда
    СЗ.Добавить(Ссылка1);
КонецЕсли;

Ссылка2 = Справочники.Контрагенты.НайтиПоКоду("002");
Если ЗначениеЗаполнено(Ссылка2) Тогда
    СЗ.Добавить(Ссылка2);
КонецЕсли;

// Устанавливаем отбор в строгой последовательности
ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
ФормаВыбора.Отбор.Ссылка.Значение = СЗ;
ФормаВыбора.Отбор.Ссылка.Использование = Истина;

// Отключаем иерархию при необходимости
ФормаВыбора.ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Ложь;

ФормаВыбора.Открыть();

Особенности работы с иерархическими справочниками и ограничения

При настройке отборов в обычных формах полезно учитывать несколько важных нюансов:

  1. Иерархия справочника: если в список отбора передаются группы (папки), стандартный ВидСравнения.ВСписке покажет только сами группы, но не отобразит элементы внутри них. Чтобы в выборку попали дочерние элементы переданных групп, используйте ВидСравнения.ВСпискеПоГруппамИЭлементам или ВидСравнения.ВСпискеПоГруппам.
  2. Пользовательские настройки: если для формы списка сохраняются пользовательские настройки, они могут перезаписать программно установленный отбор при открытии. В таких ситуациях надежнее настраивать отбор непосредственно в обработчике события ПриОткрытии самой формы либо предварительно сбрасывать сохраненные настройки.
  3. Размер списка значений: передача в отбор слишком большого количества элементов (сотни или тысячи) может снизить производительность динамического списка и СУБД, так как платформа формирует SQL-запрос с выражением IN (...). Для масштабных выборок эффективнее использовать отборы по дополнительным реквизитам, признакам или группам.

Реализация аналогичной задачи в управляемых формах

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

Вариант 1: Передача отбора через параметры формы

Платформа 1С автоматически распознает массив или список значений и применит условие «В списке»:


МассивСсылок = Новый Массив;
МассивСсылок.Добавить(Справочники.Контрагенты.НайтиПоКоду("001"));
МассивСсылок.Добавить(Справочники.Контрагенты.НайтиПоКоду("002"));

ПараметрыФормы = Новый Структура;
ПараметрыОтбора = Новый Структура("Ссылка", МассивСсылок);
ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);

ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", ПараметрыФормы, Элемент);

Вариант 2: Программная настройка Динамического Списка в форме

Если отбор настраивается внутри контекста самой управляемой формы, используется система компоновки данных динамического списка:


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