Почему возникает ошибка «Параметр не найден» при программной установке параметра СКД и как ее исправить?

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

При формировании отчетов на базе схемы компоновки данных (СКД) разработчики часто сталкиваются с ситуацией: в макете параметр объявлен, однако при вызове метода УстановитьЗначениеПараметра система выбрасывает исключение с сообщением о том, что параметр не найден. Разберем детально, почему так происходит и как правильно передавать значения параметров программно.

Выясним причину возникновения ошибки

Проанализируем стандартный код, который приводит к ошибке:


СхемаКомпоновкиДанных = ПолучитьМакет("МакетПродажи");
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПараметрОтбор"), ЗначениеОтбора);

Проблема кроется во внутреннем устройстве СКД и поведении коллекции настроек:

  1. Особенности метода УстановитьЗначениеПараметра. Данный метод не создает новый параметр в структуре, а лишь ищет существующий элемент в коллекции ПараметрыДанных.Элементы конкретного объекта настроек и меняет его значение. Если параметр не был предварительно добавлен именно в данный вариант настроек, платформа выдаст исключение.
  2. Отсутствие связи со схемой. Свойство НастройкиПоУмолчанию возвращает статический объект настроек схемы. Без инициализации источника доступных настроек этот объект не знает о полном наборе параметров, созданных на соответствующей вкладке схемы компоновки данных.
  3. Использование внешних наборов данных. Если в качестве источника выступает набор данных типа «Объект» (таблица значений или массив), платформа не создает параметры автоматически (как в случае с текстом запроса и конструкцией &Параметр). Если параметр не был инициализирован в настройках варианта, он будет отсутствовать в коллекции.

Рассмотрим надежные способы решения этой задачи.

Способ 1. Инициализация компоновщика через источник доступных настроек

Наиболее правильный и универсальный подход в платформе 1С:Предприятие — связать настройки со схемой с помощью объекта КомпоновщикНастроекКомпоновкиДанных и объекта ИсточникДоступныхНастроекКомпоновкиДанных. При этом компоновщик автоматически синхронизирует список параметров с метаданными схемы.

Посмотрим на пример реализации:


СхемаКомпоновкиДанных = ПолучитьМакет("МакетПродажи");

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

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

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

Обратите внимание: метод УстановитьЗначениеПараметра принимает строковое имя параметра первым аргументом, оборачивать его вручную в Новый ПараметрКомпоновкиДанных(...) необязательно.

Способ 2. Загрузка варианта настроек через контекст отчета

Если код выполняется внутри модуля отчета или формы отчета, у объекта уже есть собственный КомпоновщикНастроек. В этом случае мы можем загрузить настройки требуемого варианта напрямую, как предлагалось в обсуждении:


// Загружаем настройки выбранного варианта схемы
Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.ВариантыНастроек.Получить(0).Настройки);

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

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

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

Способ 3. Проверка наличия и ручное добавление параметра в коллекцию

Если по каким-либо причинам требуется работать исключительно с прямым объектом НастройкиКомпоновкиДанных без компоновщика, необходимо проверить наличие элемента в коллекции и добавить его, если он отсутствует:


Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;

// Ищем параметр в коллекции настроек
ЗначениеПараметра = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПараметрОтбор"));

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

// Устанавливаем значение и обязательно включаем флаг использования
ЗначениеПараметра.Значение = ЗначениеОтбора;
ЗначениеПараметра.Использование = Истина;

Помните, что при ручном заполнении свойства ЗначениеПараметра.Значение свойство Использование не взводится автоматически, в отличие от штатного метода УстановитьЗначениеПараметра. Поэтому строку ЗначениеПараметра.Использование = Истина; указывать обязательно.

Способ 4. Проверка и обновление настроек в конфигураторе

Если ошибка возникает при разработке нового отчета, полезно проверить саму схему в конфигураторе:

  1. Откройте макет схемы компоновки данных.
  2. Перейдите на вкладку Настройки.
  3. Убедитесь, что на вкладке Параметры (в нижней панели настроек варианта) ваш параметр присутствует в списке.
  4. Если параметр был добавлен на вкладку «Параметры» схемы позже, чем сформирован вариант, он может отсутствовать в настройках. Нажмите кнопку восстановления стандартных настроек варианта или добавьте параметр в список настроек вручную.
  5. Сохраните отчет или макет.

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

← На главную