Как ограничить список выбора для отбора по складу в отчете СКД?

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

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

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

Особенности работы со стандартными отборами СКД

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

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

Способ 1. Перехват события «НачалоВыбора» в таблице настроек

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

Разберем по шагам реализацию этого механизма:

  1. В редакторе формы отчета найдем элемент, отвечающий за ввод значения отбора (обычно это поле ввода ячейки Значение в таблице настроек).
  2. Создадим для этого элемента обработчик события НачалоВыбора.
  3. В обработчике проверим, какое именно поле компоновки сейчас редактируется, отменим стандартное открытие формы выбора и передадим свой массив значений.

Посмотрим на пример реализации кода на клиенте и сервере:


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

КонецПроцедуры

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

В данном примере форма выбора справочника откроется с фиксированным отбором по переданному массиву ссылок, исключив лишние элементы.

Способ 2. Использование параметров выбора и параметров редактирования в СКД

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

  1. Откроем схему компоновки данных и перейдем на вкладку Наборы данных.
  2. Выберем поле Склад и в колонке Параметры редактирования найдем пункт Параметры выбора.
  3. Зададим необходимые условия (например, отбор по реквизиту ТипСклада или Подразделение).

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

Способ 3. Переопределение параметров выбора в типовых конфигурациях (БСП)

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

Проанализируем пример использования процедуры в модуле отчета:


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

Этот метод является предпочтительным для типовых конфигураций на управляемых формах (ERP, КА, УТ, УНФ), так как полностью сохраняет логику работы стандартного интерфейса отчетов.

Способ 4. Создание отдельного реквизита на форме отчета

Если отчет имеет собственную форму и требуется максимальный контроль над интерфейсом, можно вынести отдельный реквизит формы СкладОтбор с типом СправочникСсылка.Склады или СписокЗначений.

В этом случае разработчик получает полный контроль над событиями НачалоВыбора, АвтоПодбор и Очистка, а перед формированием отчета значение передается в компоновщик настроек:


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

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

← На главную