Как установить отбор в журнале документов по значению из формы выбора справочника?

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

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

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

Типичные ошибки при реализации выбора и отбора

Проанализируем фрагмент кода, вызвавший затруднения:


Значение = ОткрытьФорму("Справочник.МестаХранения.ФормаВыбора").ОткрытьМодально();
Строки = Значение.Элементы.Наименование.ВыделенныеСтроки.значение;
ЭлементОтбора = Реквизит1.Отбор.Элементы.Добавить(Тип("СправочникСсылка.МестаХранения"));

В этом коде допущены три принципиальные ошибки:

  1. Неверная работа с результатом формы выбора. Стандартная форма выбора платформы 1С при закрытии с выбором возвращает не саму форму и не ссылки на элементы управления, а непосредственно ссылку выбранного объекта справочника типа СправочникСсылка.МестаХранения. Обращаться к свойствам вроде Значение.Элементы.Наименование.ВыделенныеСтроки некорректно и бессмысленно.
  2. Попытка фильтровать по наименованию вместо ссылки. Если реквизит или графа журнала типизированы ссылкой, правым значением отбора должна выступать ссылка, а не строковое представление (наименование). Поиск по строке нарушает типизацию и может приводить к ошибкам выборки при наличии элементов с одинаковыми названиями.
  3. Неверный тип при добавлении элемента отбора. Коллекция элементов отбора компоновщика данных ожидает тип элемента схемы компоновки. Нельзя передавать тип ссылки в метод Добавить(). Правильным типом является Тип("ЭлементОтбораКомпоновкиДанных").

Вариант 1. Асинхронное открытие формы выбора (рекомендуемый для 8.3)

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

Разберем по шагам реализацию через обработчик ОбработкаВыбора:

  1. В обработчике команды вызываем форму выбора справочника, передав текущую форму журнала в качестве владельца.
  2. В модуле формы журнала определяем предопределенную процедуру ОбработкаВыбора, куда платформа автоматически передаст результат.
  3. Корректно находим или создаем элемент отбора в свойстве Список.Отбор (где Список — основной реквизит формы типа ДинамическийСписок).

Посмотрим на пример программного кода на стороне формы журнала документов:


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

&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
    Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.МестаХранения") Тогда
        УстановитьОтборПоСкладу(ВыбранноеЗначение);
    КонецЕсли;
КонецПроцедуры

Теперь рассмотрим подробнее процедуру установки отбора. Чтобы элементы отбора не дублировались в коллекции при повторных вызовах, выполним поиск существующего условия:


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

Важный момент: метод Элементы.Список.Обновить() вызывать не обязательно. Динамический список автоматически считывает изменения компоновщика настроек и перерисовывает данные.

Вариант 2. Использование объекта ОписаниеОповещения

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

Посмотрим на пример вызова:


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

&НаКлиенте
Процедура ПослеВыбораСклада(ВыбранноеЗначение, ДополнительныеПараметры) Экспорт
    Если ВыбранноеЗначение <> Неопределено Тогда
        УстановитьОтборПоСкладу(ВыбранноеЗначение);
    КонецЕсли;
КонецПроцедуры

Вариант 3. Модальный вызов (для учебных баз с разрешенной модальностью)

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


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

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

Альтернативное решение без ручного открытия форм

Чтобы упростить интерфейс и не писать код открытия форм справочника, выясним наиболее лаконичный путь реализации быстрого отбора:

  1. Добавим в форму журнала реквизит ОтборСклад с типом СправочникСсылка.МестаХранения.
  2. Разместим реквизит в командной панели или над списком журнала как поле ввода. У этого поля платформа автоматически создаст кнопку выбора и очистки.
  3. В событии поля ПриИзменении вызовем процедуру установки отбора:
    
    &НаКлиенте
    Процедура ОтборСкладПриИзменении(Элемент)
        УстановитьОтборПоСкладу(ОтборСклад);
    КонецПроцедуры
    

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

← На главную