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

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

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

Шаг 1. Получение уникальных значений из источника данных

Прежде чем передать данные в отбор, их необходимо извлечь из базы данных. Поскольку категории в регистре могут повторяться, нам нужно получить только уникальные записи. Для этого идеально подходит объект Запрос с использованием конструкции СГРУППИРОВАТЬ ПО или ВЫБРАТЬ РАЗЛИЧНЫЕ. Проанализируем пример кода для получения списка категорий:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ТвойРегистр.КатегорияТовара КАК КатегорияТовара
    |ИЗ
    |   РегистрСведений.ТвойРегистр КАК ТвойРегистр
    |ГРУППИРОВАТЬ ПО
    |   ТвойРегистр.КатегорияТовара";

РезультатЗапроса = Запрос.Выполнить();
СписокКатегорий = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("КатегорияТовара");

В данном фрагменте мы обращаемся к регистру сведений и выбираем измерение КатегорияТовара. Метод ВыгрузитьКолонку() удобен тем, что сразу возвращает массив значений, который мы сможем использовать далее для заполнения списка выбора или самого значения отбора.

Шаг 2. Программное добавление элемента отбора в Компоновщик настроек

Чтобы программно добавить отбор, который будет работать по принципу "в списке", нам нужно обратиться к объекту КомпоновщикНастроек. Рассмотрим, как создать новый элемент отбора и заполнить его нашими данными. Этот код обычно размещается в процедуре ПриСозданииНаСервере формы отчета.


// Добавляем новый элемент отбора
НовыйЭлементОтбора = Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

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

// Устанавливаем вид сравнения "В списке"
НовыйЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;

// Заполняем правое значение массивом, полученным из запроса
НовыйЭлементОтбора.ПравоеЗначение = СписокКатегорий;

// Активируем использование отбора
НовыйЭлементОтбора.Использование = Истина;

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

Шаг 3. Работа с Пользовательскими настройками (UserSettings)

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

Выясним, как сделать отбор доступным для изменения пользователем:

  1. При создании элемента отбора в СКД (в конфигураторе) установите флаг "Включать в пользовательские настройки".
  2. Если вы создаете отбор полностью программно, вам нужно найти соответствующий элемент в коллекции КомпоновщикНастроек.ПользовательскиеНастройки.Элементы, используя ИдентификаторПользовательскойНастройки.

Посмотрим на пример того, как найти уже существующий пользовательский отбор и обновить его список выбора:


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

Шаг 4. Заполнение выпадающего списка выбора на форме

Если на форме отчета выведено конкретное поле ввода для категории товара, и вы хотите, чтобы при нажатии на кнопку выбора открывался список существующих в регистре значений, нужно работать с объектом СписокВыбора элемента формы. Выясним причину, по которой это может не работать: часто разработчики забывают установить свойство РежимВыбораИзСписка в значение Истина.

Разберем пример заполнения списка выбора для элемента формы КатегорияОтбор:


// Очищаем старые значения, чтобы избежать дублирования при переоткрытии формы
Элементы.КатегорияОтбор.СписокВыбора.Очистить();

// Загружаем новые значения из массива
Для Каждого ЗначениеИзРегистра Из СписокКатегорий Цикл
    Элементы.КатегорияОтбор.СписокВыбора.Добавить(ЗначениеИзРегистра);
КонецЦикла;

// Устанавливаем режим выбора именно из этого списка
Элементы.КатегорияОтбор.РежимВыбораИзСписка = Истина;

Шаг 5. Где лучше прописывать этот код?

Место размещения кода крайне важно для стабильной работы отчета. Рассмотрим основные варианты:

Рекомендации по оптимизации

Проанализируем техническую сторону хранения данных. В исходном вопросе упоминается, что КатегорияТовара — это строка длиной 100 символов. Рассмотрим несколько советов по улучшению производительности:

  1. Индексация: Обязательно установите свойство "Индексировать" для измерения КатегорияТовара в конфигураторе. Это значительно ускорит выполнение запроса СГРУППИРОВАТЬ ПО, особенно если в регистре накопятся миллионы записей.
  2. Переход к ссылочному типу: Использование строк в качестве категорий — не лучшая практика. Рекомендуем создать справочник КатегорииТоваров и изменить тип измерения в регистре на СправочникСсылка.КатегорииТоваров. В этом случае 1С автоматически предоставит механизм выбора, и вам не придется писать лишний код для получения списка уникальных значений.
  3. Кэширование: Если список категорий меняется редко, нет смысла выполнять тяжелый запрос при каждом открытии отчета. Можно использовать ПараметрыСеанса или временное хранилище для кэширования списка на время работы пользователя.

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

← На главную