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

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

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

Настройка схемы компоновки данных (конфигуратор)

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

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

Рассмотрим также текст запроса. Хотя СКД обладает встроенным интеллектом и умеет преобразовывать условие ГДЕ ВидЦены = &ВидЦены в работу со списком, правильнее и надежнее использовать оператор В. Проанализируем пример конструкции в запросе:


ВЫБРАТЬ
    Номенклатура.Ссылка,
    ЦеныНоменклатуры.Цена
ИЗ
    Справочник.Номенклатура КАК Номенклатура
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ВидЦены В (&ВидыЦен)) КАК ЦеныНоменклатуры
    ПО Номенклатура.Ссылка = ЦеныНоменклатуры.Номенклатура

Использование конструкции В (&ВидыЦен) гарантирует корректную отработку запроса на уровне СУБД при передаче пустого списка или списка из нескольких элементов.

Программная установка списка значений в параметры

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

Рассмотрим пример кода для установки списка разделов учета или видов цен:


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

// 2. Находим параметр в настройках компоновщика
ПараметрВидыЦен = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ВидыЦен"));

// 3. Устанавливаем значение и включаем использование
Если ПараметрВидыЦен <> Неопределено Тогда
    ПараметрВидыЦен.Значение = СписокВидовЦен;
    ПараметрВидыЦен.Использование = Истина;
КонецЕсли;

В этом примере мы сначала формируем коллекцию, затем ищем параметр по его идентификатору ПараметрКомпоновкиДанных и присваиваем значение. Установка свойства Использование = Истина обязательна, чтобы фильтрация применилась в итоговом запросе.

Проблема приоритета пользовательских настроек

Часто программисты сталкиваются с ситуацией: код написан верно, флаг в СКД стоит, но в отчете все равно используется старое значение или "Равно" вместо "В списке". Проанализируем причину. В системе 1С настройки делятся на "основные" (КомпоновщикНастроек.Настройки) и "пользовательские" (КомпоновщикНастроек.ПользовательскиеНастройки).

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

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


// Ищем идентификатор пользовательской настройки для нашего параметра
ИдентификаторНастройки = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ВидыЦен")).ИдентификаторПользовательскойНастройки;

// Находим элемент в пользовательских настройках
ЭлементПользовательскойНастройки = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ИдентификаторНастройки);

Если ЭлементПользовательскойНастройки <> Неопределено Тогда
    ЭлементПользовательскойНастройки.Значение = СписокВидовЦен;
    ЭлементПользовательскойНастройки.Использование = Истина;
КонецЕсли;

Если вы хотите полностью сбросить изменения, внесенные пользователем, и вернуть отчет к программным установкам, можно воспользоваться методом ЗагрузитьНастройки. Это позволит "очистить" кэш настроек и применить программную логику с нуля:

КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);

Работа с отборами вместо параметров

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


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

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

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

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

// Присваиваем список правому значению отбора
ЭлементОтбора.ПравоеЗначение = СписокЗначенийОтбора;
ЭлементОтбора.Использование = Истина;

Здесь крайне важно установить свойство ВидСравнения. Если оставить его по умолчанию (Равно), система попытается сравнить ссылку на объект со всем объектом СписокЗначений, что приведет к пустому результату или ошибке. Для реализации отборов на основе коллекций значений подойдёт обработка с примером установки отбора СКД по таблице на управляемой форме.

Использование выражений для автоматизации

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

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

Этот метод удобен тем, что настройки хранятся внутри схемы, и отчет будет работать корректно вне зависимости от того, как и откуда он вызывается.

Рекомендации по визуализации

Выясним, как сделать выбор списка удобным для пользователя, если параметр все же отображается на форме. Чтобы вместо выбора одного элемента открывалось окно со списком:

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

← На главную