Как открыть форму выбора в 1С с отбором по нескольким значениям?

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

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

Посмотрим на типичный фрагмент кода, который приводит к ошибке:


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

МассивВладельцев = Новый Массив;
МассивВладельцев.Добавить(Объект.Клиент);
Если ЗначениеЗаполнено(Объект.Клиент.Родитель) Тогда
    МассивВладельцев.Добавить(Объект.Клиент.Родитель);
КонецЕсли;

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

ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаВыбора", ОтборНаФорме, ЭтаФорма, , , , Новый ОписаниеОповещения("ДоговорОкончаниеВыбора", ЭтотОбъект), РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

При выполнении такого кода платформа выдает ошибку: «Сравнение несовместимых типов». Выясним причину такого поведения и разберем правильные способы реализации задачи.

Почему возникает ошибка несовместимости типов

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

В нашем примере поле Партнер имеет ссылочный тип СправочникСсылка.Партнеры, а в качестве правого значения передается коллекция — Массив. В результате в запросе динамического списка формируется условие вида Таблица.Партнер = &Партнер, где значением параметра является массив. Это и приводит к исключению времени выполнения из-за несовместимости типов ссылки и массива.

Разберем основные варианты решения этой проблемы.

Способ 1. Использование параметра «ФиксированныеНастройки» (без изменения формы выбора)

Если мы открываем типовую форму выбора и не хотим вносить в нее изменения, наиболее универсальным решением является передача объекта НастройкиКомпоновкиДанных через стандартный параметр ФиксированныеНастройки. Это позволяет явно указать вид сравнения ВСписке.

Разберем реализацию по шагам:

  1. Формируем массив значений для отбора.
  2. Создаем объект НастройкиКомпоновкиДанных.
  3. Добавляем элемент отбора с видом сравнения ВидСравненияКомпоновкиДанных.ВСписке.
  4. Передаем настройки в форму через параметр ФиксированныеНастройки.

Посмотрим на пример кода:


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

МассивВладельцев = Новый Массив;
МассивВладельцев.Добавить(Объект.Клиент);
Если ЗначениеЗаполнено(Объект.Клиент.Родитель) Тогда
    МассивВладельцев.Добавить(Объект.Клиент.Родитель);
КонецЕсли;

// Формируем настройки компоновки данных с отбором по списку
НастройкиКД = Новый НастройкиКомпоновкиДанных;

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

ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ФиксированныеНастройки", НастройкиКД);

ПараметрыОповещения = Новый ОписаниеОповещения("ДоговорОкончаниеВыбора", ЭтотОбъект);

ОткрытьФорму(
    "Справочник.ДоговорыКонтрагентов.ФормаВыбора",
    ПараметрыФормы,
    ЭтаФорма,
    ,
    ,
    ,
    ПараметрыОповещения,
    РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
);

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

Способ 2. Использование вида сравнения по иерархии

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

  1. ВидСравненияКомпоновкиДанных.ВИерархии — если фильтрация выполняется по одному родителю.
  2. ВидСравненияКомпоновкиДанных.ВСпискеПоИерархии — если передан массив групп и элементов, для каждого из которых требуется включить дочерние элементы.

Способ 3. Программная установка отбора в модуле формы выбора

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

Код вызова формы:


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

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

Код в модуле открываемой формы выбора (событие ПриСозданииНаСервере):


Если Параметры.Свойство("ОтборПоПартнерам") И ЗначениеЗаполнено(Параметры.ОтборПоПартнерам) Тогда
    ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
        Список,
        "Партнер",
        Параметры.ОтборПоПартнерам,
        ВидСравненияКомпоновкиДанных.ВСписке
    );
КонецЕсли;

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

← На главную