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

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

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

Если передать в отбор массив, содержащий сотни или тысячи ссылок, динамический список формирует тяжелый запрос к СУБД с конструкцией ГДЕ Ссылка В (&МассивСсылок). СУБД не может эффективно использовать индексы, что приводит к долгому открытию формы выбора. В то же время замена отбора по ссылке на логическую группу «ИЛИ» по двум проиндексированным реквизитам позволяет форме открываться мгновенно.

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

Выясним причину падения производительности

Проанализируем ситуацию с точки зрения работы СУБД. Когда мы передаем в структуру параметров метод ОткрытьФорму отбор вида:


ПараметрыФормы = Новый Структура("Отбор", Новый Структура("Ссылка", МассивБольшогоОбъема));
ОткрытьФорму("Справочник.Филиалы.ФормаВыбора", ПараметрыФормы,,,,, Оповещение);

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

Если же настроить отбор динамического списка через группу ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли, СУБД задействует существующие индексы по полям, и выборка выполняется мгновенно.

Способ 1. Использование свойства формы ОписаниеОповещенияОЗакрытии

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

Ошибочно полагать, что при использовании ПолучитьФорму невозможно привязать процедуру обратного вызова. У объекта УправляемаяФорма существует встроенное свойство ОписаниеОповещенияОЗакрытии.

Разберем алгоритм реализации на примере:

  1. Создадим объект ОписаниеОповещения и передадим в него необходимые контекстные параметры.
  2. Получим форму выбора через функцию ПолучитьФорму.
  3. Программно добавим группу условий «ИЛИ» и настроим нужные элементы отбора в динамическом списке.
  4. Присвоим свойству формы ОписаниеОповещенияОЗакрытии наш объект оповещения.
  5. Откроем форму методом Открыть().

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


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

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

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

Посмотрим на второй вариант решения, который считается более стандартным для платформы 1С:Предприятие 8.3. Метод ОткрытьФорму принимает параметр ФиксированныеНастройки. Этот параметр позволяет передать готовые настройки компоновки данных со сложными условиями (группы «ИЛИ», «И», «НЕ») напрямую в динамический список.

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

  1. Создаем объект НастройкиКомпоновкиДанных.
  2. Добавляем в коллекцию Отбор.Элементы группу условий ГруппаИли.
  3. Заполняем группу нужными отборами.
  4. Передаем настройки в структуру параметров формы с ключом ФиксированныеНастройки.
  5. Вызываем ОткрытьФорму, передавая ОписаниеОповещения седьмым параметром.

Проанализируем пример кода:


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

Важные особенности и ограничения

При решении задачи обратите внимание на следующие нюансы:

← На главную