При программной настройке форм выбора и списков справочников разработчики часто сталкиваются с неочевидным поведением платформы: отбор создается с нужным видом сравнения, но поле со значением отбора остается пустым. Разберем механизм работы отборов в платформе 1С, выясним причину сброса данных и рассмотрим правильные варианты реализации задачи как для обычных, так и для управляемых форм.
Рассмотрим типовой сценарий, в котором возникает ошибка. Разработчик программно получает форму выбора справочника, формирует СписокЗначений с нужными ссылками и пытается передать его в отбор:
СтандартнаяОбработка = Ложь;
ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора(, Элемент);
ФормаВыбора.РежимВыбора = Истина;
СЗ = Новый СписокЗначений;
СЗ.Добавить(Справочники.Контрагенты.НайтиПоКоду("001"));
СЗ.Добавить(Справочники.Контрагенты.НайтиПоКоду("002"));
ФормаВыбора.Отбор.Ссылка.Использование = Истина;
ФормаВыбора.Отбор.Ссылка.Значение = СЗ;
ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке; // Ошибка здесь
ФормаВыбора.Открыть();
При открытии формы отбор по полю Ссылка действительно оказывается включенным и имеет вид сравнения ВСписке, однако список ссылок внутри него пуст.
Причина поведения платформы: в объекте ЭлементОтбора свойство Значение жестко связано со свойством ВидСравнения. По умолчанию элемент отбора имеет вид сравнения Равно. Когда в коде строкой ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке; меняется тип операции сравнения, платформа автоматически переинициализирует свойство Значение типом по умолчанию для выбранного вида сравнения (создается новый пустой СписокЗначений). В результате ранее присвоенный заполненный список значений просто затирается.
Чтобы избежать очистки значений, необходимо соблюдать строгую последовательность инициализации свойств элемента отбора. Разберем по шагам правильный порядок:
ВидСравнения — платформа подготовит внутренний контейнер нужного типа.Значение — передаем подготовленные данные.Использование в значение Истина — активируем отбор.Посмотрим на исправленный рабочий пример кода:
СтандартнаяОбработка = Ложь;
// Получаем форму выбора
ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора(, Элемент);
ФормаВыбора.РежимВыбора = Истина;
// Формируем список значений для фильтрации
СЗ = Новый СписокЗначений;
Ссылка1 = Справочники.Контрагенты.НайтиПоКоду("001");
Если ЗначениеЗаполнено(Ссылка1) Тогда
СЗ.Добавить(Ссылка1);
КонецЕсли;
Ссылка2 = Справочники.Контрагенты.НайтиПоКоду("002");
Если ЗначениеЗаполнено(Ссылка2) Тогда
СЗ.Добавить(Ссылка2);
КонецЕсли;
// Устанавливаем отбор в строгой последовательности
ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
ФормаВыбора.Отбор.Ссылка.Значение = СЗ;
ФормаВыбора.Отбор.Ссылка.Использование = Истина;
// Отключаем иерархию при необходимости
ФормаВыбора.ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Ложь;
ФормаВыбора.Открыть();
При настройке отборов в обычных формах полезно учитывать несколько важных нюансов:
ВидСравнения.ВСписке покажет только сами группы, но не отобразит элементы внутри них. Чтобы в выборку попали дочерние элементы переданных групп, используйте ВидСравнения.ВСпискеПоГруппамИЭлементам или ВидСравнения.ВСпискеПоГруппам.ПриОткрытии самой формы либо предварительно сбрасывать сохраненные настройки.IN (...). Для масштабных выборок эффективнее использовать отборы по дополнительным реквизитам, признакам или группам.В управляемом интерфейсе архитектура работы с формами отличается. Для передачи отбора по списку значений можно использовать параметры открытия формы или настройку динамического списка.
Вариант 1: Передача отбора через параметры формы
Платформа 1С автоматически распознает массив или список значений и применит условие «В списке»:
МассивСсылок = Новый Массив;
МассивСсылок.Добавить(Справочники.Контрагенты.НайтиПоКоду("001"));
МассивСсылок.Добавить(Справочники.Контрагенты.НайтиПоКоду("002"));
ПараметрыФормы = Новый Структура;
ПараметрыОтбора = Новый Структура("Ссылка", МассивСсылок);
ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);
ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", ПараметрыФормы, Элемент);
Вариант 2: Программная настройка Динамического Списка в форме
Если отбор настраивается внутри контекста самой управляемой формы, используется система компоновки данных динамического списка:
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
ЭлементОтбора.ПравоеЗначение = МассивСсылок;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;