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

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

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

Анализ исходной проблемы и разбор типичных ошибок

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

  1. Переданный в форму выбора отбор игнорируется платформой.
  2. Выбранный в открывшемся окне документ не возвращается обратно в список значений (выбор "улетает в никуда").
  3. При нажатии стандартной кнопки Подбор процедура ПередНачаломДобавления вообще не вызывается, а форма выбора открывается без каких-либо ограничений.

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


Отбор = Новый Структура;
Отбор.Вставить("ХозяйственнаяОперация", ПредопределенноеЗначение("Перечисление.ХозяйственныеОперации. ПередачаВПроизводство"));
Отбор.Вставить("Отправитель", СкладСГД);

ОткрытьФорму("Документ.ДвижениеПродукцииИМатериалов.ФормаВыбора", Отбор);

Проанализируем этот фрагмент и выделим в нем четыре критические ошибки:

Ошибка №1: Отсутствие владельца формы. Это самая главная причина, почему выбранный документ не возвращается в список значений. Метод ОткрытьФорму третьим параметром ожидает ссылку на объект-владелец, который будет принимать результат выбора. Если этот параметр не указан, форма выбора открывается в "автономном" режиме. Она не знает, куда вернуть результат, поэтому при двойном клике по документу ничего не происходит.

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

Ошибка №3: Опечатка в имени предопределенного значения. Обратите внимание на строку "Перечисление.ХозяйственныеОперации. ПередачаВПроизводство". Пробел перед наименованием значения перечисления приведет к ошибке времени выполнения (система не сможет найти этот метаданный объект).

Ошибка №4: Непонимание работы механизма "Подбора". Стандартное действие таблицы Подбор инициирует множественный выбор на уровне платформы. Это действие выполняется в обход клиентского события ПередНачаломДобавления, которое предназначено исключительно для обработки одиночного добавления новой строки (кнопка Добавить или клавиша Insert).

Теперь, когда причины понятны, рассмотрим детальные инструкции по реализации правильного поведения системы.


Способ 1. Настройка связей параметров выбора (рекомендуемый декларативный метод)

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

Предположим, что на нашей управляемой форме есть реквизит СписокДокументов с типом СписокЗначений. На форму он выведен как таблица. В этой таблице отображается колонка Значение. Именно для этого элемента формы мы и зададим настройки фильтрации.

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


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

Преимущества данного способа:


Способ 2. Использование собственной кнопки "Подбор" и программного вызова формы

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

Рассмотрим, как это сделать правильно шаг за шагом:

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

Шаг 2. Создание собственной команды. Создайте команду формы, например, ВыполнитьПодбор, вынесите ее на командную панель таблицы в виде кнопки с заголовком "Подбор...".

Шаг 3. Написание программного кода вызова формы. Нам необходимо правильно сформировать структуру параметров, указать режим множественного выбора и обязательно передать владельца формы. Посмотрим на пример реализации:


&НаКлиенте
Процедура ВыполнитьПодбор(Команда)
    
    // Инициализируем структуру отбора для динамического списка формы выбора
    СтруктураОтбора = Новый Структура;
    СтруктураОтбора.Вставить("ХозяйственнаяОперация", ПредопределенноеЗначение("Перечисление.ХозяйственныеОперации.ПередачаВПроизводство"));
    СтруктураОтбора.Вставить("Отправитель", Объект.СкладСГД);
    
    // Формируем общие параметры открытия формы выбора
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("Отбор", СтруктураОтбора);
    
    // Включаем режим выбора и отключаем закрытие формы после первого клика (режим подбора)
    ПараметрыОткрытия.Vставить("РежимВыбора", Истина);
    ПараметрыОткрытия.Вставить("ЗакрыватьПриВыборе", Ложь);
    
    // Ключевой момент: Владельцем формы выбора должна быть наша таблица на форме!
    ВладелецФормы = Элементы.СписокДокументов;
    
    // Открываем форму выбора документа с нашими параметрами и владельцем
    ОткрытьФорму(
        "Документ.ДвижениеПродукцииИМатериалов.ФормаВыбора", 
        ПараметрыОткрытия, 
        ВладелецФормы
    );
    
КонецПроцедуры

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

Шаг 4. Дополнительная обработка выбранных значений (при необходимости). Если перед добавлением элементов в список вам нужно выполнить какие-то дополнительные проверки (например, исключить дублирование или проверить права доступа), вы можете перехватить событие ОбработкаВыбора у таблицы списка значений:


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

Резюме и рекомендации

Подводя итоги, дадим краткий чек-лист для проверки работоспособности подбора с отбором на управляемых формах:

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