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

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

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

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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

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


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

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

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


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

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

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

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

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

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

← На главную