Как программно открыть форму выбора с установленным отбором в управляемом приложении?

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

В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача предоставить пользователю возможность выбора элемента справочника или документа, но с определенными ограничениями — для её решения без программирования есть расширение для настройки условий и отборов в формах 1С. Например, при выборе договора в документе «Реализация» нам необходимо показать только договоры конкретного контрагента, или при подборе номенклатуры скрыть услуги.

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

Постановка задачи и базовый синтаксис

Наша цель — вызвать метод глобального контекста ОткрытьФорму и передать в него такие параметры, которые принимающая форма (форма выбора) сможет интерпретировать как фильтр для своего основного списка.

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

Рассмотрим базовый синтаксис метода:


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

Самый важный момент здесь — правильное формирование структуры ПараметрыФормы. Разберем несколько сценариев, от простых к сложным.

Сценарий 1: Простой отбор на равенство

Если нам необходимо отобрать записи, где определенное поле равно конкретному значению (например, Владелец = Контрагент), мы можем использовать стандартный механизм расширения управляемой формы динамического списка.

Для этого в структуру параметров необходимо добавить ключ Отбор, значением которого будет другая структура, содержащая поля и их значения.

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


// Создаем структуру для самого отбора
// Ключ структуры должен совпадать с именем поля в ДинамическомСписке формы выбора
ОтборДоговоров = Новый Структура;
ОтборДоговоров.Вставить("Владелец", Объект.Контрагент);
ОтборДоговоров.Вставить("ПометкаУдаления", Ложь); // Показывать только не удаленные

// Упаковываем отбор в параметры формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", ОтборДоговоров);

// Открываем форму
// Третий параметр (ЭтаФорма) указывает владельца формы выбора для корректной обработки выбора
ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаВыбора", ПараметрыФормы, ЭтаФорма);

Важные нюансы:

  1. Имена ключей в структуре Отбор (например, Владелец) должны в точности совпадать с именами полей, доступных в динамическом списке открываемой формы. Если в запросе динамического списка поле называется СсылкаНаКлиента, а вы передадите Владелец, отбор не сработает или вызовет ошибку.
  2. Данный метод работает "из коробки" только если основной реквизит открываемой формы имеет тип ДинамическийСписок. В некоторых случаях полезно добавить флажок в динамическом списке для удобства пользователя.

Сценарий 2: Сложные отборы (Списки, Интервалы, Группы условий)

Иногда простого равенства недостаточно. Например, нам нужно показать номенклатуру, входящую в определенный список видов (оператор "В Списке") или исключить определенную группу (оператор "Не Равно"). Если требуется поиск подобно в списке, стандартная структура Отбор, работающая только на равенство, не подойдет.

Для решения этой задачи нам придется обратиться к программной работе с КомпоновщикомНастроек динамического списка. Однако, передать компоновщик через параметры ОткрытьФорму напрямую нельзя. Но есть элегантное решение: использование параметра ФиксированныеНастройки (для жестких отборов, которые пользователь не может снять) или передача произвольных параметров с последующей обработкой в модуле открываемой формы.

Разберем способ с использованием события ПриСозданииНаСервере в форме выбора. Мы передадим наши специфические параметры и обработаем их вручную.

Сначала подготовим параметры в месте вызова:


// На клиенте в месте вызова
СписокВидов = Новый СписокЗначений;
СписокВидов.Добавить(ПредопределенноеЗначение("Справочник.ВидыНоменклатуры.Товар"));
СписокВидов.Добавить(ПредопределенноеЗначение("Справочник.ВидыНоменклатуры.Услуга"));

ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("СписокНужныхВидов", СписокВидов);

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

Теперь перейдем к коду в модуле формы выбора (Справочник.Номенклатура). Нам нужно внедрить обработчик в процедуру ПриСозданииНаСервере:


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

КонецПроцедуры

Таким образом, мы программно модифицируем коллекцию Отбор динамического списка, добавляя туда условия любой сложности, поддерживаемые СКД — аналогичные задачи по кастомизации поведения форм без программирования решает расширение для кастомизации форм и фильтрации списков 1С.

Использование режима выбора групп и элементов

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

Проанализируем, как управлять этим поведением:


ПараметрыФормы = Новый Структура;

// Разрешаем выбор только групп
ПараметрыФормы.Вставить("РежимВыбора", Истина); 
// Внимание: параметр РежимВыбора включает сам режим выбора, 
// но для фильтрации типов (группа/элемент) используются свойства списка или параметр "ВыборГруппИЭлементов"
    
// Более надежный способ для управляемых форм через стандартные параметры:
ПараметрыФормы.Вставить("ВыборГруппИЭлементов", ИспользованиеГруппИЭлементов.Группы);
// Возможные значения: .Группы, .Элементы, .ГруппыИЭлементы

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

Решение проблемы с множественным выбором

Если нам необходимо позволить пользователю выбрать сразу несколько позиций и вернуть их списком, мы должны настроить параметр ЗакрыватьПриВыборе и МножественныйВыбор.

Посмотрим на пример реализации подбора:


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

// Важно: чтобы форма не закрывалась после первого клика
ПараметрыПодбора.Вставить("ЗакрыватьПриВыборе", Ложь); 

// Если мы хотим передать уже выбранные ранее товары, чтобы они подсвечивались или не дублировались
// (это требует поддержки со стороны кода формы выбора, но параметр стандартный)
// ПараметрыПодбора.Вставить("ЗначенияЗаполнения", МассивВыбранныхСсылок); // Зависит от реализации

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

Обработка результата выбора

При использовании ОткрытьФорму, результат выбора (то, что пользователь кликнул) возвращается в процедуру владельца ОбработкаВыбора. Рассмотрим, как правильно перехватить данные.

В модуле формы, из которой мы вызывали открытие:


&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
    
    // Проверяем источник, если открываем разные формы
    // (Хотя лучше использовать ОписаниеОповещения в современных версиях 8.3)
    
    Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда
        // Обработка одиночного выбора
        Сообщить("Выбрали: " + ВыбранноеЗначение);
        
    ИначеЕсли ТипЗнч(ВыбранноеЗначение) = Тип("Массив") Тогда
        // Обработка множественного выбора
        Для Каждого Элемент Из ВыбранноеЗначение Цикл
            Сообщить("Подобрано: " + Элемент);
        КонецЦикла;
    КонецЕсли;

КонецПроцедуры

С выходом версий платформы 8.3.10+ рекомендуется использовать асинхронную модель работы через ОписаниеОповещения. Перепишем наш код в современном стиле:


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

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

Резюме и рекомендации

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

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

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

← На главную