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