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