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

· 9 мин

Содержание

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

Вторая ловушка — пользовательские настройки. Если параметр выведен в шапку отчёта, значение из быстрых настроек перекроет ваше, установленное в коде. Ниже — как это обойти, плюс работа со списками, составными типами, периодом и внешними наборами данных.

Где живёт параметр СКД и какое значение попадёт в запрос

У параметра в системе компоновки данных три слоя. Путаница между ними — причина большинства вопросов «почему параметр не установился».

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

При формировании платформа берёт итоговые настройки: вариант, поверх него — пользовательские. Метод КомпоновщикНастроек.ПолучитьНастройки() возвращает именно эту сборку.

Ещё один уровень появляется после компиляции — макет компоновки. У него своя коллекция ЗначенияПараметров, и в неё можно вмешаться уже после того, как настройки превращены в макет.

💡 Параметр, который вы написали в тексте запроса как &Склад, конструктор схемы добавляет на вкладку «Параметры» сам. Там же задаются тип, заголовок и флажок «Ограничение использования»: с ним параметр не показывается пользователю в настройках.

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

Метод УстановитьЗначениеПараметра

Самый короткий путь — одна строка в модуле объекта отчёта:

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

Метод находит параметр по имени и сам ставит флаг использования. Минус: если имени в схеме нет (опечатка, параметр переименовали), вы об этом не узнаете — отчёт просто сформируется без нужного значения.

Надёжный вариант через НайтиЗначениеПараметра

Для рабочего кода лучше искать параметр явно и проверять результат:

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

Если Параметр = Неопределено Тогда
    ВызватьИсключение "В схеме отчёта нет параметра «Организация»";
КонецЕсли;

Параметр.Значение      = Организация;
Параметр.Использование = Истина;

Без Использование = Истина значение есть, но в запрос оно не попадёт. Это частая причина пустого отчёта, когда в отладчике значение видно.

Установка в ПриКомпоновкеРезультата

Обработчик ПриКомпоновкеРезультата модуля объекта отчёта выполняется на сервере перед выводом. Здесь удобно подставить «скрытые» параметры, которые пользователь не выбирает: текущую дату, текущего пользователя, константу.

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

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

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

СтандартнаяОбработка здесь не трогаем: платформа сама скомпонует результат с уже изменёнными настройками.

⚠️ Если параметр выведен в пользовательские настройки, изменение Настройки.ПараметрыДанных может не сработать — пользовательское значение сильнее. Решение — в следующем разделе.

Пользовательские настройки, представления и списки значений

Когда параметр стоит в шапке отчёта

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

Процедура УстановитьПараметрСКД(Компоновщик, ИмяПараметра, Значение)

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

    Параметр.Значение      = Значение;
    Параметр.Использование = Истина;

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

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

Процедура меняет оба слоя, поэтому результат не зависит от того, как настроен вариант.

Подписи и представления

Тип значения параметра определяет, что увидит пользователь. Для ссылки платформа покажет её стандартное представление, менять его отдельно не нужно. Управлять подписью можно так:

  • 🏷️ Заголовок параметра — в схеме, колонка «Заголовок». Его видно в шапке отчёта и в блоке параметров при выводе.
  • 📝 ПредставлениеПользовательскойНастройки — свойство элемента настроек. Если заполнено, в быстрых настройках будет ваш текст вместо заголовка.
  • 📋 Доступные значения — в схеме можно задать фиксированный список с подписями. Удобно для параметров-флагов вида «Детализация: по дням / по месяцам».

Список значений вместо одного значения

Чтобы передать несколько складов, в схеме у параметра ставят флажок «Доступен список значений», а в запросе пишут условие через В:

// В тексте запроса набора данных:
// ГДЕ Остатки.Склад В (&Склады)

Склады = Новый СписокЗначений;
Склады.Добавить(Справочники.Склады.НайтиПоКоду("000000001"));
Склады.Добавить(Справочники.Склады.НайтиПоКоду("000000002"));

УстановитьПараметрСКД(КомпоновщикНастроек, "Склады", Склады);

Без флажка «Доступен список значений» пользователь не сможет выбрать несколько элементов в шапке, а при передаче списка кодом условие сработает неочевидно. Флажок лучше ставить явно.

Период, граница и составные типы

Стандартный период

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

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

// Или произвольные даты:
УстановитьПараметрСКД(КомпоновщикНастроек, "Период",
    Новый СтандартныйПериод(НачалоМесяца(ДатаОтчета), КонецМесяца(ДатаОтчета)));

Остатки на дату: Граница

Для виртуальной таблицы Остатки дата 01.10.2026 0:00:00 даёт остаток на начало суток. Если нужен остаток с учётом движений этого дня, передайте границу:

УстановитьПараметрСКД(КомпоновщикНастроек, "ДатаОстатков",
    Новый Граница(КонецДня(ДатаОстатков), ВидГраницы.Включая));

