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