При разработке на платформе 1С:Предприятие 8.3 часто возникает задача открыть форму списка справочника, документа или регистра сведений, предварительно отфильтровав данные. Это может потребоваться, например, когда из карточки контрагента мы хотим открыть список всех его договоров, или при подборе товаров показать только те, что есть в наличии.
В этой статье мы подробно разберем, как правильно реализовать открытие управляемой формы с отбором, используя метод ОткрытьФорму. Мы проанализируем различные подходы, изучим структуру параметров и рассмотрим нюансы работы с Динамическим списком.
Для начала вспомним, что в управляемом приложении основным методом для вызова форм является глобальный метод ОткрытьФорму. Его синтаксис позволяет передавать параметры, которые форма обрабатывает при создании.
Рассмотрим базовую структуру вызова:
// Общий синтаксис
ОткрытьФорму(ИмяФормы, Параметры, Владелец, ...);
Ключевым моментом здесь является параметр Параметры. Это структура, в которую мы можем поместить специальные ключи, которые платформа 1С распознает автоматически. Одним из таких системных ключей является Отбор.
Самый распространенный и простой способ — передать структуру с именем "Отбор" внутри основной структуры параметров. Платформа 1С устроена таким образом, что если открываемая форма является формой списка или формой выбора и имеет основной реквизит типа ДинамическийСписок, то система попытается автоматически применить переданный отбор к этому списку.
Разберем ситуацию на конкретном примере. Допустим, нам необходимо открыть форму списка справочника ДоговорыКонтрагентов и показать договоры только конкретного контрагента и только те, у которых вид договора — "С покупателем".
Давайте посмотрим, как будет выглядеть код решения:
// Подготовим структуру для самого отбора
// Ключи структуры должны совпадать с именами полей в списке (реквизитов справочника)
ЭлементыОтбора = Новый Структура;
ЭлементыОтбора.Вставить("Владелец", Объект.Контрагент);
ЭлементыОтбора.Вставить("ВидДоговора", Перечисления.ВидыДоговоровКонтрагентов.СПокупателем);
// Упакуем отбор в параметры открытия формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", ЭлементыОтбора);
// Открываем форму
ОткрытьФорму("Справочник.ДоговорыКонтрагентов.Форма.ФормаСписка", ПараметрыФормы);
Обратите внимание на важную деталь: мы создаем вложенную структуру. Внешняя структура ПараметрыФормы обязательно должна содержать ключ "Отбор". Значением этого ключа является другая структура (ЭлементыОтбора), где ключи — это имена полей, по которым мы фильтруем.
Важное замечание: Этот метод работает идеально, если поля, по которым вы делаете отбор, присутствуют в реквизитах самого объекта (справочника или документа). Если же вы хотите сделать отбор по полю, которое есть только в запросе динамического списка (например, остаток товара, вычисляемый в запросе), этот метод может не сработать напрямую, и потребуется более сложная настройка через Компоновщик настроек.
Часто нам нужно не просто открыть список, а открыть форму для выбора значения, чтобы подставить его в поле. Механизм здесь абсолютно идентичен, меняется лишь режим открытия формы.
Рассмотрим пример, где нам нужно предложить пользователю выбрать "Основной склад", но показать в списке только розничные склады.
ОтборСкладов = Новый Структура("ТипСклада", Перечисления.ТипыСкладов.РозничныйМагазин);
ПараметрыВыбора = Новый Структура;
ПараметрыВыбора.Вставить("Отбор", ОтборСкладов);
// Укажем режим выбора, хотя для форм выбора он обычно включен по умолчанию
ПараметрыВыбора.Вставить("РежимВыбора", Истина);
// Передадим "Элемент" в качестве владельца, чтобы выбор сразу попал в нужное поле на форме
ОткрытьФорму("Справочник.Склады.ФормаВыбора", ПараметрыВыбора, Элементы.Склад);
В данном случае, мы передаем третий параметр в функцию ОткрытьФорму — владельца формы. Это позволяет платформе автоматически вернуть выбранное значение и поместить его в поле Элементы.Склад, а также запустить событие ОбработкаВыбора.
Иногда возникают ситуации, когда простой передачи структуры "Отбор" недостаточно. Например, когда нам нужно установить сложный вид сравнения (не "Равно", а "В Списке", "Больше", "Содержит") или когда нужно, чтобы пользователь видел отбор, но не мог его снять.
В таких случаях мы не можем просто передать структуру. Нам придется вмешиваться в настройки Компоновщика настроек динамического списка. Однако, сделать это "снаружи" (до открытия формы) напрямую через параметры ОткрытьФорму не всегда удобно.
Проанализируем альтернативный подход. Мы можем передать в форму произвольные параметры и обработать их в событии ПриСозданииНаСервере открываемой формы. Но есть способ элегантнее, если мы не хотим менять код самой формы списка.
Для сложных отборов (например, "В Списке") через параметры открытия можно использовать следующую хитрость: передать массив значений. Платформа 1С 8.3 достаточно умна, чтобы понять: если в отборе передается массив, значит нужно применить вид сравнения ВСписке.
Посмотрим на пример отбора по списку организаций:
СписокОрганизаций = Новый Массив;
СписокОрганизаций.Добавить(Организация1);
СписокОрганизаций.Добавить(Организация2);
ПараметрыФормы = Новый Структура;
// Платформа автоматически установит отбор "Организация В Списке (...)"
ПараметрыФормы.Вставить("Отбор", Новый Структура("Организация", СписокОрганизаций));
ОткрытьФорму("Справочник.ЗаказыКлиентов.ФормаСписка", ПараметрыФормы);
Разберем частую ошибку новичков. Вы передали отбор, форма открылась, данные отфильтрованы, но пользователь не видит этого отбора в шапке (в панели отборов) и не может его отключить. Или наоборот — вы хотите, чтобы пользователь не мог его отключить.
Здесь важно понимать разницу между параметрами:
Если задача стоит сделать отбор неотключаемым (например, менеджер должен видеть только свои заказы и никак иначе), то правильнее использовать параметр ФиксированныеНастройки. Этот параметр также понимается расширением управляемой формы для динамического списка.
Пример использования фиксированных настроек (более глубокий уровень):
// Создаем дерево настроек компоновки данных
НовыйОтбор = Новый НастройкиКомпоновкиДанных;
// Добавляем элемент отбора
ЭлементОтбора = НовыйОтбор.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Менеджер");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = ТекущийМенеджер;
ЭлементОтбора.Использование = Истина;
// Передаем это как ФиксированныеНастройки
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ФиксированныеНастройки", НовыйОтбор);
ОткрытьФорму("Документ.ЗаказКлиента.ФормаСписка", ПараметрыФормы);
Используя ФиксированныеНастройки, вы гарантируете, что этот отбор применится поверх любых пользовательских настроек и пользователь не сможет его удалить через интерфейс.
Давайте проанализируем, почему код может не работать. Если вы написали код, а список открывается пустым или полным (без отбора), проверьте следующие моменты:
Статус — это перечисление, передавайте именно значение перечисления.ВЫБРАТЬ и доступно для отбора в настройках СКД этого списка.Мы разобрали основные способы программного открытия форм с отбором. Для 90% задач достаточно использовать простую структуру Новый Структура("Отбор", ...). Это быстрый и понятный способ. Однако для более тонкой настройки прав доступа к данным в форме или для сложных логических условий ("ИЛИ", "НЕ") стоит смотреть в сторону ФиксированныеНастройки или программной модификации КомпоновщикНастроек в модуле открываемой формы.
Применяйте эти методы в зависимости от вашей бизнес-задачи: простой отбор для удобства пользователя, фиксированные настройки — для ограничения видимости данных.