Параметры СКД: задаём значения в схеме, в коде и в отборах

· 9 мин

Содержание

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

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

Где хранятся параметры схемы компоновки

Параметры СКД появляются из двух источников. Первый: вы пишете в тексте запроса &Организация или &НачалоПериода, и конструктор схемы сам создаёт одноимённый параметр. Второй: вы добавляете параметр вручную на вкладке «Параметры» схемы, например вычисляемый.

Откройте схему компоновки данных (в конфигураторе или в расширении) и перейдите на вкладку «Параметры». Для каждого параметра доступны колонки:

КолонкаЧто задаёт
ИмяИдентификатор, по нему параметр находят из кода
ЗаголовокПодпись в пользовательских настройках
ТипДата, число, строка, ссылка, СтандартныйПериод, список значений
ЗначениеЗначение по умолчанию
ВыражениеФормула вместо константы
Ограничение доступностиЕсли флажок стоит, пользователь не видит параметр в настройках
Доступные значенияСписок допустимых вариантов для выбора

Если в запросе написано &Период, а тип параметра не задан, отчёт сформируется, но выбрать значение будет нечем. Первым делом проверьте тип.

Параметр с флажком «Ограничение доступности» пользователь не меняет. Значит, поставить его можно только из кода или в самой схеме. Для служебных значений, вроде ссылки на текущего пользователя, это именно то, что нужно.

Параметр «Период» и его границы

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

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

Один параметр на несколько наборов данных

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

Так же работает пакет запросов с временными таблицами: параметр, упомянутый в первом запросе пакета, доступен во всех следующих. Это удобно, когда первый запрос готовит выборку документов за период, а второй объединяет её с остатками.

Есть и обратная сторона. Если в двух наборах &Период означает разное (в одном начало месяца, в другом начало года), одним параметром не обойтись. Заведите два параметра с разными именами, например ПериодМесяца и ПериодГода, и задавайте оба.

Параметры в выражениях полей

Параметр можно использовать не только в запросе, но и в вычисляемых полях схемы. Например, поле Остаток с выражением Сумма(Приход) - &Резерв вычтет резерв из итога. Значение берётся оттуда же, из ПараметрыДанных, поэтому устанавливать его нужно до компоновки, а не после.

Как установить значение параметра в СКД из кода

Все параметры данных лежат в настройках компоновщика: КомпоновщикНастроек.Настройки.ПараметрыДанных. Задать значение проще всего одной строкой:

КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(
    "Организация", ТекущаяОрганизация);

Первый аргумент — имя параметра в схеме, строкой, без амперсанда. Второй — значение того типа, который указан в схеме. Если параметра с таким именем нет, метод ничего не сделает и не выдаст ошибку. Опечатка в имени — самая частая причина «пустого» отчёта.

Когда вызывать код

В отчёте на СКД код установки значений чаще всего пишут в одном из трёх мест:

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

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

Дата и стандартный период

Для обычной даты передают значение типа Дата. Для параметра типа СтандартныйПериод создают объект периода:

Период = Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Период);

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

Включение и выключение параметра

У каждого параметра есть флажок «Использование». Если он снят, значение параметра игнорируется, и в запрос уходит Неопределено. Обычно УстановитьЗначениеПараметра сам включает использование, но если вы получаете элемент вручную, проверьте флажок:

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

Проверка на Неопределено важна: НайтиЗначениеПараметра возвращает Неопределено, если параметра нет в настройках.

Список значений и оператор «В» в запросе

Когда нужно отобрать несколько организаций или несколько видов номенклатуры, в запросе пишут оператор В:

ГДЕ
    Продажи.Организация В (&Организации)

В схеме тип параметра Организации указывают как «Справочник.Организации» с признаком списка (в списке типов параметра можно выбрать список значений). Из кода передают массив или список значений:

МассивОрганизаций = Новый Массив;
МассивОрганизаций.Добавить(Организация1);
МассивОрганизаций.Добавить(Организация2);

КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(
    "Организации", МассивОрганизаций);

Платформа сама превратит массив в список для запроса.

Частая ловушка: в запросе В (&Организации), а в код передали одну ссылку, а не коллекцию. Тогда получите ошибку «Неверное значение параметра» или пустой результат. Даже если организация одна, кладите её в массив.

Ещё одна: пустой массив не означает «все». Условие В () не выберет ничего. Если пользователь ничего не выбрал и вы хотите показать всё, придётся либо выключить использование отбора, либо подставить в запрос условие вида (&ВсеОрганизации ИЛИ Продажи.Организация В (&Организации)) с отдельным булевым параметром.

Иерархия и группы

Для справочников с группами оператор В ИЕРАРХИИ захватывает и выбранную группу, и всё, что внутри. Используется так же, но параметру передают ссылку на группу:

ГДЕ
    Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)

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

Параметр запроса и отбор: в чём разница

