Параметры СКД — это именованные значения, которые система компоновки данных подставляет в запрос, в выражения и в шапку отчёта. Через них пользователь выбирает период, контрагента или склад, а программист передаёт в отчёт значения из кода. Разберём, как добавить параметры в СКД, настроить стандартный период и выбор нескольких значений, вывести параметр на форму, задать его из кода и передать при открытии отчёта. Примеры — для платформы 8.3 и управляемых форм, от конфигурации не зависят.
Чаще всего параметр появляется сам. Вы пишете в запросе набора данных &Контрагент или &НачалоПериода, закрываете конструктор, и на закладке «Параметры» схемы появляется строка с таким именем. Тип СКД иногда подбирает сама по контексту запроса, но проверяйте его: если тип пустой, в поле можно будет выбрать значение любого типа.
Параметр можно добавить и вручную, кнопкой «Добавить» на той же закладке. Так делают, когда значение нужно самой схеме: например, «Период» типа «Стандартный период».
Свойств у параметра на закладке «Параметры» много, чаще всего нужны эти:
| Свойство | Для чего нужно |
|---|---|
| Заголовок | Текст, который пользователь увидит в настройках вместо технического имени. |
| Тип | Тип значения и квалификаторы: для даты — состав («Дата» или «Дата и время»), для строки — длина. |
| Значение | Значение по умолчанию. |
| Выражение | Формула на языке выражений СКД: значение вычисляется при формировании. |
| Ограничение доступности | Прячет параметр от пользователя. Ставят на служебные параметры, которые заполняет выражение. |
| Доступен список значений | Разрешает выбрать несколько значений сразу. |
| Доступные значения | Ограничивает выбор заранее заданным перечнем. |
| Использование | «Авто» или «Всегда». При «Всегда» флажка использования в настройках нет: параметр применяется при каждом формировании. |
| Запрещать незаполненные значения | Отчёт не сформируется с пустым значением. Удобно для обязательной организации или периода. |
| Включать в доступные поля | Значение параметра можно вывести в отчёт как поле из группы «Параметры данных». |
Необязательное условие в запросе СКД пишут в фигурных скобках: если параметр в настройках не используется, система компоновки выбросит условие из запроса без ошибки. Имена регистра и полей ниже условные:
ВЫБРАТЬ
Продажи.Контрагент КАК Контрагент,
Продажи.Номенклатура КАК Номенклатура,
Продажи.КоличествоОборот КАК Количество,
Продажи.СуммаОборот КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи
{ГДЕ
Продажи.Контрагент В (&Контрагенты)}
Два поля «Дата начала» и «Дата окончания» неудобны: нельзя одним кликом выбрать «Этот квартал», а у даты без времени легко потерять последний день. Удобнее один параметр стандартного периода, из которого вычисляются даты для запроса.
| Имя | Тип | Выражение | Ограничение доступности |
|---|---|---|---|
| Период | Стандартный период | — | нет |
| НачалоПериода | Дата (дата и время) | &Период.ДатаНачала | да |
| КонецПериода | Дата (дата и время) | &Период.ДатаОкончания | да |
Пользователь видит только «Период» и выбирает интервал в привычном диалоге. Даты для запроса считаются выражениями и спрятаны флагом «Ограничение доступности». Задайте «Периоду» значение по умолчанию, например «Этот месяц», и отчёт будет открываться с осмысленным интервалом.
Почему «дата и время», а не просто «дата»: дата окончания стандартного периода приходит с временем конца дня. Если у параметра КонецПериода состав «Дата», время отрежется и в запрос уйдёт полночь последнего дня: пользователь выбирает 30-е число, а продажи за 30-е в отчёт не попадают.
Это два разных свойства параметра, и их часто путают.
СписокЗначений, поэтому в запросе нужно условие В (&Контрагенты), а не =. Конструкция В работает и с одним значением.Пример переключателя: параметр Показатель типа «Строка» с доступными значениями «Сумма» и «Количество». В запросе он выбирает, какую колонку считать:
ВЫБОР
КОГДА &Показатель = "Сумма"
ТОГДА Продажи.СуммаОборот
ИНАЧЕ Продажи.КоличествоОборот
КОНЕЦ КАК Значение
Параметр стоит вне фигурных скобок, поэтому СКД обязана передать его в запрос. Задайте параметру Показатель значение по умолчанию «Сумма» и установите «Использование» = «Всегда»: без значения отчёт упадёт с ошибкой «Не установлено значение параметра». Флажок «Запрещать незаполненные значения» не даст сформировать отчёт, если пользователь очистит поле.
Чтобы параметр был виден над табличным документом, а не только в окне «Настройки…», его выводят в пользовательские настройки:
Стандартная форма отчёта покажет такие поля сама. В собственной форме период часто делают обычным реквизитом и связывают с настройками кодом — пример ниже.
Параметры отчёта на СКД хранятся в компоновщике настроек в двух слоях: Настройки (вариант отчёта) и ПользовательскиеНастройки (то, что поменял пользователь). При формировании они сливаются, и для параметров, выведенных в пользовательские настройки, побеждает пользовательское значение. Поэтому привычная строка Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", Период) на форме отчёта «не работает»: значение записалось, но его перекрыли быстрые настройки. Надёжнее писать в оба слоя:
// Модуль формы отчёта (управляемая форма, платформа 8.3).
// На форме: основной реквизит «Отчет» и реквизит «Период» (тип СтандартныйПериод),
// выведенный полем ввода. В схеме компоновки есть параметр «Период».
// Обработчики событий формы назначьте в палитре свойств формы.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ОбновитьПолеПериода();
КонецПроцедуры
// Пользователь выбрал другой вариант отчёта.
&НаСервере
Процедура ПриЗагрузкеВариантаНаСервере(Настройки)
ОбновитьПолеПериода();
КонецПроцедуры
// Загружены сохранённые пользовательские настройки.
&НаСервере
Процедура ПриЗагрузкеПользовательскихНастроекНаСервере(Настройки)
ОбновитьПолеПериода();
КонецПроцедуры
&НаКлиенте
Процедура ПериодПриИзменении(Элемент)
Если Не УстановитьПараметрСКД(Отчет.КомпоновщикНастроек, "Период", Период) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = НСтр("ru = 'В настройках отчёта не найден параметр Период'");
Сообщение.Сообщить();
КонецЕсли;
КонецПроцедуры
// Команда формы. Нужна, если параметр «Период» выведен в пользовательские
// настройки: перед формированием переносит значение поля в настройки.
// Поставьте её на командную панель вместо стандартной кнопки «Сформировать».
&НаКлиенте
Процедура СформироватьОтчет(Команда)
УстановитьПараметрСКД(Отчет.КомпоновщикНастроек, "Период", Период);
СкомпоноватьРезультат(РежимКомпоновкиРезультата.Авто);
КонецПроцедуры
// Показывает в поле то значение, с которым сейчас сформируется отчёт.
&НаКлиентеНаСервере
Процедура ОбновитьПолеПериода()
ТекущееЗначение = ЗначениеПараметраСКД(Отчет.КомпоновщикНастроек, "Период");
Если ТипЗнч(ТекущееЗначение) = Тип("СтандартныйПериод") Тогда
Период = ТекущееЗначение;
КонецЕсли;
КонецПроцедуры
// Записывает значение параметра данных в настройки варианта
// и в пользовательские настройки, если параметр туда выведен.
// Возвращает Ложь, если параметра в настройках нет.
&НаКлиентеНаСервереБезКонтекста
Функция УстановитьПараметрСКД(КомпоновщикНастроек, ИмяПараметра, Значение, Использование = Истина)
ЭлементНастроек = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
Новый ПараметрКомпоновкиДанных(ИмяПараметра));
Если ЭлементНастроек = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
ЭлементНастроек.Значение = Значение;
ЭлементНастроек.Использование = Использование;
ПользовательскийЭлемент = ПользовательскийЭлементПараметра(КомпоновщикНастроек, ЭлементНастроек);
Если ПользовательскийЭлемент <> Неопределено Тогда
ПользовательскийЭлемент.Значение = Значение;
ПользовательскийЭлемент.Использование = Использование;
КонецЕсли;
Возврат Истина;
КонецФункции
// Возвращает значение параметра с учётом пользовательских настроек.
&НаКлиентеНаСервереБезКонтекста
Функция ЗначениеПараметраСКД(КомпоновщикНастроек, ИмяПараметра)
ЭлементНастроек = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(
Новый ПараметрКомпоновкиДанных(ИмяПараметра));
Если ЭлементНастроек = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПользовательскийЭлемент = ПользовательскийЭлементПараметра(КомпоновщикНастроек, ЭлементНастроек);
Если ПользовательскийЭлемент <> Неопределено Тогда
Возврат ПользовательскийЭлемент.Значение;
КонецЕсли;
Возврат ЭлементНастроек.Значение;
КонецФункции
// Находит «двойника» параметра в пользовательских настройках.
&НаКлиентеНаСервереБезКонтекста
Функция ПользовательскийЭлементПараметра(КомпоновщикНастроек, ЭлементНастроек)
Идентификатор = ЭлементНастроек.ИдентификаторПользовательскойНастройки;
Если Не ЗначениеЗаполнено(Идентификатор) Тогда
Возврат Неопределено;
КонецЕсли;
Возврат КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Идентификатор);
КонецФункции
Разбор ключевых строк:
НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(ИмяПараметра)) ищет параметр именно в настройках варианта. Если вернулось Неопределено, проверьте имя и флаг «Ограничение доступности»: параметр с этим флагом в настройки не попадает.ЭлементНастроек.Использование = Использование (по умолчанию Истина): без включённого использования значение есть, но в запрос не идёт.ИдентификаторПользовательскойНастройки заполнен только у параметров, выведенных в пользовательские настройки. По нему находим «двойника» в ПользовательскиеНастройки.Элементы и меняем значение там же.&НаКлиентеНаСервереБезКонтекста работают и на клиенте, и на сервере без лишнего серверного вызова. ОбновитьПолеПериода — &НаКлиентеНаСервере: ей нужен контекст формы, чтобы записать реквизит Период.Одного обработчика ПриОткрытии мало: после смены варианта или загрузки сохранённых настроек компоновщик получает новые значения, а реквизит Период остаётся прежним: в поле один период, а отчёт считается за другой. Поэтому поле обновляется и в событиях формы ПриЗагрузкеВариантаНаСервере и ПриЗагрузкеПользовательскихНастроекНаСервере.
Эти события относятся к загрузке настроек, а не к правке значения. Если «Период» выведен в пользовательские настройки, его можно поменять ещё и в окне «Настройки…», и поле отстанет. Когда период вводится только через реквизит Период, снимите у параметра «Включать в пользовательские настройки». Если вывести всё же нужно, формируйте отчёт командой СформироватьОтчет из листинга: перед компоновкой она переносит значение поля в настройки.
Если значение должно подставляться всегда, а пользователю не нужно, задайте его в модуле объекта отчёта. Параметр в схеме — без «Ограничения доступности» и не выведен в пользовательские настройки. В расширенном режиме настроек пользователь его увидит, но код перезапишет значение при формировании:
// Модуль объекта отчёта
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
ЭтотОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(
"ДатаФормирования", ТекущаяДатаСеанса());
КонецПроцедуры
При программной сборке отчёта пользовательских настроек нет, хватает настроек варианта. Здесь «ДатаФормирования» может быть и с «Ограничением доступности»: в отличие от предыдущего примера, значение пишется не в настройки, а прямо в макет компоновки, который построил компоновщик макета:
&НаСервере
Процедура СформироватьНаСервере()
Схема = Отчеты.ПродажиПоКонтрагентам.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = Схема.НастройкиПоУмолчанию;
ПериодОтчета = Новый СтандартныйПериод;
ПериодОтчета.Вариант = ВариантСтандартногоПериода.ПрошлыйМесяц;
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", ПериодОтчета);
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки);
ПараметрМакета = МакетКомпоновки.ЗначенияПараметров.Найти("ДатаФормирования");
Если ПараметрМакета <> Неопределено Тогда
ПараметрМакета.Значение = ТекущаяДатаСеанса();
КонецЕсли;
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
Результат.Очистить();
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Здесь Результат — реквизит формы типа «Табличный документ». Процессор вывода дописывает в документ, поэтому без Результат.Очистить() каждое нажатие «Сформировать» добавит ещё копию отчёта. Подробнее о программной компоновке — в статье про СКД из кода.
Типичная задача: из карточки контрагента открыть отчёт по продажам сразу по этому контрагенту. У формы отчёта есть стандартные параметры Отбор и СформироватьПриОткрытии. В Отбор передают структуру: ключ — имя, значение — то, что нужно установить. Если имя совпадает с параметром данных схемы, устанавливается параметр, иначе добавляется отбор по полю с этим именем:
&НаКлиенте
Процедура ОткрытьОтчетПоПродажам(Команда)
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
Возврат;
КонецЕсли;
// Отбор по полю результата «Контрагент» (параметр в схеме не нужен):
// ЗначенияОтбора = Новый Структура("Контрагент", Объект.Ссылка);
// Заполнение параметра данных «Контрагенты» из запроса выше:
СписокКонтрагентов = Новый СписокЗначений;
СписокКонтрагентов.Добавить(Объект.Ссылка);
ЗначенияОтбора = Новый Структура("Контрагенты", СписокКонтрагентов);
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", ЗначенияОтбора);
ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
ОткрытьФорму("Отчет.ПродажиПоКонтрагентам.Форма", ПараметрыФормы, ЭтотОбъект);
КонецПроцедуры
Основная форма отчёта в пути называется Форма; имени ФормаОбъекта, как у документов, у отчётов нет. Неосновную форму указывают полностью: "Отчет.ПродажиПоКонтрагентам.Форма.ФормаОтчета".
В параметризуемой команде ссылку берут из ПараметрКоманды, а владельцем формы передают ПараметрыВыполненияКоманды.Источник: ЭтотОбъект в модуле команды не определён. Если у команды режим использования параметра «Множественный», в ПараметрКоманды приходит массив:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
СписокКонтрагентов = Новый СписокЗначений;
Если ТипЗнч(ПараметрКоманды) = Тип("Массив") Тогда
СписокКонтрагентов.ЗагрузитьЗначения(ПараметрКоманды);
Иначе
СписокКонтрагентов.Добавить(ПараметрКоманды);
КонецЕсли;
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", Новый Структура("Контрагенты", СписокКонтрагентов));
ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
ОткрытьФорму("Отчет.ПродажиПоКонтрагентам.Форма", ПараметрыФормы,
ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность,
ПараметрыВыполненияКоманды.Окно, ПараметрыВыполненияКоманды.НавигационнаяСсылка);
КонецПроцедуры
Для нестандартных значений добавьте форме отчёта собственный параметр, но не пишите его в настройки в ПриСозданииНаСервере: после этого обработчика платформа загружает вариант и пользовательские настройки и может затереть значение. Сохраните его в реквизит формы, а в настройки перенесите в ПриОткрытии функцией УстановитьПараметрСКД.
{ГДЕ …}.Настройки. Нужно менять оба слоя.&Период.ДатаОкончания.=. Замените на В.Параметр — значение, которое нужно самой выборке: дата остатков, границы оборотов, вид цены. Отбор — условие на поле результата. Границы периода и дату среза виртуальной таблицы задают только параметром, а для «показать одного контрагента» обычно хватает отбора: СКД по возможности сама перенесёт его в запрос.
В настройках варианта на закладке «Другие настройки» есть параметр вывода «Выводить параметры данных». Со значением «Выводить» отчёт печатает выбранные значения над таблицей. Отдельное поле можно вывести, если у параметра включено «Включать в доступные поля».
Да, через коллекцию Параметры схемы компоновки. После изменения схемы компоновщик настроек нужно заново инициализировать, иначе новый параметр не появится среди доступных. Обычно проще добавить параметр в конфигураторе, а из кода — только когда схема и так собирается программно.
Если отчёт нужен срочно, а с вариантами, пользовательскими настройками и собственной формой уже приходится разбираться в отладчике, быстрее отдать задачу исполнителю. Подробнее об услуге — на странице доработка отчётов и обработок 1С. Опишите нужные параметры и отборы и разместите задачу: оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.