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

Ниже разберу оба сценария по шагам, покажу, как программно установить параметр и отбор, и как без ошибок получить результат в таблицу значений.

Какой способ выбрать

ЗадачаСпособГде выполняется
Открыть отчёт с отбором и сразу сформироватьОткрытьФорму с параметрамиКлиент
Открыть форму и до показа поменять настройки целикомПолучить форму, загрузить настройки, СкомпоноватьРезультатКлиент + серверный вызов
Получить результат в табличный документ (печать, рассылка)Компоновка в коде, вывод в ТабличныйДокументСервер
Использовать данные отчёта в алгоритмеКомпоновка в коде, вывод в ТаблицаЗначенийСервер

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

Открытие отчета с отбором через ОткрытьФорму

Самый короткий путь. Форма отчёта на СКД понимает несколько стандартных параметров:

  • КлючВарианта — имя варианта настроек (как он назван в схеме);
  • Отбор — структура «имя поля — значение», которая превращается в отборы компоновки;
  • СформироватьПриОткрытии — сформировать отчёт сразу после открытия;
  • ПользовательскиеНастройки — готовые пользовательские настройки, если нужно передать больше, чем отбор.
1С
&НаКлиенте
Процедура ОткрытьПродажиПоКлиенту(Команда)

	ОтборОтчета = Новый Структура("Контрагент", Объект.Контрагент);

	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("КлючВарианта", "ПродажиПоНоменклатуре");
	ПараметрыФормы.Вставить("Отбор", ОтборОтчета);
	ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);

	ОткрытьФорму("Отчет.ПродажиТоваров.Форма", ПараметрыФормы, ЭтотОбъект);

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

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

Открытие формы с подменой настроек

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

1С
&НаКлиенте
Процедура ОткрытьОтчетЗаПрошлыйМесяц(Команда)

	ФормаОтчета = ПолучитьФорму("Отчет.ПродажиТоваров.Форма");
	ФормаОтчета.УстановитьТекущийВариант("ПродажиПоНоменклатуре");

	Настройки = НастройкиЗаПрошлыйМесяц(ФормаОтчета.Отчет.КомпоновщикНастроек);
	ФормаОтчета.Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

	ФормаОтчета.СкомпоноватьРезультат();
	ФормаОтчета.Открыть();

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

&НаСервереБезКонтекста
Функция НастройкиЗаПрошлыйМесяц(КомпоновщикНастроек)

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

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

	Возврат Настройки;

КонецФункции

Для внешнего отчёта форма получается через ВнешниеОтчеты.Создать(ПутьКФайлу) и метод ПолучитьФорму у созданного объекта — но учтите, что ВнешниеОтчеты.Создать выполняется только на сервере, поэтому на клиенте этот вариант требует серверного вызова и помещения файла во временное хранилище. В типовых конфигурациях на БСП внешние отчёты подключаются через «Дополнительные отчёты и обработки», и открывать их удобнее средствами подсистемы.

Программное формирование отчета СКД на сервере

Если отчёт нужен программе, форма не участвует. Цепочка всегда одна и та же:

Программное формирование отчета СКД: схема, настройки, компоновщик макета и процессор вывода
Программное формирование отчета СКД: схема, настройки, компоновщик макета и процессор вывода
  1. Получить схему компоновки данных — макет отчёта, общий макет или макет обработки.
  2. Получить настройки: по умолчанию, из варианта или через компоновщик настроек.
  3. Изменить параметры, отборы, структуру.
  4. Собрать макет компоновки компоновщиком макета.
  5. Инициализировать процессор компоновки.
  6. Вывести результат процессором вывода в табличный документ или коллекцию значений.

Источники схемы:

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

// Внутри модуля самого отчёта или обработки
Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

// Из формы обработки: сначала объект, потом макет
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
Схема = ОбработкаОбъект.ПолучитьМакет("СхемаВыгрузки");

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

1С
// Возвращает настройки варианта отчёта, проверенные на соответствие схеме.
Функция НастройкиВарианта(Схема, ИмяВарианта = "")

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

	Если ПустаяСтрока(ИмяВарианта) Тогда
		Компоновщик.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);
	Иначе
		Компоновщик.ЗагрузитьНастройки(Схема.ВариантыНастроек[ИмяВарианта].Настройки);
	КонецЕсли;

	Возврат Компоновщик.ПолучитьНастройки();

КонецФункции

Сам вывод в табличный документ:

1С
// Формирует отчёт по схеме и настройкам и возвращает табличный документ.
Функция СформироватьТабличныйДокумент(Схема, Настройки) Экспорт

	ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;

	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, ДанныеРасшифровки);

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

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

	Возврат Результат;

КонецФункции

Четвёртый параметр Инициализировать разрешает функции общих модулей в выражениях схемы — если в отчёте есть вычисляемые поля с вызовом общих модулей, без него будет ошибка.

Как установить параметр и отбор программно

Параметры данных

Существующий параметр:

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

Если параметра в настройках может не быть (например, он появился после правки текста запроса), сначала ищем его, при отсутствии добавляем:

