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

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

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

В этом материале мы подробно разберем, как правильно реализовать программное открытие формы с отбором, предотвратить типичные ошибки клиент-серверного взаимодействия и оптимизировать запросы к СУБД.

Типичные ошибки при реализации отбора в управляемых формах

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

  1. Вызов интерактивных методов на сервере: Попытка использовать вызовы вида ПолучитьФормуСписка() или Форма.Открыть() на сервере (например, в процедуре ПриСозданииНаСервере). В режиме управляемого приложения формы создаются и открываются только на клиенте с помощью функции ОткрытьФорму().
  2. Использование устаревшего синтаксиса обычных форм: Обращение к свойствам типа Список.Отбор.Значение или Список.Отбор.ВидСравнения не работает для динамических списков управляемых форм. Управление отборами происходит через коллекцию Список.Отбор.Элементы.
  3. Некорректная группировка в запросе: При попытке получить уникальные регистраторы с помощью конструкций СГРУППИРОВАТЬ ПО добавление уникальных полей (таких как НомерСтроки) сбрасывает группировку и приводит к дублированию записей.
  4. Неизбыточное выполнение запросов: Сбор списка регистраторов отдельным запросом для последующей передачи в отбор с видом сравнения ВСписке создает лишнюю нагрузку на сервер. В большинстве случаев эффективнее устанавливать отбор напрямую по измерениям регистра.

Вариант 1. Открытие формы с передачей структуры отбора (Рекомендуемый)

Если требуется отфильтровать список по измерениям или реквизитам регистра (например, по должности и подразделению), наиболее оптимальный способ — передать структуру Отбор в параметрах функции ОткрытьФорму() на клиенте. Платформа 1С автоматически применит указанные значения к динамическому списку при инициализации формы.

Рассмотрим пример кода, который вызывается в форме документа на клиенте:


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

Вариант 2. Программная установка отбора в обработчике ПриСозданииНаСервере

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

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


&НаКлиенте
Процедура ОткрытьФормуСПараметрами()
	
	ПараметрыОткрытия = Новый Структура;
	ПараметрыОткрытия.Вставить("Подразделение", Элементы.Позиции.ТекущиеДанные.АБ_Подразделение);
	ПараметрыОткрытия.Вставить("Должность", Элементы.Позиции.ТекущиеДанные.АБ_Должность);
	
	ОткрытьФорму("РегистрСведений.АБ_ШтатнаяРасстановкаУУ.ФормаСписка", ПараметрыОткрытия);
	
КонецПроцедуры

Затем в форме списка регистра сведений обрабатываем переданные значения в процедуре ПриСозданииНаСервере:


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

Вариант 3. Передача списка регистраторов через ФиксированныеНастройки

В случаях, когда условие отбора сложная (например, нужно предварительно выбрать уникальные документы-регистраторы запросом), полученный СписокЗначений или массив ссылок можно передать в открываемую форму через параметр ФиксированныеНастройки.

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


&НаСервере
Функция ПолучитьСписокРегистраторов(Подразделение, Должность)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	АБ_ШтатнаяРасстановкаУУ.Регистратор КАК Регистратор
		|ИЗ
		|	РегистрСведений.АБ_ШтатнаяРасстановкаУУ КАК АБ_ШтатнаяРасстановкаУУ
		|ГДЕ
		|	АБ_ШтатнаяРасстановкаУУ.АБ_ПодразделениеУУ = &Подразделение
		|	И АБ_ШтатнаяРасстановкаУУ.АБ_ДолжностьУУ = &Должность";
		
	Запрос.УстановитьПараметр("Подразделение", Подразделение);
	Запрос.УстановитьПараметр("Должность", Должность);
	
	СписокРегистраторов = Новый СписокЗначений;
	Выборка = Запрос.Выполнить().Выбрать();
	
	Пока Выборка.Следующий() Цикл
		СписокРегистраторов.Добавить(Выборка.Регистратор);
	КонецЦикла;
	
	Возврат СписокРегистраторов;
	
КонецФункции

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

Использование параметра ФиксированныеНастройки гарантирует, что установленный отбор будет зафиксирован платформой при открытии и пользователь не сможет случайно сбросить его через стандартную панель поиска, если это не предусмотрено логикой системы.

← На главную