Параметры СКД: задаём значения в схеме, в коде и в отборах
Содержание
Значение параметра СКД можно задать тремя способами: прямо в схеме компоновки данных (вкладка «Параметры»), в пользовательских настройках отчёта или из кода методом УстановитьЗначениеПараметра у коллекции ПараметрыДанных компоновщика настроек. Первый вариант подходит для константных значений, второй для интерактивной работы, третий для всего, что вычисляется: периодов, выбранных организаций, списков номенклатуры.
Ниже разобрано, где живут параметры, как правильно передать в них дату, список и ссылку, чем параметр запроса отличается от отбора и почему значение иногда «не доходит» до запроса.
Где хранятся параметры схемы компоновки
Параметры СКД появляются из двух источников. Первый: вы пишете в тексте запроса &Организация или &НачалоПериода, и конструктор схемы сам создаёт одноимённый параметр. Второй: вы добавляете параметр вручную на вкладке «Параметры» схемы, например вычисляемый.
Откройте схему компоновки данных (в конфигураторе или в расширении) и перейдите на вкладку «Параметры». Для каждого параметра доступны колонки:
| Колонка | Что задаёт |
|---|---|
| Имя | Идентификатор, по нему параметр находят из кода |
| Заголовок | Подпись в пользовательских настройках |
| Тип | Дата, число, строка, ссылка, СтандартныйПериод, список значений |
| Значение | Значение по умолчанию |
| Выражение | Формула вместо константы |
| Ограничение доступности | Если флажок стоит, пользователь не видит параметр в настройках |
| Доступные значения | Список допустимых вариантов для выбора |
Если в запросе написано &Период, а тип параметра не задан, отчёт сформируется, но выбрать значение будет нечем. Первым делом проверьте тип.
Параметр с флажком «Ограничение доступности» пользователь не меняет. Значит, поставить его можно только из кода или в самой схеме. Для служебных значений, вроде ссылки на текущего пользователя, это именно то, что нужно.
Параметр «Период» и его границы
Для периода обычно заводят параметр типа СтандартныйПериод с именем Период. В запросе используют две границы: &Период.ДатаНачала и &Период.ДатаОкончания. Для этого на вкладке «Параметры» создают два вычисляемых параметра, например НачалоПериода с выражением &Период.ДатаНачала и КонецПериода с выражением &Период.ДатаОкончания. Пользователь выбирает один период, а запрос получает две даты.
Для конца периода обычно оборачивают дату в КонецПериода(&Период.ДатаОкончания, "День"), иначе документы последнего дня с временем после 00:00:00 выпадут из выборки.
Один параметр на несколько наборов данных
Параметры в схеме общие для всей схемы. Если у вас два набора данных и в обоих запросах есть &Организация, значение задаётся один раз, и оба запроса получат его. Отдельный параметр под каждый набор заводить не нужно.
Так же работает пакет запросов с временными таблицами: параметр, упомянутый в первом запросе пакета, доступен во всех следующих. Это удобно, когда первый запрос готовит выборку документов за период, а второй объединяет её с остатками.
Есть и обратная сторона. Если в двух наборах &Период означает разное (в одном начало месяца, в другом начало года), одним параметром не обойтись. Заведите два параметра с разными именами, например ПериодМесяца и ПериодГода, и задавайте оба.
Параметры в выражениях полей
Параметр можно использовать не только в запросе, но и в вычисляемых полях схемы. Например, поле Остаток с выражением Сумма(Приход) - &Резерв вычтет резерв из итога. Значение берётся оттуда же, из ПараметрыДанных, поэтому устанавливать его нужно до компоновки, а не после.
Как установить значение параметра в СКД из кода
Все параметры данных лежат в настройках компоновщика: КомпоновщикНастроек.Настройки.ПараметрыДанных. Задать значение проще всего одной строкой:
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(
"Организация", ТекущаяОрганизация);
Первый аргумент — имя параметра в схеме, строкой, без амперсанда. Второй — значение того типа, который указан в схеме. Если параметра с таким именем нет, метод ничего не сделает и не выдаст ошибку. Опечатка в имени — самая частая причина «пустого» отчёта.
Когда вызывать код
В отчёте на СКД код установки значений чаще всего пишут в одном из трёх мест:
- В обработчике
ПриКомпоновкеРезультатамодуля отчёта. Здесь настройки уже собраны, и значение можно подменить прямо перед компоновкой. - В
ПриСозданииНаСервереформы отчёта, если нужно подставить значения по умолчанию, пока пользователь ещё ничего не нажал. - Перед ручным запуском компоновки в обработке или регламентном задании, где отчёт строится без формы.
Обработчик ПриКомпоновкеРезультата срабатывает при любом запуске отчёта. Значение, заданное там, попадёт и в отчёт, открытый через форму, и в отчёт, который строится из кода без формы.
Дата и стандартный период
Для обычной даты передают значение типа Дата. Для параметра типа СтандартныйПериод создают объект периода:
Период = Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Период);
Если передать в СтандартныйПериод просто дату, платформа выдаст ошибку приведения типа. Конструктор принимает начало и конец.
Включение и выключение параметра
У каждого параметра есть флажок «Использование». Если он снят, значение параметра игнорируется, и в запрос уходит Неопределено. Обычно УстановитьЗначениеПараметра сам включает использование, но если вы получаете элемент вручную, проверьте флажок:
Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("Организация"));
Если Параметр <> Неопределено Тогда
Параметр.Использование = Истина;
Параметр.Значение = ТекущаяОрганизация;
КонецЕсли;
Проверка на Неопределено важна: НайтиЗначениеПараметра возвращает Неопределено, если параметра нет в настройках.
Список значений и оператор «В» в запросе
Когда нужно отобрать несколько организаций или несколько видов номенклатуры, в запросе пишут оператор В:
ГДЕ
Продажи.Организация В (&Организации)
В схеме тип параметра Организации указывают как «Справочник.Организации» с признаком списка (в списке типов параметра можно выбрать список значений). Из кода передают массив или список значений:
МассивОрганизаций = Новый Массив;
МассивОрганизаций.Добавить(Организация1);
МассивОрганизаций.Добавить(Организация2);
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(
"Организации", МассивОрганизаций);
Платформа сама превратит массив в список для запроса.
Частая ловушка: в запросе В (&Организации), а в код передали одну ссылку, а не коллекцию. Тогда получите ошибку «Неверное значение параметра» или пустой результат. Даже если организация одна, кладите её в массив.
Ещё одна: пустой массив не означает «все». Условие В () не выберет ничего. Если пользователь ничего не выбрал и вы хотите показать всё, придётся либо выключить использование отбора, либо подставить в запрос условие вида (&ВсеОрганизации ИЛИ Продажи.Организация В (&Организации)) с отдельным булевым параметром.
Иерархия и группы
Для справочников с группами оператор В ИЕРАРХИИ захватывает и выбранную группу, и всё, что внутри. Используется так же, но параметру передают ссылку на группу:
ГДЕ
Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)
Передавайте одну ссылку, не массив. Если групп несколько, работают оба варианта: массив тоже допустим.
Параметр запроса и отбор: в чём разница
Это два разных механизма, и путают их постоянно.
| Параметр запроса | Отбор в настройках | |
|---|---|---|
| Где применяется | Внутри текста запроса, до выполнения | После выборки, поверх полей набора |
| Что даёт | Ограничивает данные ещё на уровне СУБД | Фильтрует то, что уже вернул запрос |
| Скорость | Быстрее, особенно на виртуальных таблицах | Медленнее на больших объёмах |
| Как задать | ПараметрыДанных | Отбор.Элементы |
Параметры виртуальных таблиц, например РегистрНакопления.Остатки(&Период, Организация = &Организация), всегда выгоднее отбора. Фильтр срабатывает внутри запроса, и платформа читает меньше записей.
Отбор из кода добавляют так:
Отбор = КомпоновщикНастроек.Настройки.Отбор;
Элемент = Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
Элемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Элемент.ПравоеЗначение = Контрагент;
Элемент.Использование = Истина;
Если нужен список контрагентов, вид сравнения меняют на ВСписке, а правое значение делают списком значений.
Если в запросе уже есть условие на то же поле через параметр, а потом добавить ещё и отбор, оба сработают одновременно. Результат получится пересечением. Для отладки сначала уберите одно из условий.
Настройка параметров в пользовательском режиме
Пользовательские настройки отчёта дают пользователю менять параметры без программиста. В схеме на вкладке «Настройки» откройте элемент «Параметры» и для нужных параметров поставьте флажок «Включать в пользовательские настройки». Тогда в форме отчёта значение можно выбрать мышью.
Что настроить в схеме, чтобы всё работало:
- 📌 тип параметра соответствует реальным данным, иначе выбор вернёт пустое поле;
- 📌 для параметра-периода выбран тип
СтандартныйПериод, иначе вместо удобного выбора «квартал, месяц» будет голое поле даты; - 📌 в «Доступные значения» занесён список вариантов, если выбор должен быть ограничен;
- 📌 в разделе настроек параметр помечен нужным режимом отображения, например быстрым доступом.
Значения, которые пользователь выбрал, можно прочитать из кода и подставить в свои вычисления. Они лежат в КомпоновщикНастроек.ПользовательскиеНастройки, а попадают в рабочие настройки при загрузке: КомпоновщикНастроек.ЗагрузитьНастройки(...) и ЗагрузитьПользовательскиеНастройки.
Конструктор запроса и консоль: как проверить параметры
Чтобы не гадать, откуда взялась пустая выборка, проверяйте запрос отдельно от схемы.
Конструктор запроса. В схеме компоновки данных запрос набора данных открывается кнопкой «Конструктор запроса». Параметры, которые вы пишете в условиях вкладки «Условия» как &Имя, появятся в схеме автоматически. Если конструктор не подхватил параметр, проверьте, что написали его без пробелов и в тексте запроса, а не в комментарии.
Консоль запросов. Консоль нужна, когда значение параметра подозрительное. Вставьте текст запроса, на панели «Параметры» задайте значения вручную и выполните. Если в консоли данные есть, а в отчёте пусто, виновата настройка СКД: тип, использование, отбор или группировка. Если и в консоли пусто, виноват сам запрос или данные.
Стандартного периода в консоли нет: даты вводят отдельными параметрами, как &НачалоПериода и &КонецПериода. Если в отчёте работает один Период с выражениями, в консоли подставьте границы вручную.
Для сложных запросов выведите в консоли временную таблицу, а не итог. Сразу видно, на каком шаге данные потерялись.
Пример: отчёт с периодом, организацией и списком контрагентов
Соберём все приёмы в одном обработчике модуля отчёта. Задача: по умолчанию показать текущий месяц, выбранную организацию и двух контрагентов.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
Параметры = КомпоновщикНастроек.Настройки.ПараметрыДанных;
Период = Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
Параметры.УстановитьЗначениеПараметра("Период", Период);
Параметры.УстановитьЗначениеПараметра("Организация", ОсновнаяОрганизация);
Контрагенты = Новый Массив;
Контрагенты.Добавить(Контрагент1);
Контрагенты.Добавить(Контрагент2);
Параметры.УстановитьЗначениеПараметра("Контрагенты", Контрагенты);
КонецПроцедуры
Здесь ОсновнаяОрганизация, Контрагент1 и Контрагент2 условные переменные: подставьте свои ссылки, полученные запросом или из реквизитов отчёта.
Если пользователь уже выбрал свои значения в форме, этот код затрёт их. Чтобы уважать выбор пользователя, перед установкой проверяйте, заполнен ли параметр: найдите его через НайтиЗначениеПараметра и меняйте значение только при пустом.
УстановитьЗначениеПараметра в ПриКомпоновкеРезультата.&Период.Типичные ошибки при установке значений
УстановитьЗначениеПараметра не совпадает с именем в схеме. Метод молча ничего не делает. Скопируйте имя прямо из схемы.СтандартныйПериод нужен объект периода, для ссылочного параметра нужна ссылка нужного справочника, а не строка.УстановитьЗначениеПараметра.ПриКомпоновкеРезультата или после загрузки настроек.Частые вопросы
Можно ли задать значение параметра СКД без кода?
Почему `УстановитьЗначениеПараметра` не выдаёт ошибку, если имя неверное?
Как передать в параметр СКД текущую дату?
ТекущаяДата() в параметр типа «Дата». Для границ дня оберните значения в НачалоДня и КонецДня, чтобы время не потерялось.Как передать в параметр несколько значений?
В в запросе. Одиночную ссылку в такой параметр не отправляйте.