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

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

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

Шаг 1. Создание реквизита формы со списком значений

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

  1. Откроем форму нашей обработки или отчета в конфигураторе.
  2. В правой верхней панели («Реквизиты») нажмем кнопку Добавить реквизит.
  3. Присвоим реквизиту понятное имя, например, СписокКонтрагентов.
  4. В свойстве Тип укажем СписокЗначений.
  5. После выбора типа СписокЗначений в палитре свойств реквизита появится дополнительная вкладка/свойство Тип значения (или в некоторых версиях платформы — вкладка «Объект» -> «Тип значения»). Нам необходимо строго ограничить тип элементов этого списка. Нажмем на кнопку выбора в этом поле и установим тип: СправочникСсылка.Контрагенты. Это нужно для того, чтобы при добавлении строк в список система сразу понимала, элементы какого справочника мы выбираем, и открывала нужную форму выбора.

Шаг 2. Размещение списка на управляемой форме

Теперь созданный реквизит нужно показать пользователю на форме. Перетащим созданный реквизит СписокКонтрагентов из правого окна структуры реквизитов в левое окно элементов формы.

При перетаскивании платформа предложит нам два основных варианта отображения:

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

Рассмотрим оба варианта. Для небольших отчетов чаще выбирают Поле ввода, так как оно занимает минимум места на экране.

Шаг 3. Передача списка значений в запрос

После того как пользователь выбрал нужных контрагентов, нам необходимо передать этот список в запрос для получения данных. Разберем, как это сделать программно в модуле формы или в модуле объекта.

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

Рассмотрим пример кода для обработки нажатия кнопки «Сформировать»:


&НаСервере
Процедура СформироватьОтчетНаСервере()
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ВзаиморасчетыОбороты.Контрагент КАК Контрагент,
        |	ВзаиморасчетыОбороты.СуммаВзаиморасчетовОборот КАК СуммаОборот
        |ИЗ
        |	РегистрНакопления.Взаиморасчеты.Обороты(&НачалоПериода, &КонецПериода, , Контрагент В (&Контрагент)) КАК ВзаиморасчетыОбороты";
    
    // Передаем параметры периода
    Запрос.УстановитьПараметр("НачалоПериода", Объект.НачалоПериода);
    Запрос.УстановитьПараметр("КонецПериода", Объект.КонецПериода);
    
    // Передаем наш список значений напрямую в параметр запроса
    Запрос.УстановитьПараметр("Контрагент", СписокКонтрагентов);
    
    РезультатЗапроса = Запрос.Выполнить();
    // Далее следует код вывода данных в табличный документ...
    
КонецПроцедуры

Оператор В (&Контрагент) в тексте запроса автоматически обработает переданный СписокЗначений и отберет только те записи, контрагенты которых входят в этот список.

Шаг 4. Обработка пустого списка (Важное правило бизнес-логики)

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

Чтобы реализовать такое поведение, применим динамическое формирование текста запроса. Перепишем нашу процедуру:


&НаСервере
Процедура СформироватьОтчетСДинамическимФильтромНаСервере()
    
    Запрос = Новый Запрос;
    
    // Используем базовый текст запроса без жесткого условия в ГДЕ
    ТекстЗапроса = 
        "ВЫБРАТЬ
        |	ВзаиморасчетыОбороты.Контрагент КАК Контрагент,
        |	ВзаиморасчетыОбороты.СуммаВзаиморасчетовОборот КАК СуммаОборот
        |ИЗ
        |	РегистрНакопления.Взаиморасчеты.Обороты(&НачалоПериода, &КонецПериода, , {УсловиеКонтрагенты}) КАК ВзаиморасчетыОбороты";
    
    // Проверяем, заполнен ли список контрагентов
    Если СписокКонтрагентов.Количество() > 0 Тогда
        // Подставляем реальное условие фильтрации
        ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "{УсловиеКонтрагенты}", "Контрагент В (&Контрагент)");
        Запрос.УстановитьПараметр("Контрагент", СписокКонтрагентов);
    Иначе
        // Убираем маркер условия из текста запроса, чтобы отбор не применялся
        ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "{УсловиеКонтрагенты}", "ИСТИНА");
    КонецЕсли;
    
    Запрос.Текст = ТекстЗапроса;
    Запрос.УстановитьПараметр("НачалоПериода", Объект.НачалоПериода);
    Запрос.УстановитьПараметр("КонецПериода", Объект.КонецПериода);
    
    РезультатЗапроса = Запрос.Выполнить();
    // Вывод результатов...
    
КонецПроцедуры

Шаг 5. Повышаем удобство работы: механизм множественного подбора

Стандартный выбор элементов в список значений заставляет пользователя выполнять много лишних действий: открывать окно редактирования списка, нажимать кнопку добавления строки, выбирать одного контрагента из справочника, закрывать форму выбора, снова нажимать кнопку добавления и т.д. Это крайне неудобно, если нужно выбрать, например, 15-20 контрагентов.

Решим эту проблему с помощью реализации механизма множественного подбора — есть конструктор настройки логики форм и управления элементами без программирования. Мы позволим пользователю один раз открыть форму выбора справочника «Контрагенты», выделить в ней нужных клиентов списком (используя клавиши Shift или Ctrl) и перенести их все в наш отчет одним нажатием.

Для этого выполним следующие действия:

  1. Добавим на форму кнопку с именем ПодборКонтрагентов и привяжем к ней команду.
  2. В модуле формы напишем процедуру открытия формы выбора в режиме множественного выбора:

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

Теперь нам нужно обработать результат выбора. Для этого у элемента формы СписокКонтрагентов создадим обработчик события ОбработкаВыбора:


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

Шаг 6. Современные возможности: Множественный выбор в поле ввода (с платформы 8.3.23)

Если вы работаете на современных версиях платформы 1С:Предприятие (начиная с релиза 8.3.23), вам доступен невероятно удобный встроенный функционал — множественный выбор непосредственно внутри одного поля ввода (удобно через расширение для улучшения поиска и подбора в полях ввода 1С). Больше нет необходимости открывать дополнительные модальные списки или размещать на форме таблицы!

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

Чтобы задействовать этот механизм, выполните следующие настройки элемента формы типа «Поле ввода» в конфигураторе:

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

Этот подход значительно улучшает UX (пользовательский опыт), делая интерфейс приложения современным и интуитивно понятным. Для этой задачи есть инструментарий для расширенной фильтрации и отборов в списках.

Шаг 7. Использование Системы компоновки данных (СКД)

В завершение рассмотрим альтернативный вариант. Если вы делаете классический отчет, то писать программный код для создания списков, вывода кнопок подбора и ручной модификации запросов вообще не требуется. Для этого идеально подходит Система компоновки данных (СКД).

Разберем по шагам, как настроить множественный выбор в СКД (поможет набор инструментов разработчика с консолью запросов и СКД):

  1. В схеме компоновки данных на вкладке Параметры найдите параметр Контрагент (или добавьте его вручную).
  2. В колонке Доступен список значений установите галочку.
  3. Перейдите на вкладку Настройки, выберите вкладку Параметры внизу экрана.
  4. Нажмите кнопку Свойства элемента пользовательских настроек (иконка с шестеренкой) для параметра Контрагент.
  5. Поставьте флаг Включать в пользовательские настройки и укажите режим отображения Быстрый доступ.

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

← На главную