При программной работе с системой компоновки данных (СКД) часто возникает задача сформировать отчет, настройки которого сохранены в общем макете типа МакетКомпоновкиДанных. Стандартная операция — передать в такой отчет параметры, например, текущую организацию или период. Однако именно на этом этапе можно столкнуться с ошибкой "Поле не найдено" при попытке установить значение параметра, даже если вы уверены, что параметр с таким именем в отчете существует. Разберем, почему возникает эта ошибка и как ее исправить.
Проанализируем типичную ситуацию: у нас есть код, который получает схему компоновки из макета, инициализирует компоновщик настроек и пытается установить параметр. В управляемой консоли отчетов все работает, а при программном выполнении — нет.
Ключевая проблема кроется в неправильной инициализации настроек отчета. Часто разработчики получают настройки по умолчанию напрямую из схемы компоновки данных (в этом может помочь консоль кода с ИИ), вот так:
// НЕПРАВИЛЬНЫЙ ПОДХОД
СхемаКомпоновкиДанных = ПолучитьИзВременногоХранилища(АдресСхемы);
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
// Настройки берутся по умолчанию из схемы, а не из макета!
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
// Эта строка вызовет ошибку, если параметра "Организация" нет в настройках по умолчанию
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Организация", Организация);
Ошибка "Поле не найдено 'Организация'" возникает потому, что настройки по умолчанию (СхемаКомпоновкиДанных.НастройкиПоУмолчанию) и настройки, сохраненные в конкретном варианте отчета внутри макета — это не одно и то же. Параметр "Организация" мог быть добавлен в вариант отчета позже, и его просто нет в настройках схемы по умолчанию. Объект МакетКомпоновкиДанных — это не просто схема, а "контейнер", который хранит в себе и схему, и уже сконфигурированные варианты настроек. Наша задача — извлечь именно эти сохраненные настройки.
Чтобы все работало корректно, необходимо выполнить действия в правильной последовательности. Рассмотрим по шагам, как получить доступ к настройкам из макета и модифицировать их (в этом поможет СКДБилдер).
Сначала нам нужен сам макет. Его можно получить, например, из общих макетов конфигурации. Затем из этого макета нужно получить его объектное представление с помощью метода ПолучитьОбъект(). Этот объект и будет содержать необходимые нам сохраненные настройки.
// Предположим, у нас есть общий макет с именем "МойОтчетСКД"
МакетКомпоновкиДанных = ПолучитьОбщийМакет("МойОтчетСКД");
// Получаем объект из макета, который содержит схему и настройки
ОбъектМакета = МакетКомпоновкиДанных.ПолучитьОбъект();
Теперь, когда у нас есть объект макета, мы можем получить из него как схему компоновки данных, так и, что самое важное, сохраненные в нем настройки. Настройки хранятся в свойстве Настройки этого объекта.
СхемаКомпоновкиДанных = ОбъектМакета.СхемаКомпоновкиДанных;
НастройкиОтчета = ОбъектМакета.Настройки;
Создаем и инициализируем КомпоновщикНастроек, как и раньше, передавая ему схему. Но ключевое отличие — после инициализации мы загружаем в него не настройки по умолчанию, а те самые настройки, которые мы извлекли из макета на предыдущем шаге, используя метод ЗагрузитьНастройки().
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
// Загружаем настройки, которые были сохранены в макете!
КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиОтчета);
Теперь, когда компоновщик содержит правильные настройки, в которых уже определен параметр "Организация", мы можем безопасно установить его значение. Ошибки "Поле не найдено" больше не будет.
// Находим параметр в коллекции параметров данных
ПараметрОрганизация = КомпоновщикНастроек.Настройки.ПараметрыДанных.Найти("Организация");
// Проверяем, что параметр найден, и устанавливаем его значение
Если ПараметрОрганизация <> Неопределено Тогда
ПараметрОрганизация.Значение = ВашаОрганизация;
ПараметрОрганизация.Использование = Истина;
КонецЕсли;
Важно: рекомендуется всегда проверять наличие параметра через метод Найти(), прежде чем обращаться к нему. Это делает код более надежным.
Оставшаяся часть процесса стандартна: создаем макет компоновки, получаем процессор компоновки, инициализируем процессор вывода и выводим результат в табличный документ.
// Формируем макет компоновки с нашими измененными настройками
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
// Выполняем компоновку
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(Макет);
// Выводим результат в табличный документ
Результат = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
Соберем все шаги в единую работающую процедуру (наподобие ПриКомпоновкеРезультата). Этот код можно использовать как шаблон для программного формирования отчетов из макетов СКД.
Процедура СформироватьОтчетИзМакета()
// 1. Получаем макет и его объект
МакетКомпоновкиДанных = ПолучитьОбщийМакет("МойОтчетСКД");
ОбъектМакета = МакетКомпоновкиДанных.ПолучитьОбъект();
// 2. Извлекаем схему и настройки из объекта макета
СхемаКомпоновкиДанных = ОбъектМакета.СхемаКомпоновкиДанных;
НастройкиОтчета = ОбъектМакета.Настройки;
// 3. Инициализируем компоновщик и загружаем ПРАВИЛЬНЫЕ настройки
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиОтчета);
// 4. Устанавливаем значение параметра
// Предполагаем, что переменная "НужнаяОрганизация" уже определена
ЭлементПараметра = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Организация");
Если ЭлементПараметра <> Неопределено Тогда
ЭлементПараметра.Значение = НужнаяОрганизация;
ЭлементПараметра.Использование = Истина;
КонецЕсли;
// 5. Выполняем компоновку и выводим результат
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетДляВыполнения = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетДляВыполнения);
ТабличныйДокументРезультат = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
ТабличныйДокументРезультат.Показать("Результат отчета");
КонецПроцедуры
Таким образом, главный секрет — всегда извлекать настройки непосредственно из объекта, полученного из макета (Макет.ПолучитьОбъект().Настройки), а не использовать настройки по умолчанию из схемы. Это гарантирует, что вы работаете с актуальным вариантом отчета, содержащим все необходимые параметры, и позволяет избежать ошибки "Поле не найдено".