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

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

При разработке нестандартных отчетов или сложных печатных форм, выводимых по собственному макету в ТабличныйДокумент без применения системы компоновки данных (СКД), разработчики часто сталкиваются с необходимостью организовать отбор «В списке» (например, по справочнику Организации). Использование типовых процедур из общих модулей конфигураций (КА, ERP, УТ или БП) часто затруднено из-за различий в коде и зависимостей между общими формами. Разберем универсальные и независимые платформенные способы реализации множественного выбора на управляемой форме и правила работы с таким отбором в запросе.

Способ 1. Использование реквизита формы типа «СписокЗначений» и стандартного диалога

Рассмотрим самый простой и надежный подход, не требующий вызова процедур общих модулей. Платформа 1С:Предприятие предоставляет встроенные элементы управления для работы со списками значений.

Разберем по шагам создание такого отбора:

  1. В реквизитах управляемой формы отчета создадим реквизит ОрганизацииОтбор с типом данных СписокЗначений.
  2. В свойствах реквизита в поле «Тип значения» обязательно укажем ограничение типа: СправочникСсылка.Организации. Это позволит платформе сразу предлагать выбор нужного справочника при добавлении строк.
  3. Перетащим реквизит в элементы формы — будет создано поле ввода. В свойствах элемента формы проверим, чтобы флаг КнопкаВыпадающегоСписка или КнопкаВыбора был активен.

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

Если необходимо программно открыть окно редактирования списка, например, по нажатию отдельной кнопки, используем асинхронный платформенный метод:


&НаКлиенте
Процедура НастроитьОтборПоОрганизациям(Команда)
    
    Оповещение = Новый ОписаниеОповещения("ПослеРедактированияСписка", ЭтотОбъект);
    ПоказатьРедактированиеСпискаЗначений(Оповещение, Отчет.ОрганизацииОтбор, "Выберите организации для отчета");
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеРедактированияСписка(Результат, ДополнительныеПараметры) Экспорт
    
    Если Результат <> Неопределено Тогда
        // Список отредактирован, можно обновить представление или запустить формирование
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Открытие формы выбора справочника в режиме множественного выбора

Если требуется, чтобы пользователь при нажатии на кнопку выбора сразу попадал в список справочника Организации с возможностью отметить несколько строк (через Shift/Ctrl или множественное выделение), настроим перехват события начала выбора.

Разберем реализацию через обработчики события элемента формы:


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

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

Способ 3. Заполнение всех организаций и использование метода «ОтметитьЭлементы()»

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

Для этого сначала заполняем список значений всеми элементами справочника на сервере, а на клиенте вызываем платформенный метод интерактивной расстановки пометок:


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

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

Передача множественного отбора в запрос отчета

Проанализируем частую ошибку: если список отбора не заполнен пользователем (отбор снят), простое условие в запросе вида ГДЕ Организация В (&Организации) вернет пустой результат, так как условие отбора по пустому списку не выполнится ни для одной строки.

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


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

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

← На главную