Как сделать быстрый доступ к элементам отбора СКД в форме обработки 1С

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

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

В чем разница между отчетом и обработкой при работе с отборами СКД

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

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

Шаг 1. Инициализация Компоновщика настроек на сервере

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

Создадим на форме реквизит КомпоновщикНастроекФормы с типом КомпоновщикНастроекКомпоновкиДанных и выполним следующую процедуру при создании формы:


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

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

Шаг 2. Динамическое создание элементов отбора на форме

Разберем способ создания элементов управления прямо в коде. Мы обходим все элементы коллекции отбора СКД и для каждого поля создаем горизонтальную группу, содержащую:

  1. Флаг использования отбора (тип ПолеФлажка).
  2. Имя поля / представление (тип ПолеВвода).
  3. Вид сравнения (тип ПолеВвода).
  4. Правое значение / значение отбора (тип ПолеВвода).

Рассмотрим программную реализацию построения таких полей в шапке формы:


&НаСервере
Процедура ДобавлениеЭлементов()

    Индекс = 0;
    
    Для Каждого ЭлементОтбора Из КомпоновщикНастроекФормы.Настройки.Отбор.Элементы Цикл 
        
        ИмяПоля = СокрЛП(ЭлементОтбора.ЛевоеЗначение);
        
        // Создаем контейнер-группу для строки отбора
        Группа = Элементы.Добавить("ГруппаОтбора_" + ИмяПоля, Тип("ГруппаФормы"), Элементы.ГруппаОтбора);
        Группа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
        Группа.Отображение = ОтображениеОбычнойГруппы.Нет;
        Группа.ОтображатьЗаголовок = Ложь;
        Группа.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
        
        // 1. Флаг использования
        ЭлементФлаг = Элементы.Добавить("Использование_" + ИмяПоля, Тип("ПолеФормы"), Группа);
        ЭлементФлаг.Вид = ВидПоляФормы.ПолеФлажка;
        ЭлементФлаг.ПутьКДанным = "КомпоновщикНастроекФормы.Настройки.Отбор[" + Формат(Индекс, "ЧГ=0") + "].Использование";
        ЭлементФлаг.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
        
        // 2. Левое значение (Имя поля)
        ЭлементПоле = Элементы.Добавить("Параметр_" + ИмяПоля, Тип("ПолеФормы"), Группа);
        ЭлементПоле.Вид = ВидПоляФормы.ПолеВвода;
        ЭлементПоле.ПутьКДанным = "КомпоновщикНастроекФормы.Настройки.Отбор[" + Формат(Индекс, "ЧГ=0") + "].ЛевоеЗначение";
        ЭлементПоле.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
        ЭлементПоле.ТолькоПросмотр = Истина;
        
        // 3. Вид сравнения
        ЭлементВид = Элементы.Добавить("ВидСравнения_" + ИмяПоля, Тип("ПолеФормы"), Группа);
        ЭлементВид.Вид = ВидПоляФормы.ПолеВвода;
        ЭлементВид.ПутьКДанным = "КомпоновщикНастроекФормы.Настройки.Отбор[" + Формат(Индекс, "ЧГ=0") + "].ВидСравнения";
        ЭлементВид.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
        
        // 4. Правое значение
        ЭлементЗначение = Элементы.Добавить("Значение_" + ИмяПоля, Тип("ПолеФормы"), Группа);
        ЭлементЗначение.Вид = ВидПоляФормы.ПолеВвода;
        ЭлементЗначение.ПутьКДанным = "КомпоновщикНастроекФормы.Настройки.Отбор[" + Формат(Индекс, "ЧГ=0") + "].ПравоеЗначение";
        ЭлементЗначение.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
        
        Индекс = Индекс + 1;
        
    КонецЦикла;

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

Важный нюанс при связывании `ПутьКДанным`: При обращении к индексам коллекции отбора путь указывется строго через индекс массива, например: "КомпоновщикНастроекФормы.Настройки.Отбор[0].ПравоеЗначение". Если связывать поле с коллекцией ПользовательскиеНастройки.Элементы[0].Значение, вы можете столкнуться с ошибкой «Недопустимое значение», так как в пользовательских настройках хранятся объекты разного типа (параметры, отборы, группы) и свойство Значение есть только у параметров, а у отборов используется ПравоеЗначение.

Шаг 3. Динамическое ограничение списка доступных значений

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

Существует три основных подхода к решению этой задачи:

Способ A. Подмена макета СКД

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


&НаСервере
Процедура ИнициализироватьОтборСЗаменойМакета() 

    ЕстьПравоРасширенногоВыбора = РольДоступна("КорректировкаЗакрытия");
    ИмяМакета = ?(ЕстьПравоРасширенногоВыбора, "Схема_Полная", "Схема_Ограниченная");
        
    Обработка = РеквизитФормыВЗначение("Объект");
    СхемаКомпоновкиДанных = Обработка.ПолучитьМакет(ИмяМакета); 
    
    // Далее стандартная инициализация компоновщика...

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

Способ Б. Программная установка ДоступныхЗначений в объекте СКД

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

Рассмотрим пример кода:


&НаСервере
Процедура НастроитьДоступныеЗначенияВСхеме(СхемаКомпоновкиДанных)

    // 1. Формируем список разрешенных элементов
    СписокРазрешенных = Новый СписокЗначений;
    СписокРазрешенных.Добавить(ПредопределенноеЗначение("Перечисление.Состояния.Согласовано"));
    СписокРазрешенных.Добавить(ПредопределенноеЗначение("Перечисление.Состояния.ВРаботе"));

    // 2. Находим набор данных и нужная поле отбора
    НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.ОсновнойНаборДанных; // Имя вашего набора данных
    ПолеСостояние = НаборДанных.Поля.Найти("Состояние");
    
    Если ПолеСостояние <> Неопределено Тогда
        // Задаем ограниченный список доступных значений
        ПолеСостояние.ДоступныеЗначения = СписокРазрешенных;
        ПолеСостояние.ОграничениеДоступныхЗначений = Истина;
    КонецЕсли;

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

Способ В. Использование ПараметрыВыбора для элемента формы

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


МассивЗначений = Новый Массив;
МассивЗначений.Добавить(ПредопределенноеЗначение("Перечисление.Состояния.Значение1"));

ПараметрОтбора = Новый ПараметрВыбора("Отбор.Ссылка", Новый ФиксированныйМассив(МассивЗначений));

МассивПараметров = Новый Массив;
МассивПараметров.Добавить(ПараметрОтбора);

ЭлементЗначение.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);

Подводя итоги

Мы разглядели особенности работы с быстрым доступом к отборам СКД во внешних обработках 1С. Для создания удобного интерфейса фильтрации достаточно:

  1. Правильно инициализировать реквизит формы типа КомпоновщикНастроекКомпоновкиДанных.
  2. Динамически сгенерировать поля ввода и флаги на управляемой форме, привязав их к путям Настройки.Отбор[Индекс].ПравоеЗначение и Использование.
  3. Управлять доступными значениями списка выбора непосредственно в схеме компоновки данных перед инициализацией компоновщика.
← На главную