При работе со старыми конфигурациями на обычных формах (например, «1С:Управление торговлей 10.3», «Управление производственным предприятием 1.3» или «Бухгалтерия предприятия 2.0») разработчики часто сталкиваются с необходимостью добавить фильтрацию списка номенклатуры или контрагентов по какому-либо дополнительному реквизиту (например, по производителю или поставщику). В управляемом приложении эта задача решается за пару кликов через настройку динамического списка. Однако на обычных формах стандартный диалог «Отбор и сортировка» накладывает жесткие ограничения.
В этой статье мы подробно разберем, почему простой вывод колонки на форму не решает проблему, и рассмотрим несколько эффективных способов реализации отбора по любому реквизиту справочника на обычных формах.
Рассмотрим стандартное поведение платформы «1С:Предприятие» в режиме обычного приложения. На форме списка или выбора основным источником данных выступает объект типа СправочникСписок, отображаемый через элемент управления ТабличноеПоле.
Когда пользователь открывает окно «Отбор и сортировка», платформа автоматически сканирует метаданные справочника и предлагает поля для фильтрации. Но чтобы реквизит гарантированно появился в этом списке, для него в конфигураторе должно быть включено индексирование. Если реквизит не проиндексирован, платформа скрывает его из стандартного диалога отбора для предотвращения падения производительности СУБД (таких как MS SQL Server или PostgreSQL), поскольку поиск по неиндексированным полям на больших базах данных приводит к сканированию всей таблицы (Table Scan) и блокировкам.
Простое добавление колонки в элемент ТабличноеПоле на форме лишь выводит данные на экран, но не делает поле доступным для стандартного механизма интерактивного отбора.
Если у нас есть доступ к изменению конфигурации (база находится на поддержке с возможностью изменения или используются расширения), это самый быстрый и правильный способ. Он не требует написания кода и делает реквизит доступным во всех стандартных механизмах поиска.
Выполним следующие шаги в конфигураторе:
Номенклатура).Производитель или Поставщик), и откроем его палитру свойств.После выполнения этих действий реквизит автоматически появится в стандартном окне настройки отборов у пользователя.
Рассмотрим ситуацию, когда конфигурация находится на жесткой поддержке, изменять структуру метаданных нельзя или мы не хотим увеличивать размер базы данных новыми индексами. В таком случае мы можем реализовать удобный программный отбор, добавив элемент управления прямо на форму подбора или списка.
Давайте разберем по шагам, как это сделать:
ПолеВвода. Назовем его, например, ОтборПоставщик.СправочникСсылка.Контрагенты).В модуле формы напишем следующий код:
Процедура ОтборПоставщикПриИзменении(Элемент)
// Сбрасываем предыдущее значение отбора, чтобы избежать наложения старых условий
СправочникСписок.Отбор.Поставщик.Установить(, Ложь);
// Проверяем, выбрал ли пользователь значение для фильтрации
Если ЗначениеЗаполнено(ОтборПоставщик) Тогда
// Устанавливаем новое значение отбора и включаем его использование (второй параметр - Истина)
СправочникСписок.Отбор.Поставщик.Установить(ОтборПоставщик, Истина);
КонецЕсли;
КонецПроцедуры
Этот способ крайне эффективен, так как программный отбор через объект Отбор работает в обычных формах даже для неиндексированных реквизитов. Пользователю станет гораздо удобнее работать, ведь нужный фильтр всегда находится перед глазами на форме, и нет необходимости открывать стандартные диалоги настройки.
Иногда требуется более гибкая логика управления отборами. Коллекция Отбор состоит из элементов типа ЭлементОтбора. Вместо использования метода Установить() мы можем настраивать параметры фильтра напрямую. Это позволяет использовать различные виды сравнения, например, поиск по вхождению в список или проверку на неравенство.
Проанализируем пример настройки сложного отбора:
Процедура УстановитьСложныйОтбор()
// Получаем элемент отбора по нужному реквизиту
ЭлементОтбора = СправочникСписок.Отбор.Поставщик;
// Задаем вид сравнения (например, поиск в списке значений)
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
// Формируем список значений для отбора
СписокПоставщиков = Новый СписокЗначений;
СписокПоставщиков.Добавить(Справочники.Контрагенты.НайтиПоКоду("00001"));
СписокПоставщиков.Добавить(Справочники.Контрагенты.НайтиПоКоду("00002"));
// Заполняем значение и активируем отбор
ЭлементОтбора.Значение = СписокПоставщиков;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Часто возникает задача открыть форму выбора номенклатуры из документа (например, из «Поступления товаров и услуг») так, чтобы в ней сразу отображались только товары конкретного поставщика или производителя. Для этого мы можем передать параметры отбора при открытии формы.
Рассмотрим пример кода, который можно разместить в обработчике начала выбора реквизита в документе:
Процедура НоменклатураНачалоВыбора(Элемент, СтандартнаяОбработка)
// Отменяем стандартное открытие формы выбора платформой
СтандартнаяОбработка = Ложь;
// Получаем форму выбора справочника Номенклатура
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора("ФормаВыбора", Элемент, );
// Указываем, что форма открывается в режиме выбора значения
ФормаВыбора.РежимВыбора = Истина;
// Устанавливаем отбор по поставщику, если он заполнилен в документе
Если ЗначениеЗаполнено(ЭтотОбъект.Поставщик) Тогда
ФормаВыбора.СправочникСписок.Отбор.Поставщик.Установить(ЭтотОбъект.Поставщик, Истина);
КонецЕсли;
// Открываем настроенную форму выбора
ФормаВыбора.Открыть();
КонецПроцедуры
Этот подход гарантирует, что пользователь увидит только подходящие позиции номенклатуры, исключая ошибки ручного ввода и ускоряя процесс заполнения табличных частей документов.
Если мы хотим предоставить пользователю возможность не только фильтровать список по нашему новому реквизиту, но и упорядочивать его кликом по шапке колонки табличного поля, нам необходимо программно включить доступность сортировки. Для этого добавим в обработчик события ПриОткрытии формы списка следующую строку:
Процедура ПриОткрытии()
Попытка
// Разрешаем сортировку по реквизиту Поставщик в табличном поле списка
ЭлементыФормы.СправочникСписок.НастройкаПорядка.Поставщик.Доступность = Истина;
Исключение
// Исключение может возникнуть, если тип реквизита не поддерживает сортировку (например, ХранилищеЗначения)
КонецПопытки;
КонецПроцедуры
Таким образом, комбинируя методы индексирования метаданных и программного управления коллекцией Отбор, мы можем решить любую задачу по кастомизации списков в обычных формах 1С, сделав интерфейс программы максимально удобным и отзывчивым для конечного пользователя.