Это два разных механизма, и путают их постоянно.

Параметр запросаОтбор в настройках
Где применяетсяВнутри текста запроса, до выполненияПосле выборки, поверх полей набора
Что даётОграничивает данные ещё на уровне СУБДФильтрует то, что уже вернул запрос
СкоростьБыстрее, особенно на виртуальных таблицахМедленнее на больших объёмах
Как задатьПараметрыДанныхОтбор.Элементы

Параметры виртуальных таблиц, например РегистрНакопления.Остатки(&Период, Организация = &Организация), всегда выгоднее отбора. Фильтр срабатывает внутри запроса, и платформа читает меньше записей.

Отбор из кода добавляют так:

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

Если нужен список контрагентов, вид сравнения меняют на ВСписке, а правое значение делают списком значений.

Если в запросе уже есть условие на то же поле через параметр, а потом добавить ещё и отбор, оба сработают одновременно. Результат получится пересечением. Для отладки сначала уберите одно из условий.

Настройка параметров в пользовательском режиме

Пользовательские настройки отчёта дают пользователю менять параметры без программиста. В схеме на вкладке «Настройки» откройте элемент «Параметры» и для нужных параметров поставьте флажок «Включать в пользовательские настройки». Тогда в форме отчёта значение можно выбрать мышью.

Что настроить в схеме, чтобы всё работало:

  • 📌 тип параметра соответствует реальным данным, иначе выбор вернёт пустое поле;
  • 📌 для параметра-периода выбран тип СтандартныйПериод, иначе вместо удобного выбора «квартал, месяц» будет голое поле даты;
  • 📌 в «Доступные значения» занесён список вариантов, если выбор должен быть ограничен;
  • 📌 в разделе настроек параметр помечен нужным режимом отображения, например быстрым доступом.

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

Перед запуском отчёта с параметрами
Выполнено: 0 / 5

Конструктор запроса и консоль: как проверить параметры

Чтобы не гадать, откуда взялась пустая выборка, проверяйте запрос отдельно от схемы.

Конструктор запроса. В схеме компоновки данных запрос набора данных открывается кнопкой «Конструктор запроса». Параметры, которые вы пишете в условиях вкладки «Условия» как &Имя, появятся в схеме автоматически. Если конструктор не подхватил параметр, проверьте, что написали его без пробелов и в тексте запроса, а не в комментарии.

Консоль запросов. Консоль нужна, когда значение параметра подозрительное. Вставьте текст запроса, на панели «Параметры» задайте значения вручную и выполните. Если в консоли данные есть, а в отчёте пусто, виновата настройка СКД: тип, использование, отбор или группировка. Если и в консоли пусто, виноват сам запрос или данные.

Стандартного периода в консоли нет: даты вводят отдельными параметрами, как &НачалоПериода и &КонецПериода. Если в отчёте работает один Период с выражениями, в консоли подставьте границы вручную.

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

Пример: отчёт с периодом, организацией и списком контрагентов

Соберём все приёмы в одном обработчике модуля отчёта. Задача: по умолчанию показать текущий месяц, выбранную организацию и двух контрагентов.

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

    Параметры = КомпоновщикНастроек.Настройки.ПараметрыДанных;

    Период = Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
    Параметры.УстановитьЗначениеПараметра("Период", Период);
    Параметры.УстановитьЗначениеПараметра("Организация", ОсновнаяОрганизация);

    Контрагенты = Новый Массив;
    Контрагенты.Добавить(Контрагент1);
    Контрагенты.Добавить(Контрагент2);
    Параметры.УстановитьЗначениеПараметра("Контрагенты", Контрагенты);

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

Здесь ОсновнаяОрганизация, Контрагент1 и Контрагент2 условные переменные: подставьте свои ссылки, полученные запросом или из реквизитов отчёта.

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

Как задать значение параметра?

Типичные ошибки при установке значений

Диагностика: выберите симптом

Частые вопросы

Можно ли задать значение параметра СКД без кода?
Да. В схеме на вкладке «Параметры» заполните колонку «Значение», а для выбора пользователем включите параметр в пользовательские настройки.
Почему `УстановитьЗначениеПараметра` не выдаёт ошибку, если имя неверное?
Метод ищет параметр по имени и при отсутствии просто завершается. Поэтому опечатка проявляется только как пустой или неотфильтрованный результат.
Как передать в параметр СКД текущую дату?
Передайте ТекущаяДата() в параметр типа «Дата». Для границ дня оберните значения в НачалоДня и КонецДня, чтобы время не потерялось.
Как передать в параметр несколько значений?
Используйте массив или список значений и оператор В в запросе. Одиночную ссылку в такой параметр не отправляйте.
Чем `ПараметрыДанных` отличается от отбора?
Параметр попадает в текст запроса и ограничивает данные на стороне СУБД. Отбор фильтрует уже готовую выборку, поэтому он медленнее на больших объёмах.