Как программно открыть форму выбора с отбором в 1С: подробное руководство

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

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

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

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

Представим ситуацию: пользователь работает в документе и нажимает кнопку для подбора товара. Нам необходимо открыть форму выбора справочника Номенклатура, но показать в ней только товары определенного вида (например, только "Услуги") или товары, находящиеся в наличии на определенном складе.

Для решения этой задачи в управляемых формах используется глобальный метод ОткрытьФорму. Основной нюанс заключается в правильной передаче параметров в эту функцию.

Использование метода ОткрытьФорму

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

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

  1. Создаем структуру параметров формы.
  2. В эту структуру вставляем другую структуру — структуру отбора.
  3. Вызываем метод открытия формы, передавая подготовленные параметры.

Разберем простейший пример кода, который открывает форму выбора номенклатуры с отбором по реквизиту ВидНоменклатуры.


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

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

Сложные виды отборов

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

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


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

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

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

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

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


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

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

Давайте проанализируем этот код. Мы разделили логику на две части: инициацию выбора и обработку результата. Это позволяет интерфейсу оставаться отзывчивым. Параметр РезультатВыбора будет содержать ссылку на выбранный элемент справочника.

Режим множественного выбора

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


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

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

Важно отметить: поведение при множественном выборе может зависеть от того, как настроена сама форма выбора в конфигураторе, и используется ли событие ОбработкаВыбора внутри самой формы. Однако передача параметра МножественныйВыбор принудительно включает этот режим для текущего вызова.

Передача значений в создаваемый элемент

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

Разберем пример: мы открываем список договоров с отбором по контрагенту. Логично, что если пользователь нажмет кнопку "Создать", новый договор должен быть сразу привязан к этому контрагенту.


&НаКлиенте
Процедура ВыбратьДоговор(КонтрагентСсылка)
    
    ПараметрыФормы = Новый Структура;
    
    // 1. Устанавливаем визуальный отбор в списке
    Отбор = Новый Структура("Владелец", КонтрагентСсылка);
    ПараметрыФормы.Вставить("Отбор", Отбор);
    
    // 2. Указываем значения для заполнения нового элемента
    ЗначенияЗаполнения = Новый Структура("Владелец", КонтрагентСсылка);
    ПараметрыФормы.Вставить("ЗначенияЗаполнения", ЗначенияЗаполнения);
    
    ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаВыбора", ПараметрыФормы, ЭтаФорма);
    
КонецПроцедуры

Используя этот подход, мы значительно улучшаем пользовательский опыт (User Experience), избавляя пользователя от рутинного ввода одних и тех же данных и снижая вероятность ошибок.

Особенности работы с владельцем формы

В примерах выше мы использовали ЭтаФорма в качестве третьего параметра метода ОткрытьФорму. Это параметр "Владелец". Указание владельца крайне важно по нескольким причинам:

  1. Блокировка интерфейса: Если форма открывается в режиме блокирования окна владельца (режим диалога), пользователь не сможет вернуться в родительскую форму, пока не закроет выбор.
  2. Связь выбора: Платформа автоматически вызывает событие ОбработкаВыбора в модуле формы-владельца, если мы не передали ОписаниеОповещения.
  3. Закрытие окон: При закрытии формы-владельца автоматически закроются и все подчиненные формы выбора.

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

Подведем итоги

Мы проанализировали механизм программного открытия форм выбора в 1С. Ключевые моменты, которые стоит запомнить:

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

← На главную