Тип параметра в схеме при этом должен допускать дату — граница передаётся в запрос корректно.

Составной тип

Параметр «Контрагент или физлицо» описывают в схеме составным типом. В коде это выглядит так:

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

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

Если передать значение типа, которого нет в описании параметра, результат отчёта перестаёт быть предсказуемым: вместо ошибки вы можете получить пустую выборку или отбор по пустому значению. Проверка типа до присвоения снимает эту проблему и даёт понятное сообщение.

💡 Если в запросе одно поле хранит ссылки разных типов, условие пишут без приведения: ГДЕ Движения.Получатель = &Получатель. Сравнение ссылки разных типов просто вернёт ложь.

Проверка и защита от пустых параметров

Классическое сообщение при формировании — Не установлено значение параметра "Период". Оно появляется, когда параметр есть в запросе, а значения в итоговых настройках нет или снят флаг использования.

Защиту ставят в двух местах:

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

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

    Если Параметр = Неопределено
       Или Не Параметр.Использование
       Или Не ЗначениеЗаполнено(Параметр.Значение.ДатаНачала) Тогда
        ВызватьИсключение "Укажите период отчёта";
    КонецЕсли;

    Если Параметр.Значение.ДатаНачала > Параметр.Значение.ДатаОкончания Тогда
        ВызватьИсключение "Дата начала периода позже даты окончания";
    КонецЕсли;

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

Проверяйте результат ПолучитьНастройки(), а не КомпоновщикНастроек.Настройки — во втором объекте нет значений, которые пользователь ввёл в шапке.

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

Полная компоновка из кода и внешние наборы данных

Компоновка вручную с параметрами

В обработке или при выводе в таблицу значений отчётную форму не используют, и схему собирают полностью из кода:

Схема = Отчеты.ОстаткиТоваров.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

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

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

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

Процессор = Новый ПроцессорКомпоновкиДанных;
Процессор.Инициализировать(Макет);

Результат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Результат);
ПроцессорВывода.Вывести(Процессор);

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

Параметр в уже скомпилированном макете

Иногда значение известно только после компиляции, или параметр нужно подменить, не трогая настройки. Тогда правят коллекцию макета:

ПараметрМакета = Макет.ЗначенияПараметров.Найти("ДатаОстатков");
Если ПараметрМакета <> Неопределено Тогда
    ПараметрМакета.Значение = Новый Граница(КонецДня(ДатаОстатков), ВидГраницы.Включая);
КонецЕсли;

Делать это нужно до Процессор.Инициализировать(Макет): процессор забирает значения при инициализации.

Набор данных «объект»

Если в схеме есть набор «объект», данные передаются вторым параметром Инициализировать — структурой с таблицами:

ВнешниеНаборы = Новый Структура("ДанныеИзФайла", ТаблицаИзФайла);
Процессор.Инициализировать(Макет, ВнешниеНаборы);

⚠️ Параметры данных на такой набор не действуют: запроса нет, подставлять значение некуда. Отберите строки таблицы заранее или используйте отбор компоновки по полю. В связке «запрос + объект» параметр работает только в запросной части.

Таблицы внешних источников данных, подключённые в конфигурации, используются в обычном наборе-запросе. Параметры к ним передаются так же, как к таблицам базы.

Клиент, сервер и веб-клиент

Компоновка результата выполняется только на сервере. На клиенте — в тонком и в веб-клиенте — нельзя создать ПроцессорКомпоновкиДанных и КомпоновщикМакетаКомпоновкиДанных, а ПолучитьМакет недоступен.

Что можно делать на клиенте в форме отчёта:

  • ✅ менять значения через реквизит формы Отчет.КомпоновщикНастроек — он доступен в клиентском контексте;
  • ✅ вызывать СкомпоноватьРезультат() формы, чтобы перестроить отчёт после изменения;
  • ✅ открывать отчёт с параметрами из другой формы.

Пример открытия с заранее заданными значениями:

ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", Новый Структура("Организация", Организация));
ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
ОткрытьФорму("Отчет.ОстаткиТоваров.Форма", ПараметрыФормы);

Ключи структуры Отбор расширение формы отчёта сопоставляет с параметрами данных и полями отбора по имени.

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

Где ставить значениеКогда подходит
ПриКомпоновкеРезультатаСлужебные параметры, которые пользователь не видит
ПриЗагрузкеПользовательскихНастроекНаСервереЗначение по умолчанию в шапке, которое пользователь может поменять
Параметр формы ОтборОтчёт открывается из документа или другой формы
Макет.ЗначенияПараметровРучная компоновка в обработке, подмена после компиляции

💡 В фоновом режиме формирования (РежимКомпоновкиРезультата.Фоновый) код из ПриКомпоновкеРезультата выполняется в фоновом задании. Не полагайтесь там на данные клиентской формы: всё нужное передавайте через настройки компоновщика.

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

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