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