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

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

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

Рассмотрим, почему возникает эта проблема и какими способами можно реализовать отбор по вложенным реквизитам при открытии формы.

Выясним причину ошибки при использовании структуры отбора

Попытка передать составной отбор следующим образом приводит к сбою в работе программы:


Отбор = Новый Структура;
Отбор.Вставить("Сотрудник.Организация", Орг); // Ошибка!
ПараметрыФормы = Новый Структура("Отбор", Отбор);
ОткрытьФорму("Справочник.Водители.ФормаВыбора", ПараметрыФормы);

Ошибка происходит по двум причинам:

  1. Ограничения объекта Структура: ключ структуры в языке 1С обязан быть валидным идентификатором. Точка в имени ключа недопустима, поэтому попытка вставить ключ "Сотрудник.Организация" вызывает исключение «Задано неправильное имя атрибута структуры».
  2. Ограничения стандартного параметра Отбор: стандартный механизм платформы ожидает в структуре параметры, совпадающие с именами колонок верхнего уровня динамического списка. Передать составное поле через точку в этот параметр невозможно.

Проанализируем доступные варианты решения этой задачи.

Способ 1. Фильтрация по массиву ссылок с помощью предварительного запроса

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Водители.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Водители КАК Водители
    |ГДЕ
    |	Водители.Сотрудник.Организация = &Организация";

Запрос.УстановитьПараметр("Организация", ВыбраннаяОрганизация);
Выборка = Запрос.Выполнить().Выбрать();

МассивСсылок = Новый Массив;
Пока Выборка.Следующий() Цикл
    МассивСсылок.Добавить(Выборка.Ссылка);
КонецЦикла;

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

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

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

Способ 2. Использование параметра формы "ФиксированныеНастройки"

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


Настройки = Новый НастройкиКомпоновкиДанных;

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

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

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

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

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

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

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


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

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

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


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

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

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

В тексте запроса динамического списка добавим условие:


ГДЕ
	Водители.Сотрудник.Организация = &Организация

А в модуле формы выбора в событии ПриСозданииНаСервере передадим значение этого параметра:


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

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

← На главную