1С
Параметр = Новый ПараметрКомпоновкиДанных("ТолькоАктивные");
ЗначениеПараметра = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Параметр);
Если ЗначениеПараметра = Неопределено Тогда
	ЗначениеПараметра = Настройки.ПараметрыДанных.Элементы.Добавить();
	ЗначениеПараметра.Параметр = Параметр;
КонецЕсли;
ЗначениеПараметра.Значение = Истина;
ЗначениеПараметра.Использование = Истина;

Отборы

У отборов нет метода «установить значение по имени», элементы приходится перебирать. Удобно вынести это в функцию:

1С
// Включает отбор «Поле = Значение»: обновляет существующий элемент или добавляет новый.
Процедура УстановитьОтборКомпоновки(Отбор, ИмяПоля, Значение)

	Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);

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

	Если Отбор.ДоступныеПоляОтбора.НайтиПоле(Поле) = Неопределено Тогда
		ВызватьИсключение СтрШаблон("Поле %1 недоступно для отбора", ИмяПоля);
	КонецЕсли;

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

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

Проверка ТипЗнч нужна, потому что в коллекции могут лежать группы отбора — у них нет ЛевоеЗначение. В конфигурациях на БСП ту же задачу решает ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора, им и пользуюсь, если библиотека есть.

ДоступныеПоляОтбора заполняются только у настроек, полученных из инициализированного компоновщика. У «голых» Схема.НастройкиПоУмолчанию проверка доступности не сработает — ещё одна причина работать через компоновщик.

Вывод результата СКД в таблицу значений

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

Вывод результата отчета СКД в таблицу значений через простую структуру детальных записей
Вывод результата отчета СКД в таблицу значений через простую структуру детальных записей
1С
// Формирует отчёт и возвращает результат в виде таблицы значений.
Функция СформироватьТаблицуЗначений(Схема, Настройки) Экспорт

	// Одна группировка детальных записей: таблицы и диаграммы в коллекцию не выводятся
	Настройки.Структура.Очистить();
	Группировка = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
	Группировка.Использование = Истина;
	Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
	Группировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));

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

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

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

	Возврат Результат;

КонецФункции

Колонки таблицы получат имена полей выбора. Если в варианте отчёта настроены конкретные выбранные поля, они и попадут в таблицу; автополе берёт выбранные поля из настроек верхнего уровня. Данные расшифровки для коллекции значений не нужны — их можно не передавать.

Изменение запроса схемы в коде

Иногда нужно ограничить данные по полю, которого нет в доступных полях отчёта. Текст запроса набора данных доступен через Схема.НаборыДанных[ИмяНабора].Запрос, и его можно поменять перед компоновкой. Я делаю это редко и только с копией схемы: правка текста строкой хрупкая — после обновления типового отчёта замена может перестать срабатывать молча. Надёжнее добавить в схему параметр и условие через доработку отчёта, а в коде лишь задавать значение параметра. Такие доработки отчётов делаю в рамках услуги отчёты на СКД.

Типичные ошибки

  • «Не поддерживается вывод таблиц и диаграмм в универсальную коллекцию значений». В структуре настроек есть таблица или диаграмма. Очистите структуру и добавьте одну группировку детальных записей.
  • Отбор не применился. Поле указано не так, как в доступных полях (например, Контрагент вместо Документ.Контрагент), или у элемента не включено Использование.
  • Параметр не меняется. У параметра в схеме задано выражение, вычисляемое из другого параметра, или имя в коде не совпадает с именем в схеме. Проверьте схему.
  • Ошибка вызова функции общего модуля в выражении. Не передан четвёртый параметр Истина при инициализации процессора компоновки.
  • Компоновка на клиенте. Объекты СКД доступны только на сервере — переносите формирование в серверную функцию.
  • Старое окно отчёта. При повторном ОткрытьФорму пользователь видит уже открытую форму с прежними отборами. Используйте ключ уникальности или закрывайте форму.
Если отчёт формируется из кода регулярно, вынесите формирование в серверный общий модуль с понятным интерфейсом «вариант + параметры → результат». Тогда его можно вызывать из формы, регламентного задания и HTTP-сервиса одинаково.

Готовые результаты отчётов часто уходят дальше — в рассылку или в аналитику. Если нужна регулярная выгрузка данных в BI, это уже задача BI-аналитики на данных 1С; точечные доработки типовых отчётов и форм — в рамках доработки 1С.

Итог

  • Открыть отчёт с отбором и сразу сформировать — ОткрытьФорму с КлючВарианта, Отбор и СформироватьПриОткрытии.
  • Для полной подмены настроек получите форму, загрузите настройки в компоновщик, вызовите СкомпоноватьРезультат и откройте форму.
  • Программное формирование отчета СКД без формы — цепочка «схема → настройки → компоновщик макета → процессор компоновки → процессор вывода», только на сервере.
  • Настройки берите через КомпоновщикНастроекКомпоновкиДанных: так работают доступные поля и проверка отборов.
  • Для таблицы значений нужны генератор для коллекции значений, процессор вывода в коллекцию и плоская структура настроек.