Как ограничить выбор в поле формы, если значения являются структурами, а не перечислением?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При доработке типовых конфигураций 1С часто возникает задача ограничить список выбора в том или ином поле. Если поле содержит простые данные, например, ссылку на справочник или значение перечисления, задача решается достаточно просто через настройку параметров выбора. Однако, что делать, если элементами списка являются не примитивные типы, а сложные, например, Структура? Попытка передать в параметры выбора простой список значений в таком случае приведет к ошибкам, так как система не получит данные в ожидаемом формате.

Рассмотрим эту проблему на классическом примере из документа "Заказ клиента" — поле "Действия" (внутреннее представление "Вариант обеспечения"). В этом поле пользователь выбирает, что сделать с товаром: отгрузить, зарезервировать, обеспечить и т.д. При выборе значения система ожидает получить структуру с несколькими ключами, которые определяют дальнейшее поведение, например, нужно ли разбивать строку заказа или открывать дополнительную форму. Давайте разберемся, как правильно ограничить такой список, оставив, например, только варианты "К обеспечению" и "Отгрузить".

Анализ проблемы: почему стандартные методы не работают

Основная сложность, описанная в задаче, заключается в том, что элемент выбора — это не просто значение перечисления ВариантыОбеспечения, а структура. Она может выглядеть примерно так:

Когда мы пытаемся ограничить выбор через свойства элемента формы или через ПараметрыВыбора, передавая туда просто список значений перечислений, типовая логика ломается. Она не находит нужных ключей ("РазбитьСтроку" и т.д.) и вызывает ошибки. Создание списка значений, содержащего строки ("К обеспечению", "Отгрузить"), также не решает проблему, так как это просто текст, а не ожидаемая системой структура данных.

Вывод: чтобы все работало корректно, мы должны сформировать и подставить в качестве списка выбора свой собственный список, элементами которого будут точно такие же структуры, какие ожидает система.

Решение: Динамическое формирование списка выбора через событие "НачалоВыбора"

Наиболее правильный и управляемый способ решения этой задачи — использовать событие НачалоВыбора (или ПриНачалеВыбораИзСписка) для поля табличной части. Этот обработчик позволяет перехватить момент, когда пользователь нажимает на кнопку выбора, и подменить стандартный список своим собственным.

Разберем алгоритм по шагам:

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

    Для каждого варианта мы создаем новую структуру и заполняем ее ключами и значениями. Значения булевых флагов ("РазбитьСтроку" и т.д.) нужно выставлять в соответствии с бизнес-логикой. Например, при выборе "Отгрузить" может потребоваться открыть форму выбора склада, а при "К обеспечению" — нет.

  5. Передаем наш список в параметры события. Готовый список присваивается специальному параметру обработчика ДанныеВыбора. Платформа возьмет его и покажет пользователю.

Пример кода для события "НачалоВыбора"

Рассмотрим, как будет выглядеть полный код обработчика для нашей задачи. Предположим, мы хотим оставить только два варианта: "Отгрузить" и "К обеспечению".


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

Таким образом, мы полностью контролируем, что увидит пользователь, и при этом передаем системе данные в том формате, который она ожидает. Вся связанная логика (разбиение строк, открытие форм) будет работать корректно.

Альтернативный вариант: событие "ПриАктивизацииСтроки"

В ходе обсуждения на форуме был предложен вариант с использованием события ПриАктивизацииСтроки табличной части. Логика та же: при переходе на новую строку проверять условия (например, остаток товара) и динамически формировать доступный список вариантов обеспечения для этой конкретной строки, записывая его в свойство элемента формы СписокВыбора.

Этот подход тоже рабочий, но событие НачалоВыбора является более "правильным" и предназначенным именно для таких задач. Оно срабатывает только в тот момент, когда пользователь действительно хочет что-то выбрать, и не выполняет лишних действий при простом перемещении по строкам таблицы.

Итог: не ищите готовую "волшебную" функцию БСП для таких случаев. Правильный путь — это ручное, программное формирование списка выбора с нужной структурой данных в соответствующем обработчике событий формы. Это дает полный контроль над поведением системы и гарантирует сохранение работоспособности типового функционала.

← На главную