Как программно задать параметры выбора для поля в управляемой форме 1С?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

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

Рассмотрим ситуацию, с которой сталкиваются разработчики при работе с типовыми конфигурациями (например, «1С:Бухгалтерия предприятия 3.0»), где используются поля с суффиксом «Интерактивная». Разберем, как правильно установить отбор, избежать ошибок при обращении к реквизитам и почему использование ФиксированныйМассив является обязательным условием.

Постановка задачи и типичная ошибка

Представим, что мы работаем с формой документа (например, «Счет на оплату»). Наша цель — в момент открытия формы или при определенном событии установить фильтр на поле выбора номенклатуры так, чтобы пользователь не видел элементы, у которых установлен признак блокировки (реквизит мБлокировка равен Ложь).

Часто разработчики пытаются установить отбор, интуитивно повторяя иерархию элементов формы. Рассмотрим ошибочный код, который приводит к исключению:


// ОШИБОЧНЫЙ ВАРИАНТ
МассивПараметров = Новый Массив;
// Попытка обратиться через имя элемента формы
МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.ТоварыНоменклатураИнтерактивная.мБлокировка", Ложь));
НовыеПараметры = Новый ФиксированныйМассив(МассивПараметров);
Элементы.ТоварыНоменклатураИнтерактивная.ПараметрыВыбора = НовыеПараметры;

При выполнении этого кода платформа выдаст ошибку: «Недопустимое значение параметра (параметр номер '1')».

Давайте проанализируем, почему это происходит. Конструктор объекта ПараметрВыбора ожидает имя поля, которое существует в открываемой форме выбора (в динамическом списке справочника), а не путь к элементу на текущей форме. Платформа не может найти поле с именем ТоварыНоменклатураИнтерактивная.мБлокировка внутри справочника Номенклатуры.

Правильное решение: использование прямых имен реквизитов

Чтобы отбор сработал корректно, мы должны указывать имя реквизита именно так, как оно задано в объекте метаданных (справочнике), список которого мы открываем. Если мы хотим отфильтровать список номенклатуры по реквизиту мБлокировка, то в параметре отбора нужно указывать путь именно к этому реквизиту. Для автоматизации подобных манипуляций разработчики часто используют готовые решения для программного изменения форм, что ускоряет процесс кодинга — для этого есть конструктор программного изменения управляемых форм.

Рассмотрим правильный вариант кода, который следует размещать в процедуре ПриСозданииНаСервере, если отбор статичен для всего документа, или в обработчиках событий изменения других полей.


// ПРАВИЛЬНЫЙ ВАРИАНТ
// 1. Создаем обычный массив для накопления параметров
МассивПараметровВыбора = Новый Массив;

// 2. Добавляем параметр выбора. 
// "Отбор.ИмяРеквизитаСправочника" — обращаемся напрямую к реквизиту объекта
МассивПараметровВыбора.Добавить(Новый ПараметрВыбора("Отбор.мБлокировка", Ложь));

// 3. Преобразуем массив в ФиксированныйМассив
// Свойство ПараметрыВыбора принимает только коллекцию этого типа
НовыеПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметровВыбора);

// 4. Присваиваем новые параметры элементу формы
Элементы.ТоварыНоменклатураИнтерактивная.ПараметрыВыбора = НовыеПараметрыВыбора;

Обратите внимание на ключевой момент: мы указываем Отбор.мБлокировка. Когда пользователь нажмет кнопку выбора, платформа откроет форму списка номенклатуры, найдет в ней колонку или поле списка, связанное с мБлокировка, и применит к нему значение Ложь.

Особенности работы с полями типа «Интерактивная»

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

Это архитектурный паттерн, используемый разработчиками типовых конфигураций для реализации сложной логики выбора. Обычно в табличной части есть реальный реквизит ссылки (например, Номенклатура), но на форме отображается суррогатный реквизит (...Интерактивная). Это делается для следующих целей:

  1. Выбор разных типов данных: В одной колонке пользователю нужно дать возможность выбрать или Номенклатуру, или Основное средство, или просто ввести строку текста. В таких случаях часто применяется универсальная форма выбора типа.
  2. Обработка ввода: При выборе значения срабатывает программный код, который решает, куда именно записать данные в объекте, или выполняет дополнительные проверки.

Когда мы устанавливаем ПараметрыВыбора для такого поля, мы фактически говорим платформе: «Когда для этого поля будет инициировано открытие списка выбора (каким бы он ни был), попытайся применить этот отбор». Если тип поля составной, и мы установим отбор по реквизиту, который есть только у одного из типов (например, Артикул есть у Номенклатуры, но нет у Строки), то при выборе типа «Строка» отбор будет просто проигнорирован, либо платформа попытается применить его к совместимым типам.

Работа с коллекцией ФиксированныйМассив

Важно понимать техническую особенность свойства ПараметрыВыбора у элементов управляемой формы. Это свойство имеет тип ФиксированныйМассив. Давайте выясним, что это значит для нас как для программистов.

Фиксированный массив — это неизменяемая коллекция. Мы не можем сделать так:


// Так работать НЕ будет, метод Добавить недоступен
Элементы.Поле.ПараметрыВыбора.Добавить(Новый ПараметрВыбора(...));

Именно поэтому алгоритм действий всегда включает три шага:

  1. Создание обычного (изменяемого) объекта Массив.
  2. Наполнение его элементами типа ПараметрВыбора.
  3. Конвертация в ФиксированныйМассив и полная перезапись свойства элемента формы.

Альтернативные способы установки отбора

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

1. Событие «НачалоВыбора»

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


&НаКлиенте
Процедура ТоварыНоменклатураНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // Формируем параметры отбора динамически
    ПараметрыФормы = Новый Структура;
    Отбор = Новый Структура;
    Отбор.Вставить("ВидНоменклатуры", ПредопределенноеЗначение("Справочник.ВидыНоменклатуры.Товар"));
    ПараметрыФормы.Вставить("Отбор", Отбор);
    
    // Открываем форму с параметрами
    СтандартнаяОбработка = Ложь;
    ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);
    
КонецПроцедуры

2. Связи параметров выбора

Самый "чистый" метод, не требующий написания кода — настройка свойства СвязиПараметровВыбора в палитре свойств элемента формы. Мы просто указываем, что реквизит Договор.Владелец должен быть равен реквизиту формы Объект.Контрагент. Также существуют инструменты, позволяющие реализовать добавление реквизитов и элементов формы без сложного кодирования, используя только настройки — например, настройка прав и элементов формы без программирования.

Заключение

Для решения задачи ограничения выбора номенклатуры по булевому флагу (блокировка) наиболее эффективным и производительным способом является установка свойства ПараметрыВыбора при создании формы на сервере. Главное — помнить про правильный путь к данным через Отбор.ИмяРеквизита и необходимость использования промежуточного массива для формирования коллекции.

← На главную