При работе с отчетами, построенными на Системе Компоновки Данных (СКД) в 1С, часто возникает задача программного формирования отчета — для этого есть инструменты разработчика и консоль СКД для анализа схем. Если отчет содержит несколько предопределенных или сохраненных пользователем вариантов, нам может потребоваться вывести конкретный вариант, выбранный пользователем, вместо настроек по умолчанию. В этой статье мы подробно рассмотрим, как это сделать, используя программный подход.
Изначально, при программной компоновке, как показано в исходном коде, для формирования отчета часто используются настройки по умолчанию из схемы компоновки данных. Это происходит, когда мы передаем Схема.НастройкиПоУмолчанию в метод КомпоновщикМакета.Выполнить(). Однако, если отчет имеет несколько вариантов, сохраненных в конфигураторе или пользователем, нам необходимо динамически загрузить настройки нужного варианта. Именно это мы и будем разбирать.
Когда мы выполняем программную компоновку отчета СКД, как в представленном вами коде, мы используем следующий фрагмент:
МакетКомпановки = КомпоновщикМакета.Выполнить(Схема, Схема.НастройкиПоУмолчанию, ДанныеРасшифровки);
Здесь Схема.НастройкиПоУмолчанию всегда возвращает те настройки, которые были заданы как основные (или первые созданные) в схеме компоновки данных в конфигураторе. Если у вашего отчета есть несколько вариантов, и пользователь выбрал один из них, эти настройки не будут учтены. Нам необходимо получить конкретные настройки выбранного варианта и передать их в КомпоновщикМакета.Выполнить().
Для решения нашей задачи мы будем работать со следующими объектами (также можно использовать СКДБилдер для упрощения кода):
СхемаКомпоновкиДанных: Объект, представляющий макет СКД. Он содержит все определения наборов данных, полей, ресурсов, параметры и, что самое главное для нас, коллекцию вариантов настроек.НастройкиКомпоновкиДанных: Объект, который хранит текущие настройки отчета – отборы, поля, группировки, порядок, параметры и т.д.КомпоновщикНастроекКомпоновкиДанных: Вспомогательный объект, который управляет настройками. Он может загружать, сохранять, получать и применять различные настройки.ИсточникДоступныхНастроекКомпоновкиДанных: Объект, который предоставляет информацию о доступных полях, группировках и других элементах СКД для КомпоновщикаНастроек.КомпоновщикМакетаКомпоновкиДанных: Объект, который формирует двоичный макет компоновки данных на основе схемы и текущих настроек.Прежде всего, нам необходимо узнать, какой вариант отчета был выбран пользователем. Это может быть реализовано различными способами в зависимости от вашей формы отчета:
Предположим, что у нас есть реквизит формы (или свойство объекта), например, ЭтотОбъект.ВыбранныйВариантОтчета, который содержит строковый идентификатор (ключ) выбранного варианта.
Способ получения настроек зависит от того, где эти варианты хранятся:
Если варианты отчета были предопределены разработчиком в конфигураторе, они являются частью самого макета СКД и доступны через коллекцию СхемаКомпоновкиДанных.ВариантыНастроек. Каждый элемент этой коллекции содержит объект варианта, у которого есть свойство Настройки.
Для получения настроек конкретного варианта по его ключу, мы используем следующий синтаксис:
НастройкиКД = Схема.ВариантыНастроек[ЭтотОбъект.ВыбранныйВариантОтчета].Настройки;
Здесь ЭтотОбъект.ВыбранныйВариантОтчета должен содержать строковый ключ варианта, который был задан в конфигураторе.
Варианты, которые пользователи сохраняют в режиме 1С:Предприятие, как правило, хранятся в специальном хранилище (например, в справочнике "ВариантыОтчетов" или "НастройкиПользователей"). В типовых конфигурациях 1С, основанных на Библиотеке Стандартных Подсистем (БСП), для работы с такими вариантами используется общий модуль ВариантыОтчетов.
В этом случае, процесс получения настроек будет немного сложнее, но более универсален. Рассмотрим пример из сообщения 6, который использует типовые механизмы БСП:
ВариантОтчета = ВариантыОтчетов.ВариантОтчета(Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоРеквизиту("Имя", "ВедомостьПоТоварамНаСкладах"), "06f7644a-4bb6-4d4d-9eb4-a60865224151");
ПараметрыИдентификации = Новый Структура;
ПараметрыИдентификации.Вставить("СсылкаВарианта" , ВариантОтчета);
ПараметрыИдентификации.Вставить("СсылкаОтчета" , Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоРеквизиту("Имя", "ВедомостьПоТоварамНаСкладах"));
ПараметрыИдентификации.Вставить("КлючВарианта" , "06f7644a-4bb6-4d4d-9eb4-a60865224151");
ПараметрыИдентификации.Вставить("ИдентификаторФормы" , Неопределено);
ПараметрыОтчета = ВариантыОтчетов.ПодключитьОтчетИЗагрузитьНастройки(ПараметрыИдентификации);
СхемаКомпоновкиДанных = ПараметрыОтчета.Объект.СхемаКомпоновкиДанных;
НастройкиКД = ПараметрыОтчета.НастройкиКД;
Здесь:
ВариантыОтчетов.ВариантОтчета().
Для этого необходимо знать имя отчета в метаданных ("ВедомостьПоТоварамНаСкладах") и ключ варианта ("06f7644a-4bb6-4d4d-9eb4-a60865224151", который является GUID'ом). Ключ варианта обычно можно получить из соответствующего реквизита формы или из объекта, который хранит информацию о выбранном варианте.
ПараметрыИдентификации, которая содержит всю необходимую информацию для идентификации отчета и варианта.ВариантыОтчетов.ПодключитьОтчетИЗагрузитьНастройки() является универсальным инструментом БСП для получения схемы компоновки данных отчета и загруженных в нее настроек выбранного варианта. Результатом его работы является структура ПараметрыОтчета, из которой мы можем получить как саму схему (ПараметрыОтчета.Объект.СхемаКомпоновкиДанных), так и уже загруженные настройки (ПараметрыОтчета.НастройкиКД).Использование модуля ВариантыОтчетов предпочтительнее для БСП-конфигураций (например, если вы создаете сводный отчет для БСП), так как он корректно работает с различными сценариями, включая варианты из расширений.
После того как мы получили объект НастройкиКомпоновкиДанных, соответствующий выбранному варианту, его необходимо использовать при создании макета компоновки.
Рассмотрим, как интегрировать эти шаги в вашу процедуру ПриКомпоновкеРезультата:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ДокументРезультат.Очистить();
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ТаблицаОстатков", ?(ЭтотОбъект.РежимОтчета = "Остатки", ПолучитьТаблицуОстатков(), ПолучитьТаблицуВзаиморасчетов())); // подготавливаем структуру с готовой таблицей
Если ЭтотОбъект.РежимОтчета = "Остатки" Тогда
Схема = ЭтотОбъект.ПолучитьМакет("СхемаКомпоновкиДанныхОстатки");
Иначе
Схема = ЭтотОбъект.ПолучитьМакет("СхемаКомпоновкиДанныхВзаиморасчеты");
КонецЕсли;
// --- НАЧИНАЕМ ИЗМЕНЕНИЯ ЗДЕСЬ ---
// 1. Создаем КомпоновщикНастроекКомпоновкиДанных
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
// 2. Инициализируем его схемой
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
// 3. Получаем НастройкиКомпоновкиДанных для выбранного варианта
// Предположим, что "ВыбранныйВариантОтчета" - это реквизит формы,
// хранящий наименование/ключ выбранного варианта.
// Если вариант не выбран, или указан несуществующий,
// можем загрузить настройки по умолчанию или вывести ошибку.
Перем НастройкиКД;
// Пример получения настроек из схемы (вариант, определенный в конфигураторе)
Если Не ЗначениеЗаполнено(ЭтотОбъект.ВыбранныйВариантОтчета) Тогда
// Если вариант не выбран, загружаем настройки по умолчанию
НастройкиКД = Схема.НастройкиПоУмолчанию;
Иначе
Попытка
// Пытаемся получить настройки из коллекции вариантов схемы
НастройкиКД = Схема.ВариантыНастроек[ЭтотОбъект.ВыбранныйВариантОтчета].Настройки;
Исключение
Сообщить("Не найден вариант отчета с ключом " + ЭтотОбъект.ВыбранныйВариантОтчета + ". Будут использованы настройки по умолчанию.", СтатусСообщения.Важное);
НастройкиКД = Схема.НастройкиПоУмолчанию;
КонецПопытки;
КонецЕсли;
// Если вы используете ВариантыОтчетов из БСП (как в сообщении 6), код будет другим:
// Если Не ЗначениеЗаполнено(ЭтотОбъект.ВыбранныйВариантОтчета) Тогда
// НастройкиКД = Схема.НастройкиПоУмолчанию;
// Иначе
// // Предположим, что ЭтотОбъект.ИмяОтчетаМетаданных содержит имя отчета в метаданных
// // А ЭтотОбъект.ВыбранныйВариантОтчета - GUID ключа варианта
// ВариантОтчета = ВариантыОтчетов.ВариантОтчета(Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоРеквизиту("Имя", ЭтотОбъект.ИмяОтчетаМетаданных), ЭтотОбъект.ВыбранныйВариантОтчета);
// Если ВариантОтчета <> Неопределено Тогда
// ПараметрыИдентификации = Новый Структура;
// ПараметрыИдентификации.Вставить("СсылкаВарианта" , ВариантОтчета);
// ПараметрыИдентификации.Вставить("СсылкаОтчета" , Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоРеквизиту("Имя", ЭтотОбъект.ИмяОтчетаМетаданных));
// ПараметрыИдентификации.Вставить("КлючВарианта" , ЭтотОбъект.ВыбранныйВариантОтчета);
// ПараметрыИдентификации.Вставить("ИдентификаторФормы" , Неопределено);
//
// ПараметрыОтчета = ВариантыОтчетов.ПодключитьОтчетИЗагрузитьНастройки(ПараметрыИдентификации);
// НастройкиКД = ПараметрыОтчета.НастройкиКД;
// Иначе
// Сообщить("Вариант отчета не найден. Будут использованы настройки по умолчанию.", СтатусСообщения.Важное);
// НастройкиКД = Схема.НастройкиПоУмолчанию;
// КонецЕсли;
// КонецЕсли;
// 4. Загружаем полученные настройки в КомпоновщикНастроек
КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиКД);
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// 5. Передаем настройки из КомпоновщикаНастроек в КомпоновщикМакета.Выполнить()
МакетКомпановки = КомпоновщикМакета.Выполнить(Схема, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпановки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
//Вывод результата
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.НачатьВывод();
ПроцессорВывода.Вывести(ПроцессорКомпоновки, Истина);
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры
Разберем по шагам ключевые изменения:
КомпоновщикНастроекКомпоновкиДанных: Мы создаем экземпляр объекта КомпоновщикНастроек, который будет управлять настройками.КомпоновщикНастроек: Объект КомпоновщикНастроек необходимо инициализировать, чтобы он "знал" о структуре схемы СКД. Для этого используется Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема). Это позволяет компоновщику настроек работать с полями, группировками и другими элементами, определенными в нашей схеме.НастройкиКД: На этом шаге мы используем один из методов, описанных в Шаге 2, для получения конкретных настроек выбранного варианта отчета. Мы предусмотрели проверку на случай, если вариант не выбран или не найден, чтобы использовать настройки по умолчанию и избежать ошибок.КомпоновщикНастроек: С помощью метода КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиКД) мы применяем полученные настройки к нашему компоновщику. Это обновляет внутреннее состояние объекта КомпоновщикНастроек.КомпоновщикМакета.Выполнить(): Самый важный момент – вместо Схема.НастройкиПоУмолчанию мы теперь передаем КомпоновщикНастроек.Настройки. Объект КомпоновщикНастроек теперь содержит актуальные настройки выбранного варианта, и именно эти настройки будут использованы для формирования макета компоновки данных.СхемаКомпоновкиДанных) доступны только на сервере. Если вам нужно передать схему с клиента на сервер, используйте временное хранилище. Однако, в данном примере код располагается в модуле объекта отчета (процедура ПриКомпоновкеРезультата), который выполняется на сервере, что упрощает работу.КомпоновщикНастроек вы можете получить к ним доступ через КомпоновщикНастроек.Настройки.ПараметрыДанных и при необходимости программно изменить их значения (например, чтобы реализовать логику нет данных - нет столбцов) перед выполнением компоновки.Таким образом, для программного вывода выбранного пользователем варианта отчета СКД необходимо получить объект настроек этого варианта, загрузить его в КомпоновщикНастроекКомпоновкиДанных и затем использовать эти настройки при выполнении метода КомпоновщикМакета.Выполнить(). Этот подход позволяет полностью контролировать процесс формирования отчета и динамически применять любые сохраненные варианты.