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