Как программно открыть форму списка или выбора с отбором в 1С 8.3?

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

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

Постановка задачи и выбор метода

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

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

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


// Общий синтаксис
Результат = ОткрытьФорму(ИмяФормы, Параметры, Владелец, Уникальность, Окно, НавигационнаяСсылка, ОписаниеОповещенияОЗакрытии, РежимОткрытияОкна);

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

Простой отбор на равенство

Разберем по шагам самый простой сценарий: нам нужно открыть форму списка справочника "ДоговорыКонтрагентов" и отобразить только договоры, принадлежащие конкретному контрагенту, ссылка на которого у нас уже есть.

Для этого мы выполним следующие действия:

  1. Создадим структуру для параметров отбора.
  2. Поместим в эту структуру условия фильтрации.
  3. Создадим структуру параметров формы.
  4. Вставим структуру отбора в параметры формы под ключом Отбор.
  5. Вызовем метод открытия формы.

Посмотрим, как это выглядит в коде:


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

// Создаем параметры для самой формы
ПараметрыФормы = Новый Структура;
// ВАЖНО: Имя ключа должно быть строго "Отбор"
ПараметрыФормы.Вставить("Отбор", ЗначениеОтбора);

// Открываем форму списка договоров с примененным фильтром
ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаСписка", ПараметрыФормы);

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

Обратите внимание, что мы можем записать этот код компактнее, используя конструкторы структур:


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

Отбор по нескольким полям

Часто бывает необходимо установить фильтр сразу по нескольким критериям. Например, при выборе номенклатуры мы хотим показать только товары (не услуги) и только те, что находятся в определенной папке. Проанализируем, как это реализовать.

Механизм остается прежним, мы просто добавляем больше ключей в структуру отбора. Все условия в структуре объединяются по логическому "И" (AND). Это значит, что в списке останутся только те записи, которые удовлетворяют всем условиям одновременно.


// Формируем сложный отбор
ОтборСписка = Новый Структура;
ОтборСписка.Вставить("Родитель", ГруппаТоваров); // Ссылка на группу
ОтборСписка.Вставить("ВидНоменклатуры", Перечисления.ВидыНоменклатуры.Товар);

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

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

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

Отбор по списку значений (оператор "В Списке")

Рассмотрим более сложную ситуацию. Что делать, если нам нужно отобрать документы не по одному конкретному складу, а по списку складов? Стандартная структура отбора, которую мы использовали выше, работает по умолчанию как проверка на равенство.

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

Посмотрим на реализацию этого подхода:


// Создаем массив и наполняем его нужными складами
СписокСкладов = Новый Массив;
СписокСкладов.Добавить(СкладМосква);
СписокСкладов.Добавить(СкладКазань);

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

ПараметрыФормы = Новый Структура("Отбор", Отбор);

// Открываем форму списка приходных накладных
ОткрытьФорму("Документ.ПоступлениеТоваровУслуг.ФормаСписка", ПараметрыФормы);

В результате пользователь увидит документы, оформленные либо на СкладМосква, либо на СкладКазань.

Работа с формой выбора и получение результата

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

Разберем полный цикл: открытие формы с отбором и обработка выбранного значения. Предположим, мы выбираем договор для поля ввода на форме.


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

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

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

Особенности использования фиксированных настроек

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

В таких случаях можно передать параметр ФиксированныеНастройки. Это свойство расширения управляемой формы для динамического списка. Чтобы проанализировать, как эти настройки влияют на поведение элементов в реальном времени, можно применить редактор форм в режиме предприятия. Однако, на практике в 95% случаев достаточно использования ключа Отбор, так как он наиболее прост и понятен.

Также стоит упомянуть о параметре ТекущаяСтрока. Если помимо отбора вы хотите сфокусировать курсор на конкретной записи при открытии, используйте этот ключ в параметрах формы.


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

ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаСписка", ПараметрыФормы);

Решение возможных проблем

Проанализируем распространенные ошибки, которые возникают при реализации этой задачи:

  1. Отбор не срабатывает. Убедитесь, что в динамическом списке открываемой формы действительно есть колонка с тем именем, которое вы указываете в структуре. Часто имя реквизита в таблице базы данных (например, СсылкаНаСклад) не совпадает с именем поля в списке на форме (например, Склад).
  2. Ошибка "Недопустимое значение параметра". Это часто случается, если вы передаете в отбор Неопределено или пустую ссылку, а поле не поддерживает пустые значения, или если тип передаваемого значения не совпадает с типом поля (например, передаете строку вместо ссылки).
  3. Не работает отбор в "Произвольном запросе". Если динамический список построен на произвольном запросе, убедитесь, что нужные поля выбраны в секции ВЫБРАТЬ и доступны в настройках списка (в конфигураторе на закладке "Настройки").

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

← На главную