Как программно сформировать отчет СКД из макета и передать в него параметры, избежав ошибки "Поле не найдено"?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

В чем заключается основная ошибка?

Ключевая проблема кроется в неправильной инициализации настроек отчета. Часто разработчики получают настройки по умолчанию напрямую из схемы компоновки данных (в этом может помочь консоль кода с ИИ), вот так:


// НЕПРАВИЛЬНЫЙ ПОДХОД
СхемаКомпоновкиДанных = ПолучитьИзВременногоХранилища(АдресСхемы);
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
// Настройки берутся по умолчанию из схемы, а не из макета!
КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию); 

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

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

Правильный алгоритм программного формирования отчета из макета СКД

Чтобы все работало корректно, необходимо выполнить действия в правильной последовательности. Рассмотрим по шагам, как получить доступ к настройкам из макета и модифицировать их (в этом поможет СКДБилдер).

  1. Получение макета и его объекта.

    Сначала нам нужен сам макет. Его можно получить, например, из общих макетов конфигурации. Затем из этого макета нужно получить его объектное представление с помощью метода ПолучитьОбъект(). Этот объект и будет содержать необходимые нам сохраненные настройки.

    
    // Предположим, у нас есть общий макет с именем "МойОтчетСКД"
    МакетКомпоновкиДанных = ПолучитьОбщийМакет("МойОтчетСКД");
    
    // Получаем объект из макета, который содержит схему и настройки
    ОбъектМакета = МакетКомпоновкиДанных.ПолучитьОбъект();
    
  2. Извлечение схемы и сохраненных настроек.

    Теперь, когда у нас есть объект макета, мы можем получить из него как схему компоновки данных, так и, что самое важное, сохраненные в нем настройки. Настройки хранятся в свойстве Настройки этого объекта.

    
    СхемаКомпоновкиДанных = ОбъектМакета.СхемаКомпоновкиДанных;
    НастройкиОтчета = ОбъектМакета.Настройки;
    
  3. Инициализация компоновщика настроек.

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

    
    КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
    КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
    
    // Загружаем настройки, которые были сохранены в макете!
    КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиОтчета);
    
  4. Установка значения параметра.

    Теперь, когда компоновщик содержит правильные настройки, в которых уже определен параметр "Организация", мы можем безопасно установить его значение. Ошибки "Поле не найдено" больше не будет.

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

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

  5. Компоновка макета и вывод результата.

    Оставшаяся часть процесса стандартна: создаем макет компоновки, получаем процессор компоновки, инициализируем процессор вывода и выводим результат в табличный документ.

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

Полный пример корректного кода

Соберем все шаги в единую работающую процедуру (наподобие ПриКомпоновкеРезультата). Этот код можно использовать как шаблон для программного формирования отчетов из макетов СКД.


Процедура СформироватьОтчетИзМакета()

    // 1. Получаем макет и его объект
    МакетКомпоновкиДанных = ПолучитьОбщийМакет("МойОтчетСКД");
    ОбъектМакета = МакетКомпоновкиДанных.ПолучитьОбъект();

    // 2. Извлекаем схему и настройки из объекта макета
    СхемаКомпоновкиДанных = ОбъектМакета.СхемаКомпоновкиДанных;
    НастройкиОтчета = ОбъектМакета.Настройки;

    // 3. Инициализируем компоновщик и загружаем ПРАВИЛЬНЫЕ настройки
    КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
    КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
    КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиОтчета);

    // 4. Устанавливаем значение параметра
    // Предполагаем, что переменная "НужнаяОрганизация" уже определена
    ЭлементПараметра = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Организация");
    Если ЭлементПараметра <> Неопределено Тогда
        ЭлементПараметра.Значение = НужнаяОрганизация;
        ЭлементПараметра.Использование = Истина;
    КонецЕсли;

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

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

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

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

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

Таким образом, главный секрет — всегда извлекать настройки непосредственно из объекта, полученного из макета (Макет.ПолучитьОбъект().Настройки), а не использовать настройки по умолчанию из схемы. Это гарантирует, что вы работаете с актуальным вариантом отчета, содержащим все необходимые параметры, и позволяет избежать ошибки "Поле не найдено".

← На главную