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